本篇文章在基于本人第一篇文章(基于STM32 RS485传感器数据采集(参考正点原子部分代码)_stm32用rs485代码_做个有理想的程序员的博客-CSDN博客)修改过后 思路和步骤基本一样,我接着讲述不一样的部分
1、需要定义好两个传感器的地址和功能码,避免传输时,数据冲突,造成乱码现象
//主机命令区
u8 SlaverAddr_1=0x01; // 传感器1
u8 SlaverAddr_2=0x06; //传感器2
u8 SlaverAddr;
//振动传感器指令 01 03 00 00 00 04
u8 Fuction_1=0x03; // 功能码
u16 StartAddr_1=0x00; //起始地址
u16 ValueOrLenth_1=0x04; //数据or长度
//油含水率传感器指令 06 03 00 00 00 04
u8 Fuction_2=0x03; // 功能码
u16 StartAddr_2=0x00; //起始地址
u16 ValueOrLenth_2=0x04; //数据or长度
2、需要添加一个通讯策略,基于一个传感器上添加一个即可。因为两个传感器的功能码不一样,主机需要按顺序访问这两个丛机。
/
//通讯策略
void modbus_rtu(void) //中断4调用
{
static u8 i=0;
// static u8 j=0;
switch(i)
{
case 0: //modbus执行命令第一步。
//RS485_TX_Service(); //向从机发送一个请求。就在此时发送完成TX_RX_SET=1 发送命令完成,定时器T4处理接收到的数据
//在此处也可以直接写Master_Service( SlaverAddr, Fuction, StartAddr, ValueOrLenth);
//多次通讯结果可以按照类似的封装进行填写
if(shock_state == 0)
{
Master_Service(0x01);//测振动速度
shock_state = 1;
}
else
{
Master_Service(0x06);//测油中含油水分
shock_state = 0;
}
if(TX_RX_SET) i=1; //发送,接受命令切换。 0 发送模式 1 接受模式
state=1;
break;
case 1: //modbus命令执行第二步。
RS485_RX_Service(); //执行数据接收
state=2;
if(ComErr==0) //如果什么错误都没有发生
{
i=2;//完成命令更换功能码!
} //一次通讯已经完成
else //错误接收后再次准备接收
{
i=1;//
j++;//一个命令发送3次没有应答切换下一个命令
if(j>=2)
{
j=0;
i=2;
ComErr=7; //通讯超时
}
}
break;
case 2: //从机地址++
i=0;
state=3;
break;
}
}
3、从机 功能码01处理的程序添加上
void Master_01_Slove(u8 SlaverAddr_1,u8 Fuction_1,u8 StartAddr_1,u8 ValueOrLenth_1)
{
u16 calCRC;
RS485_TX_BUFF[0] = SlaverAddr_1;
RS485_TX_BUFF[1] = Fuction_1; //modbus 指令码03
RS485_TX_BUFF[2] = HI(StartAddr_1);
RS485_TX_BUFF[3] = LOW(StartAddr_1);
RS485_TX_BUFF[4] = HI(ValueOrLenth_1);
RS485_TX_BUFF[5] = LOW(ValueOrLenth_1);
calCRC=CRC_Compute(RS485_TX_BUFF,6);
RS485_TX_BUFF[6]=(calCRC>>8)&0xFF;
RS485_TX_BUFF[7]=(calCRC)&0xFF;
RS485_SendData(RS485_TX_BUFF,8);
}
4、然后对传感器采集的数据进行处理,每个传感器采集的数据格式有所不同,有的是单精度浮点数,有的是先低8位,在高8位.
void Modbus_01_Solve(void)
{
u8 rxlen=RS485_RX_CNT;
u8 i=0;
float temp_value=0;
float X_shock=0,Y_shock=0,Z_shock=0;
if(rxlen==RS485_RX_CNT&&rxlen)//接收到了数据,且接收完成了
{
for(i=0;i<rxlen;i++)
{
printf("%13x",RS485_RX_BUFF[i]);
}
printf("n");
RS485_RX_CNT=0; //清零
//温度值
temp_value=RS485_RX_BUFF[4]+(RS485_RX_BUFF[3]<<8);
printf("temp_value=%.1f \r\n",temp_value/10);
//X_shock
temp_value=RS485_RX_BUFF[6]+(RS485_RX_BUFF[5]<<8);
printf("X_shock=%.1f \r\n",X_shock/10);
//Y_shock
temp_value=RS485_RX_BUFF[8]+(RS485_RX_BUFF[7]<<8);
printf("Y_shock=%.1f \r\n",Y_shock/10);
//Z_shock
temp_value=RS485_RX_BUFF[10]+(RS485_RX_BUFF[9]<<8);
printf("Z_shock=%.1f \r\n",Z_shock/10);
}
TX_RX_SET=0; //命令完成
}
有什么问题可以直接咨询问,平时回复都比较及时