【STC12C5A60S2】串口通信无法检测数据

2019-07-15 16:16发布

现在手上有一个传感器,测量结果用串口输出,输出频率1HZ。输出的格式是帧数据(十六进制)的形式,帧头是0XAA 0XAA,始终检测不到帧头。
做了以下实验:
1、用传感器与PC端直连,用串口助手查看结果,可以检测到帧头,且数据正常。
2、用单片机与PC端直连,用单片机发送消息,波特率9600,数据位8,正常通信
3、用单片机与传感器相连,按上述2个实验,波特率应该无误。但是帧数据是15个字节,每次只能收到13个字节。
问:
1、既然波特率无误,为什么会漏掉2个字节内容,而且每个周期都一样呢?
2、我尝试在接收中断里用if(Buffer==某个特定字节),在检测过程中,经常出现跳帧的情况,本来应该1s能够检测到1个,但实际上,有时候会突然漏掉一个,下一秒又正常了。这又是为什么呢?
希望各位前辈能不吝赐教。
友情提示: 此问题已得到解决,问题已经关闭,关闭后问题禁止继续编辑,回答。
4条回答
enigama
2019-07-15 16:54
先把代码放出来,慢慢改吧
  1. #include <STC12C5A60S2.h>
  2. #include <string.h>
  3. #include <stdio.h>
  4. #include<LCD.h>
  5. #define uchar unsigned char
  6. #define uint unsigned int


  7. #define Data_H 0XAA                                                 //帧数据定义:2个帧头
  8. #define Data_Length 0X0D                                //帧数据定义:帧长
  9. #define Data_Address 0X02                                //帧数据定义:地址位
  10. #define Data_Cmd                                                //帧数据定义:命令字
  11. #define Data_X_H                                                //
  12. #define Data_X_L                                                //
  13. #define Data_Y_H                                                //
  14. #define Data_Y_L                                                //
  15. #define Data_Tempratrue                                        //帧数据定义:温度
  16. #define Data_Check                                                //帧数据定义:校验位

  17. static uchar counter = 0;                  //字符接收计数

  18. uchar receive[15];                                  //接收缓冲数组

  19. bit start_flag = 0;                                //帧开始接收位
  20. bit finish_flag = 0;                        //帧接收完成位

  21. uchar Rec_Angle[20];
  22. unsigned char code Single_Output[6]={0xAA,0xAA,0x04,0x02,0xA0,0XA6};
  23. unsigned char code Continous_Output[6]={0xAA,0xAA,0x04,0x02,0xA1,0XA7};


  24. void Uart_One_Send(uchar c)
  25. {
  26.         ES=0;                                //关中断
  27.         SBUF=c;                                //将字符c赋值给
  28.         while(TI!=1);                //等待发送结束
  29.         TI=0;                                //软件置零
  30.         ES=1;                                //开中断
  31. }
  32. void Uart_One_String(uchar *p,uint length)
  33. {
  34.         uint k=0;
  35.         do
  36.         {
  37.                 Uart_One_Send(*(p+k));
  38.                 k++;
  39.         }while(k<length);       
  40. }
  41. void Uart_init(void)                //9600bps@11.0592MHz  串口初始化
  42. {
  43.         ES=0;
  44.         PCON &= 0x7F;                //波特率不倍速
  45.         SCON = 0x50;                //8位数据,可变波特率
  46.         AUXR |= 0x40;                //定时器1时钟为Fosc,即1T
  47.         AUXR &= 0xFE;                //串口1选择定时器1为波特率发生器
  48.         TMOD &= 0x0F;                //清除定时器1模式位
  49.         TMOD |= 0x20;                //设定定时器1为8位自动重装方式
  50.         TL1 = 0xDC;                //设定定时初值
  51.         TH1 = 0xDC;                //设定定时器重装值
  52.         ET1 = 0;                //禁止定时器1中断
  53.         TR1 = 1;                //启动定时器1
  54.         ES=1;
  55.         EA=1;
  56. }
  57. void delay100us(uint z)
  58. {
  59.         uint i,k;
  60.         for(i=0;i<z;i++)
  61.                 for(k=0;k<125;k++);
  62. }
  63. void CLR_Rec_Angle()           //清除接收指针缓存
  64. {
  65.         uchar k;
  66.         for(k=0;k<15;k++)
  67.                 Rec_Angle[k]=0;
  68.        
  69. }

  70. void Uart_One_Receive() interrupt 4
  71. {               
  72.         ES=0;
  73.         if(TI)
  74.         {
  75.           TI=0;          
  76.         }
  77.         if(RI)
  78.         {
  79.                 RI=0;       
  80.                 receive[counter++] = SBUF;
  81.                 if(counter==15)
  82.                 {
  83.                         counter=0;
  84.                         finish_flag=1;
  85.                 }
  86.                

  87.                


  88. /*********************************************中断用于接收15个字节*********************************/
  89. //                if(counter == 0 && receive[counter] == Data_H)                //判断第一个字节是否是第一个帧头AA
  90. //                        {
  91. //                                counter = 1;
  92. //                        }
  93. //                else if(counter==1&&receive[counter]==Data_H)        //判断第二个字节是否是第二个帧头AA
  94. //                        {
  95. //                                counter = 2 ;
  96. //                        }
  97. //                else if(counter == 2 && receive[counter] == Data_Length)        //判断第三个字节是否是帧长度13个字节
  98. //                        {
  99. //                                counter = 3;
  100. //                                start_flag = 1 ;
  101. //                        }
  102. //                else if(counter != 14 && counter>2 )        //后续数据接收
  103. //                        {
  104. //                                counter++;                                                       
  105. //                        }
  106. //                else if(counter == 14 )                             //最后的校验位接收
  107. //                        {
  108. //                                uint temp,j ;
  109. //                                uint result = 0;
  110. //                                counter = 0;
  111. //                                for(j=0;j<14;j++)
  112. //                                {
  113. //                                        temp = result^receive[j];
  114. //                                        result= temp;       
  115. //                                }
  116. //                                if(result==receive[14])                        //数据校验
  117. //                                {
  118. //                                        finish_flag = 1;
  119. //                                        counter=0;
  120. //                                }
  121. //                        }       
  122. //                else if(counter > 14)
  123. //                {
  124. //                                counter = 0;
  125. //                }
  126. /*********************************************中断用于接收15个字节*********************************/
  127.                
  128.         }
  129.                 ES=1;
  130. }





  131. void main()
  132. {       
  133.         uchar *p = Continous_Output;
  134.         uint i = 0 ;
  135.         uint j = 8 ;
  136.         delay100us(10000);
  137.         L1602_init();
  138.         delay100us(20000);
  139.         wcmd(0xc1+0x01);
  140.         L1602_string(1,1,"Linking...")  ;
  141.         Uart_init();
  142.         delay100us(10000);
  143.         L1602_string(1,1,"Setting...");
  144.         delay100us(10000);
  145.         wcmd(0x01);

  146.                        
  147. /*****************************************十六进制显示******************************************/       
  148. //                wcmd(0x80);
  149. //                display_num(receive[0]);
  150. //                wcmd(0x82);
  151. //                display_num(receive[1]);
  152. //                wcmd(0x84);
  153. //                display_num();
  154. //                wcmd(0xc0);
  155. //                display_num(0xAA);       
  156. /*****************************************十六进制显示******************************************/       
  157.                   
  158.         while(1){
  159.                        
  160.                            Uart_One_String(p,6);
  161.                         delay100us(5000);


  162. /*****************************************1602显示接收的数据******************************************/       
  163.                         if(finish_flag)
  164.                         {
  165.                                 wcmd(0x01);
  166.                                 finish_flag = 0;
  167.                                 for(i=0;i<8;i++)                          //第一行显示前8位
  168.                                 {
  169.                                         wcmd(0x80+0x02*i);
  170.                                         display_num(receive[i]);
  171.                                 }
  172.                                 for(j=8;j<15;j++)                          //第二行显示后7位
  173.                                 {
  174.                                         wcmd(0xc0+0x02*(j-8));
  175.                                         display_num(receive[j]);
  176.                                 }
  177.                                 delay100us(5000) ;
  178.                         }
  179. /*****************************************1602显示接收的数据******************************************/       

  180.                
  181. /**********************************************十进制显示******************************************/
  182. //                if(receive[counter])
  183. //                {                                 
  184. //               
  185. //                          wcmd(0xc1);
  186. //                        x1 = counter;
  187. //                        L1602_char(2,1,x1/100+0x30);
  188. //                        L1602_char(2,2,x1%100/10+0x30);
  189. //                        L1602_char(2,3,x1%10+0x30);
  190. //                }
  191. /**********************************************十进制显示******************************************/
  192.                 }
  193.        
  194. //        Read_Angle();
  195. }
  196.                  
复制代码

一周热门 更多>