【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
1楼-- · 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.                  
复制代码
enigama
2楼-- · 2019-07-15 20:51
1、下载上面的程序,单片机以0.5s间隔发送 AA AA 04 02 A1 A7。使用串口助手发送AA AA 0D 02 A0 2C 25 19 B5 1B 2C F2 8A F1 B4 ,1602显示AA AA 0D 02 A0 2C 25 19 B5 1B 2C F2 8A F1 B4 ,显示正常。
2、将传感器与单片机相连,1602有时候接收后不显示,有时候显示16*2个0.是否哪里时序不对?
enigama
3楼-- · 2019-07-16 00:39
 精彩回答 2  元偷偷看……
enigama
4楼-- · 2019-07-16 05:36
被自己弄醉了,原来是母头串口线的RX tX接反了,结贴

一周热门 更多>