IM1281B电能计量模块_C语言例程

一、前言

毕设采用了艾锐达公司的IM1281B电量计能模块,找了一圈没发现具体的51单片机的例程,现在写个能使用的C语言例程,方便以后的开发者们。

 

二、事前准备

引脚定义:

引脚功能说明
V+ 供电正极(可引主控板5v)
V- 供电负极(可引主控板Gnd)
RX 串口通讯(接主控板TX)
TX 串口通讯(接主控板RX)
PF 脉冲输出引脚,检测电能精度(不需要可悬空)
VL 用电器火线接口
VN 用电器零线接口

 

接线示意图“

 补充:该模块只能测交流。。。

 

三、例程

注意:此文件并不是一个完整的工程,但是函数基本都可以使用,可以参考。

  1 /***************************************/
  2 /*****   Some funtion for send data*****/
  3 /***************************************/
  4 
  5 
  6 #define  _IM1281B_C
  7 typedef  unsigned  char    uint8;  
  8 typedef  unsigned  short  int  uint16;  
  9 typedef  unsigned  long   int  uint32; 
 10 
 11 bit uart_busy = 0;
 12 uint8 Tx_Buffer[8]; // 发送读取数据指令缓冲数组
 13 uint8 Rx_Buffer[37];//接受到的数据
 14 uint8 MeterUsedBuff[8] = {"000.000k"};  
 15 /*这个字符数组存放的电能数据,可以通过LCD1602打印出来,也可以通过串口发送*/
 16 
 17 uint32 Energy_data;
 18 
 19 
 20 /*延时5ms*/
 21 void delay5ms() {
 22     unsigned char a,b;
 23     for(b=101;b>0;b--)
 24         for(a=147;a>0;a--);
 25 }
 26 
 27 
 28 /****************************************************/
 29 /************     电能计量模块相关     **************/
 30 /****************************************************/
 31 
 32 /*电能数据刷新时调用此函数*/
 33 void clear_data(void)
 34 {
 35     uint8 i = 0;
 36     Tx_Buffer[0]=0x01;    //这部分数据可以在艾锐达提供的上位机里边读到
 37     Tx_Buffer[1]=0x03;
 38     Tx_Buffer[2]=0x00;
 39     Tx_Buffer[3]=0x48;
 40     Tx_Buffer[4]=0x00;
 41     Tx_Buffer[5]=0x08;
 42     Tx_Buffer[6]=0xC4;
 43     Tx_Buffer[7]=0x1A;
 44 
 45     for(i=0;i<8;i++){
 46             Uart_SendByteData(Tx_Buffer[i]);  //最好单个字符发送,发送字符串的话00会被认为结束符
 47     }        
 48 
 49 }
 50 
 51 /*接收数据放到数组*/
 52 //
 53 void Analysis_data()
 54 {
 55     //电能数据的接收,其他数据也是类似
 56     Energy_data=(((uint32)(RX_Buffer[15]))<<24)|(((uint32)(RX_Buffer[16]))<<16)|(((uint32)(RX_Buffer[17]))<<8)|RX_Buffer[18];
 57 }
 58 
 59 /*对接收的数据进行一个转化*/
 60 void TransMeterData(uint32 meterdata){   
 61 //example:电能数据
 62     uint16 data6=0,data5=0,data4=0,data3=0,data2=0,data1=0;
 63     data6 = meterdata/1000000;
 64     data5 = meterdata%1000000/100000;
 65     data4 = meterdata%100000/10000;    
 66     data3 = meterdata%10000/1000;
 67     data2 = meterdata%1000/100;
 68     data1 = meterdata%100/10;
 69     MeterUsedBuff[0] = data6 + '0';
 70     MeterUsedBuff[1] = data5 + '0';
 71     MeterUsedBuff[2] = data4 + '0';
 72     MeterUsedBuff[3] = '.';
 73     MeterUsedBuff[4] = data3 + '0';
 74     MeterUsedBuff[5] = data2 + '0';
 75     MeterUsedBuff[6] = data1 + '0';
 76 }
 77 
 78 void ReadMeterData(){   //这个函数在主函数里面调用即可
 79         clear_data();
 80         delay5ms();
 81         Uart_SendStrData("read data ...\r\n");
 82         Analysis_data();  
 83         TransMeterData(Energy_data);
 84 }
 85 
 86 /****************************************************/
 87 /************     串口收发数据相关     **************/
 88 /****************************************************/
 89 
 90 /*串口发送数据*/
 91 void Uart_SendByteData(uint8 msg){
 92     while(uart_busy); 
 93     SBUF = msg;          
 94     uart_busy = 1;     
 95 }
 96 void Uart_SendStrData(uint8 *msg){
 97     while(*msg){
 98         Uart_SendByteData(*msg++);
 99     }
100 }  
101 
102 /* 51单片机UART1中断服务函数 */
103 void InterruptUART() interrupt 4
104 {
105     uint8 rec;
106     if (RI)  //接收到字节
107     {
108         if(rflag){
109             Rx_Buffer[i++] = SBUF;
110             if(i==37){
111                 i=1;
112                 rflag = 0;
113             }
114         }
115         else{
116             rec = SBUF;
117             if(rec == 0x01){   //验证
118                 
119                 rflag = 1;
120                 Rx_Buffer[0] = rec;
121             }
122         }
123         RI = 0;//手动清零接收中断标志位
124     }
125     if (TI)  //字节发送完毕
126     {
127         TI = 0;  //手动清零发送中断标志位
128         uart_busy = 0;
129     }
130 }

 

仅供参考,觉得有用的话给我点个赞把~

不会的也可以留言,我看到会尽力帮忙解答。

posted @ 2022-05-15 21:15  peng010104  阅读(767)  评论(0编辑  收藏  举报