现在手上有一个传感器,测量结果用串口输出,输出频率1HZ。输出的格式是帧数据(十六进制)的形式,帧头是0XAA 0XAA,始终检测不到帧头。
做了以下实验:
1、用传感器与PC端直连,用串口助手查看结果,可以检测到帧头,且数据正常。
2、用
单片机与PC端直连,用单片机发送消息,波特率9600,数据位8,正常
通信。
3、用单片机与传感器相连,按上述2个实验,波特率应该无误。但是帧数据是15个字节,每次只能收到13个字节。
问:
1、既然波特率无误,为什么会漏掉2个字节内容,而且每个周期都一样呢?
2、我尝试在接收中断里用if(Buffer==某个特定字节),在检测过程中,经常出现跳帧的情况,本来应该1s能够检测到1个,但实际上,有时候会突然漏掉一个,下一秒又正常了。这又是为什么呢?
希望各位前辈能不吝赐教。
- #include <STC12C5A60S2.h>
- #include <string.h>
- #include <stdio.h>
- #include<LCD.h>
- #define uchar unsigned char
- #define uint unsigned int
- #define Data_H 0XAA //帧数据定义:2个帧头
- #define Data_Length 0X0D //帧数据定义:帧长
- #define Data_Address 0X02 //帧数据定义:地址位
- #define Data_Cmd //帧数据定义:命令字
- #define Data_X_H //
- #define Data_X_L //
- #define Data_Y_H //
- #define Data_Y_L //
- #define Data_Tempratrue //帧数据定义:温度
- #define Data_Check //帧数据定义:校验位
- static uchar counter = 0; //字符接收计数
- uchar receive[15]; //接收缓冲数组
- bit start_flag = 0; //帧开始接收位
- bit finish_flag = 0; //帧接收完成位
- uchar Rec_Angle[20];
- unsigned char code Single_Output[6]={0xAA,0xAA,0x04,0x02,0xA0,0XA6};
- unsigned char code Continous_Output[6]={0xAA,0xAA,0x04,0x02,0xA1,0XA7};
- void Uart_One_Send(uchar c)
- {
- ES=0; //关中断
- SBUF=c; //将字符c赋值给
- while(TI!=1); //等待发送结束
- TI=0; //软件置零
- ES=1; //开中断
- }
- void Uart_One_String(uchar *p,uint length)
- {
- uint k=0;
- do
- {
- Uart_One_Send(*(p+k));
- k++;
- }while(k<length);
- }
- void Uart_init(void) //9600bps@11.0592MHz 串口初始化
- {
- ES=0;
- PCON &= 0x7F; //波特率不倍速
- SCON = 0x50; //8位数据,可变波特率
- AUXR |= 0x40; //定时器1时钟为Fosc,即1T
- AUXR &= 0xFE; //串口1选择定时器1为波特率发生器
- TMOD &= 0x0F; //清除定时器1模式位
- TMOD |= 0x20; //设定定时器1为8位自动重装方式
- TL1 = 0xDC; //设定定时初值
- TH1 = 0xDC; //设定定时器重装值
- ET1 = 0; //禁止定时器1中断
- TR1 = 1; //启动定时器1
- ES=1;
- EA=1;
- }
- void delay100us(uint z)
- {
- uint i,k;
- for(i=0;i<z;i++)
- for(k=0;k<125;k++);
- }
- void CLR_Rec_Angle() //清除接收指针缓存
- {
- uchar k;
- for(k=0;k<15;k++)
- Rec_Angle[k]=0;
-
- }
- void Uart_One_Receive() interrupt 4
- {
- ES=0;
- if(TI)
- {
- TI=0;
- }
- if(RI)
- {
- RI=0;
- receive[counter++] = SBUF;
- if(counter==15)
- {
- counter=0;
- finish_flag=1;
- }
-
-
- /*********************************************中断用于接收15个字节*********************************/
- // if(counter == 0 && receive[counter] == Data_H) //判断第一个字节是否是第一个帧头AA
- // {
- // counter = 1;
- // }
- // else if(counter==1&&receive[counter]==Data_H) //判断第二个字节是否是第二个帧头AA
- // {
- // counter = 2 ;
- // }
- // else if(counter == 2 && receive[counter] == Data_Length) //判断第三个字节是否是帧长度13个字节
- // {
- // counter = 3;
- // start_flag = 1 ;
- // }
- // else if(counter != 14 && counter>2 ) //后续数据接收
- // {
- // counter++;
- // }
- // else if(counter == 14 ) //最后的校验位接收
- // {
- // uint temp,j ;
- // uint result = 0;
- // counter = 0;
- // for(j=0;j<14;j++)
- // {
- // temp = result^receive[j];
- // result= temp;
- // }
- // if(result==receive[14]) //数据校验
- // {
- // finish_flag = 1;
- // counter=0;
- // }
- // }
- // else if(counter > 14)
- // {
- // counter = 0;
- // }
- /*********************************************中断用于接收15个字节*********************************/
-
- }
- ES=1;
- }
- void main()
- {
- uchar *p = Continous_Output;
- uint i = 0 ;
- uint j = 8 ;
- delay100us(10000);
- L1602_init();
- delay100us(20000);
- wcmd(0xc1+0x01);
- L1602_string(1,1,"Linking...") ;
- Uart_init();
- delay100us(10000);
- L1602_string(1,1,"Setting...");
- delay100us(10000);
- wcmd(0x01);
-
- /*****************************************十六进制显示******************************************/
- // wcmd(0x80);
- // display_num(receive[0]);
- // wcmd(0x82);
- // display_num(receive[1]);
- // wcmd(0x84);
- // display_num();
- // wcmd(0xc0);
- // display_num(0xAA);
- /*****************************************十六进制显示******************************************/
-
- while(1){
-
- Uart_One_String(p,6);
- delay100us(5000);
- /*****************************************1602显示接收的数据******************************************/
- if(finish_flag)
- {
- wcmd(0x01);
- finish_flag = 0;
- for(i=0;i<8;i++) //第一行显示前8位
- {
- wcmd(0x80+0x02*i);
- display_num(receive[i]);
- }
- for(j=8;j<15;j++) //第二行显示后7位
- {
- wcmd(0xc0+0x02*(j-8));
- display_num(receive[j]);
- }
- delay100us(5000) ;
- }
- /*****************************************1602显示接收的数据******************************************/
-
- /**********************************************十进制显示******************************************/
- // if(receive[counter])
- // {
- //
- // wcmd(0xc1);
- // x1 = counter;
- // L1602_char(2,1,x1/100+0x30);
- // L1602_char(2,2,x1%100/10+0x30);
- // L1602_char(2,3,x1%10+0x30);
- // }
- /**********************************************十进制显示******************************************/
- }
-
- // Read_Angle();
- }
-
复制代码2、将传感器与单片机相连,1602有时候接收后不显示,有时候显示16*2个0.是否哪里时序不对?
一周热门 更多>