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;
    }
    
}

 

posted @ 2021-06-11 10:26  98年互联网打工老阿姨  阅读(342)  评论(0)    收藏  举报