看了一大堆乱七八糟的文章介绍本质上这个模块就是一个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();
}
}