IM1281B单相交流计量模块使用与实际讲解原理RS485modbus规则,一篇吃透;可接PLC(接TTL转485模块)理论上可采集255个用电计量模块一起用。

看了一大堆乱七八糟的文章介绍本质上这个模块就是一个RS485,modbus协议的从机。默认站号0x01;

用USB转TTL工具进行串口通讯;可选厂家的上位机;默认波特率速率:4800;串口编程初始化一定要选4800;

既然是支持MODBUS 协议的模块;那就可以用协议去操作;

首先更改站址:TX[11]:00 10 00 04 00 01 02 FF 05 2B B7

其中00是所有从站都接收的广播地址;

10是功能码。写多个寄存器的功能码;

00 04是寄存器起始地址;

00 01是寄存器个数;

02是写一个寄存器的字节数;

FF是具体数值是十进制255从站号;

05默认(不清楚厂家设置意图,好像是站址寄存器的1个字节高位);

2B B7是CRC校验码;

返回内容是:RX[8]:FF 10 00 04 00 01 55 D6;

FF是十进制站址255;

10是写多个寄存器的功能码;

0004 是站址所在寄存器的地址名称编码;类似于门牌号码;

0001是写的寄存器个数;

55 D6是CRC校验码;

下面是主要编程原理:

以stm32f103c8t6进行C语言编程,选串口3;PB10发送引脚,PB11接收引脚;

1,建立发送缓冲区数组;

//模块波特率4800;固定格式;发送8个字节,接收37个字节。

uint8_t     Tx3_Buffer[8]; // 发送读取数据指令缓冲数组

uint8_t     Rx3Buff[37];   // 接收到的数据

将:01 03 00 48 00 08 C4 1A写入数组;建立传参延时间隔发送函数

/* 电能数据刷新时调用此函数 */
void Tx3_Buffer_data(uint32_t delay_times_ms)
    {
    
    uint8_t  i = 0;
    HAL_Delay(delay_times_ms);//间隔xxx传参毫秒延时抄表
    Tx3_Buffer[0] = 0x01;//Read_ID;    //模块的 ID 号,默认 ID 为 0x01
    Tx3_Buffer[1] = 0x03;//功能码0x03;读取连续寄存器的功能码
    Tx3_Buffer[2] = 0x00;//读寄存器开始的地址0X0048;两字节保存
    Tx3_Buffer[3] = 0x48;
    Tx3_Buffer[4] = 0x00;//读寄存器总共的个数0X0008;两字节保存
    Tx3_Buffer[5] = 0x08;
    Tx3_Buffer[6] = 0xC4;//crc校验码,这里算出直接写死,不用计算;
    Tx3_Buffer[7] = 0x1A;

    for(i = 0; i < 8; i++) {
        HAL_UART_Transmit(&huart3, &Tx3_Buffer[i], 1, HAL_MAX_DELAY);

// 串口3发送循环发送单个字节,就是把01 03 00 48 00 08 C4 1A发送到模块;
    }
}

接收缓冲区处理函数:

RX[37]:01 03 20 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 03 E7 00 00 00 00 00 00 0A 73 00 00 13 88 EC 68

1 电压 0048H                    4 读 16 进制无符号数 单位 0.0001V
2 电流 0049H                    4 读 16 进制无符号数 单位 0.0001A
3 有功功率 004AH            4 读 16 进制无符号数 单位 0.0001W
4 有功总电量 004BH         4 读/写 0 16 进制无符号数 单位 0.0001KWh
5 功率因数 004CH            4 读 16 进制无符号数 单位 0.001
6 二氧化碳排量 004DH     4 读 16 进制无符号数 单位 0.0001Kg
7 温度 004EH                    4 读 16 进制无符号数 单位 0.1℃
8 频率 004FH                    4 读 16 进制无符号数 单位 0.01Hz

从后往前分析数值:

13 88 十六进制转成十进制是50 00HZ;是中国居民用电标准的50HZ.

/* 接收数据放到数组 */
void Analysis_data(void) {
    // 电能数据的接收,其他数据也是类似
    // 注意:确保在调用此函数前,Rx3Buff已经填充了接收到的数据
    //电压数据3,4,5,6
    Voltage_data= (((uint32_t)(Rx3Buff[3])) << 24) | (((uint32_t)(Rx3Buff[4])) << 16) | (((uint32_t)(Rx3Buff[5])) << 8) | Rx3Buff[6];
    //电流数据7,8,9,10
    Current_data= (((uint32_t)(Rx3Buff[7])) << 24) | (((uint32_t)(Rx3Buff[8])) << 16) | (((uint32_t)(Rx3Buff[9])) << 8) | Rx3Buff[10];
    //总功率11,12,13,14
    Power_data = (((uint32_t)(Rx3Buff[11])) << 24) | (((uint32_t)(Rx3Buff[12])) << 16) | (((uint32_t)(Rx3Buff[13])) << 8) | Rx3Buff[14];
    //电能电量可清零擦写计数15,16,17,18
    Energy_data = (((uint32_t)(Rx3Buff[15])) << 24) | (((uint32_t)(Rx3Buff[16])) << 16) | (((uint32_t)(Rx3Buff[17])) << 8) | Rx3Buff[18];
    //功率因数19,20,21,22,23
    Pf_data = (((uint32_t)(Rx3Buff[19])) << 24) | (((uint32_t)(Rx3Buff[20])) << 16) | (((uint32_t)(Rx3Buff[21])) << 8) | Rx3Buff[22];
    //二氧化碳数据碳排放量25,26,27,28
    CO2_data = (((uint32_t)(Rx3Buff[24])) << 24) | (((uint32_t)(Rx3Buff[25])) << 16) | (((uint32_t)(Rx3Buff[26])) << 8) | Rx3Buff[27];
    //赫兹29,30,31,32
    Power_HZ = (((uint32_t)(Rx3Buff[29])) << 24) | (((uint32_t)(Rx3Buff[30])) << 16) | (((uint32_t)(Rx3Buff[31])) << 8) | Rx3Buff[32];
    
}

TX[13]:01 10 00 4B 00 02 04 00 00 00 00 B6 2C 依据这个写一个电能清零函数

void ClearEnergy(void)

{

    uint8_t txBuffer[13] = {0x01, 0x10, 0x00, 0x4B, 0x00, 0x02, 0x04, 0x00, 0x00, 0x00, 0x00, 0xB6, 0x2C};

    if(HAL_UART_Transmit(&huart3, txBuffer, sizeof(txBuffer), 1000) != HAL_OK)

    {

        // 发送失败的处理

        Error_Handler();

    }

}

猜你喜欢

转载自blog.csdn.net/2301_81235726/article/details/137594947