RS485简单的数据通信协议,接收端显示不正确,无法更新

2019-07-14 23:20发布

      各位大神,小弟出来贵地,烦请大神门帮帮忙呀,帮我解决下我的问题呀!
    我有两个板子A和B。我想做的东西是,A板实时采集环境温度并显示温度值,同时A板将采集到的温度数据通过RS485传送到B板,B板将接从A板接收到的温度数据也在液晶上显示出来。
     我自己写了一个简单单向的485传输协议
起始位0x24 十位 个位 小数位 校验位 结束0x23, 其中校验位是取:十位,个位和小数位之和。我将A板通过USB转485工具和电脑相连,电脑上打开串口助手,可以采集到当前的温度实时数据:比如27度到30度之间采集的数据是:
24 31 35 37 9D 23            
24 31 36 35 9C 23
24 31 36 33 9A 23
24 31 36 35 9C 23
24 31 36 35 9C 23
24 31 36 37 9E 23
24 31 36 35 9C 23
24 31 36 35 9C 23
24 31 36 37 9E 23
24 31 36 33 9A 23
24 31 36 37 9E 23
24 31 36 33 9A 23
24 32 33 37 9C 23
24 32 33 35 9A 23
24 32 33 37 9C 23
24 32 34 31 97 23
24 32 31 37 9A 23
24 32 31 39 9C 23
24 32 32 33 97 23
24 32 31 39 9C 23
24 32 31 39 9C 23
24 32 31 39 9C 23
24 32 31 37 9A 23
24 32 31 35 98 23
24 32 31 34 97 23
24 32 31 34 97 23
24 32 31 30 93 23

可以看出数据是正确的温度为0的时候,串口收到的数据是:24 30 30 30 90 23。
      现在的问题是B板子上接收到的温度数据不对,数据只能接收一次而且无法自动更新。我把B板用工具和电脑连接起来,通过串口助手发送数据,B板显示数据不正确,且无法更新数据。
      但是经我调试看,B板程序可以进入中断接收函数(我在中断里放了一个LED,一发数据进入中断接收灯就会亮一下)。我接收程序写得不好,就是不知道怎么写。大家帮帮我吧!小弟刚学没几天!再次恳请大家帮忙了!
      有能力的帮解决下,和我一样菜鸟的捧个人场,帮我顶顶!!!让大神看到帮我解决一下!!!小弟定感激涕零,无以言表!!!!
b12a48604fe6c9b5a6aef14955089b43_630.jpg

下面贴出程序代码:
//RS485接收/发送资源
//
uint8_t           aucTxBuff_UART4[256];                                //RS485发送缓冲区
uint8_t         aucRxBuff_UART4[256];                                //RS485接收缓冲区
uint16_t    uiRx4_DataLen = 0;                                        //接收数据长度
uint8_t     ucRx4_RcvReady = 0;                                        //为是则表示数据接收完毕
uint8_t     RS485_RX_CNT=0;                                                        //接收到的数据长度



*******************************************************************************************************************
                                 sum();求和函数
取温度值得十位,个位和小数位上的数据之和,作为校验字节返回

********************************************************************************************************************/
unsigned char sum(unsigned char *dat,unsigned char n)
{
unsigned char i;
unsigned char s_dat=0x00;
for(i=1;i<n+1;i++)
{
      s_dat+=dat;
    }

    return(s_dat);
}


          发送部分:


if(mode==2)//模式2界面
{
LCD12864_Display_Words(0, 2, "RS485");
LCD12864_Display_Words(0, 5, "模式");
LCD12864_Display_Words(1,0,"从机1:");
/***********************************************以下为自定义通讯协议***************************************************************/

Temperature =(sDevSystemPara.afAI_InputLast[0]/0.306)*100;//对pt100电流值进行处理转化为温度值,*10保留一位小数
temp = Temperature;//读取温度

aucRxBuff_UART4[0]=0x24;                //发送协议起始标志$
aucRxBuff_UART4[1]=temp%1000/100;       //存十位上的数据
aucRxBuff_UART4[2]=temp%100/10;         //存个位上的数据
aucRxBuff_UART4[3]=temp%10;             //存小数位上的数据
aucRxBuff_UART4[4]=sum(aucRxBuff_UART4,3);//存校验和
aucRxBuff_UART4[5]=0x23;                //发送协议结束标志位

UART4_SendData(aucRxBuff_UART4,6);        //从机向主句发送温度数据

OStimeDlyHMSM(0,0,0,1000);                //延时1秒
    }


接收部分:

if(mode==2)
{
LCD12864_Display_Words(0, 2, "RS485");
LCD12864_Display_Words(0, 5, "模式");
LCD12864_Display_Words(1,0,"从机1:");

                               //以下为接收部分代码
if(ucRx4_RcvReady == 1)//接收完成,数据均缓存到aucRxBuff_UART4[]里
{   

if(aucRxBuff_UART4[0]!=0x24)//判断头是不是起始标志0x24
   {
             uiRx4_DataLen=0;
            }
if(uiRx4_DataLen>6)//若接收字节大于6
   {
      uiRx4_DataLen=0;
      sum_reslut=0;
      sum_reslut=sum(aucRxBuff_UART4,3);//和校验求和
      if(sum_reslut==aucRxBuff_UART4[4])//校验和对则对接收的数据进行显示
        {  
   LCD12864_Write(0xf8,0x98);
   LCD12864_Write(0xfa,(aucRxBuff_UART4[1]+0x30));
   LCD12864_Write(0xfa,(aucRxBuff_UART4[2]+0x30));
   LCD12864_Write(0xfa,'.');
   LCD12864_Write(0xfa,(aucRxBuff_UART4[3]+0x30));

                                          }
   OSTimeDlyHMSM(0,0,0,1000);
            }

}




接收中断部分:

void UART4_IRQHandler(void)
{
u8 c;
static u8 flag = 0;
static u8 uiRx4_DataLen_Temp = 0;
if(USART_GetITStatus(UART4, USART_IT_RXNE) != RESET)
{
   USART_ClearITPendingBit( UART4, USART_IT_RXNE);         //清除中断位
            c=UART4->DR;
           if((c=='$')|(flag==1))
    {   
flag=1;
   
aucRxBuff_UART4[uiRx4_DataLen_Temp] = c;
uiRx4_DataLen_Temp++;
       if(c == '#')
{   

  ucRx4_RcvReady = 1;//置位一个接收完成标志?
uiRx4_DataLen = uiRx4_DataLen_Temp;//外部获取接收长度
  flag = 0;

}
    }
          else
    { flag=0;
      uiRx4_DataLen_Temp = 0;
     }
//aucRxBuff_UART4[uiRx4_DataLen] = c;
//uiRx4_DataLen++;
}
//处理IDLE中断
//当产生IDLE中断时,表示接收完毕一组完整的数据
else if(USART_GetITStatus(UART4, USART_IT_IDLE) != RESET)
{
//这个语句加上上面的判断语句结合起来才能清除IDLE中断
   c = UART4->DR;

//
//此时UART4数据接收完毕。
//用户可以处理数据。最好在主程序中处理,而不是在中断程序中处理。
//
  ucRx4_RcvReady = 1;
}
}
协议代码.zip (1.64 KB, 下载次数: 24)


















友情提示: 此问题已得到解决,问题已经关闭,关闭后问题禁止继续编辑,回答。