RTT_modbus 485设备踩坑
rt_timer_t r_slave_t = rt_timer_create("r_check_t", check_timerout, RT_NULL, 3000, RT_TIMER_FLAG_ONE_SHOT); rt_timer_t w_slave_t = rt_timer_create("w_check_t", check_timerout, RT_NULL, 3000, RT_TIMER_FLAG_ONE_SHOT); 、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、 uint8_t WriteHoldReg(struct ModbusMasterDevice *MBM,uint16_t Addr,uint16_t Len,uint16_t *Data) { uint16_t CRC16 = 0; uint16_t CRC16_Receive = 0; uint8_t i = 0; //rt_timer_t timerout = (rt_timer_t)rt_device_find("w_check_t"); rt_timer_t timerout = (rt_timer_t)rt_object_find("w_check_t",RT_Object_Class_Timer); switch(MBM->State) { case 0: { MBM->UDM->TransmitBuf[0] = MBM->DeviceAddr; MBM->UDM->TransmitBuf[1] = 0x10; MBM->UDM->TransmitBuf[2] = Addr>>8; MBM->UDM->TransmitBuf[3] = Addr; MBM->UDM->TransmitBuf[4] = Len>>8; MBM->UDM->TransmitBuf[5] = Len; MBM->UDM->TransmitBuf[6] = Len*2; for(i=0;i<Len;i++) { MBM->UDM->TransmitBuf[i*2+7] = *(Data+i)>>8; MBM->UDM->TransmitBuf[i*2+8] = *(Data+i); } CRC16 = CRC16_CHECK(MBM->UDM->TransmitBuf,7+Len*2); MBM->UDM->TransmitBuf[8+Len*2] = CRC16>>8; MBM->UDM->TransmitBuf[7+Len*2] = CRC16; transmit(MBM->UDM->name, (char *)MBM->UDM->TransmitBuf, MBM->UDM,9+Len*2); rt_timer_start(timerout); MBM->timeout_en = 0; MBM->State ++; }break; case 1: { MMD = MBM; /*±ÜÃⳬʱҰָÕë*/ if(MBM->UDM->ReceiveFinish) { CRC16_Receive = (MBM->UDM->ReceiveBuf[MBM->UDM->ReceivePoint-1]<<8)|MBM->UDM->ReceiveBuf[MBM->UDM->ReceivePoint-2]; CRC16 = CRC16_CHECK(MBM->UDM->ReceiveBuf,MBM->UDM->ReceivePoint-2); if(CRC16_Receive == CRC16) { MBM->WHR_Success = 1; } MBM->State = 0; ClearRxData(MBM->UDM); return 1; } else if(MBM->timeout_en == 1) { MBM->State = 0; ClearRxData(MBM->UDM); rt_timer_stop(timerout); return 1; } }break; } return 0; }
【问题描述!!!】解决不接风速风向设备,其他485设备无法调度的问题。
详细原因:因风速风向设备通信很费劲,会使得通信一直处于超时状态,并清除缓冲区。(其实此时已经接受到数据只是没处理)
导致在上层pmt计数时,停滞在case2,认为一直未发送成功,实际上从机已经回复。
【解决方案】
由于风速风向设备通信很特殊,即 如果在同一条总线上发生数据传输,即使不是他的数据他也会罢工不响应一段时间(一两秒)。
为解决此问题,将超时定时器延长至3秒!!!(其实2秒也行),之后即使没有风速风向设备也能进行正常通信运转。
case 2:
{
if(pmt1.MMD.WHR_Success == 1)
{
pmt1.MMD.WHR_Success = 0;
State++;
LOG_W("2if");
}
else
{
State = 1;
LOG_W("2else");
}
}break;
void RS485Device1Handle(void) { // LOG_E("HAN485"); if(TaskHandle(THP1.Enable, ReadTHP, &THP1, &BusTake, 1) != 0) { return; } if(TaskHandle(pmt1.SetEnable, SetPMT, &pmt1, &BusTake, 2) != 0) { return; } if(TaskHandle(pmt1.BusyEnable, BusyPMT, &pmt1, &BusTake, 3) != 0) { return; } if(TaskHandle(pmt1.ReadEnable, ReadPMT, &pmt1, &BusTake, 4) != 0) { return; } rt_thread_mdelay(100); if(TaskHandle(wind_sp.Enable, ReadWS, &wind_sp, &BusTake, 5) != 0) { return; } rt_thread_mdelay(100); if(TaskHandle(wind_di.Enable, ReadWD, &wind_di, &BusTake, 6) != 0) { return; } }

浙公网安备 33010602011771号