找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 1825|回复: 5
收起左侧

单片机串口通讯问题求助 读出来的数据总不对

[复制链接]
ID:382944 发表于 2022-3-4 07:12 | 显示全部楼层 |阅读模式
读一个传感器,串口通讯,读出来的数据总不对
cpu stc9c52  晶振11.0592   
接口定义 URAT        

端口名
接口用途
端口 1
接电源负极 (-)
端口 2
接电源正极 (+)
端口 3
A( RX
端口 4
B( TX
通讯协议
波特率
9600bps
数据位
8
停止位
1
校验位
串口数据流格式

B1
B2
B3
B4
B5
B6
模块地址
TVOC 高
TVOC 低
满量程高
满量程低
校验和
2Ch
   0XXh
    0XXh
    03h   
    0FFh
    0XXh

说明: B1 的内容 2Ch 是模块固定地址。校验和(B6)=unit_8(B1+B2+B3+B4+B5)
污染气体浓度值(mg/m3)=(TVOC 浓度高(B2)*256+TVOC 浓度低(B3))


程序:
void uart_init(u8 baud)
{
        TMOD|=0X20;        //设置计数器工作方式2
        SCON=0X50;        //设置为工作方式1
        PCON=0X00;        
        TH1=0XFD;        //计数器初始值设置
        TL1=0XFD;
        ES=1;                //打开接收中断
        EA=1;                //打开总中断
        TR1=1;                //打开计数器               
}


void uart() interrupt 4 //串口通信中断函数
{
        u8 rec_data;

        RI = 0;                        //清除接收中断标志位
        rec_data=SBUF;        //存储接收到的数据
         
        if (0x2c != rec_data)      --》这里0x2c是设备的地址,固定值,目前一直读不到这个值 ,每次都能都出6个数值,但一直没有0x2c
                {
                  
                        return;
                }
        uart_co2[uart_cou++]=rec_data;
        if (uart_cou == 6)
        {
                if(uart_co2[5]==uart_co2[0]+uart_co2[1]+uart_co2[2]+uart_co2[3]+uart_co2[4])
                                  temp_co2 = uart_co2[1]*256+uart_co2[2];
                 uart_cou = 0;
                 co2_ok = 1;
         }
         else
         {
                  uart_cou = 0;
         }                        
}

请指教
回复

使用道具 举报

ID:311903 发表于 2022-3-4 08:44 | 显示全部楼层
那你就看看这6个值,每次来一帧报文时,第一个字节是不是都是一样的;
此外,你这个串口接收代码逻辑不对,不应该每次都判断是否为0x2c,不是就退出
回复

使用道具 举报

ID:123289 发表于 2022-3-4 09:06 | 显示全部楼层
1、不要在【void uart() interrupt 4】进行数据处理。数据处理放在中断外进行。
2、【void uart() interrupt 4】只管下载数据,且来者不拒,来一个收一个。建立一个缓冲区,收到这此数据。
这时处理的好处是:【void uart() interrupt 4】耗时最小,占用主程序的时间就少,卡机的可能性就小。
分析缓冲区中的数据,就能知道问题在哪里了,如果没有问题,也不影响你计算目标值。
回复

使用道具 举报

ID:213173 发表于 2022-3-4 10:10 | 显示全部楼层
建议定义一个接收完成标志,接收与解析分开处理
  1. void uart() interrupt 4 //串口通信中断函数
  2. {
  3.         static uchar i=0;        //静态计数变量
  4.         RI=0;                                //接收中断请求标志位清0
  5.         uart_co2[i]=SBUF;        //接收到的数据串保存在缓存数组
  6.         if(uart_co2[0]==0x2c)//验证数据头(起始位)否则被后续数据覆盖
  7.         {
  8.                 i++;
  9.                 if(i>=6)
  10.                 {
  11.                         flag=1;                        //接收完成标志置1
  12.                         i=0;                        //计数变量清0
  13.                 }
  14.         }
  15. }

  16. void parsing()//解析函数放在主函数中调用
  17. {
  18.         uchar i;       
  19.         if(flag)
  20.         {
  21.                 flag=0;
  22.                 if(uart_co2[5]==uart_co2[0]+uart_co2[1]+uart_co2[2]+uart_co2[3]+uart_co2[4])//验证
  23.                         temp_co2 = uart_co2[1]<<8|uart_co2[2];//获取有效数据
  24.                 for(i=0;i<6;i++)
  25.                         uart_co2[i]=0;//清除缓存数组
  26.         }                     
  27. }
复制代码
回复

使用道具 举报

ID:121859 发表于 2022-3-4 10:27 | 显示全部楼层
可能是波特率有问题,主从双方不一致,或者波特率误差较大所致,将晶振改为11.0592MHz试试。
回复

使用道具 举报

ID:382944 发表于 2022-6-17 23:33 | 显示全部楼层
wulin 发表于 2022-3-4 10:10
建议定义一个接收完成标志,接收与解析分开处理

感谢大神指点,问题已解决,波特率设置问题。
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

手机版|小黑屋|51黑电子论坛 |51黑电子论坛6群 QQ 管理员QQ:125739409;技术交流QQ群281945664

Powered by 单片机教程网

快速回复 返回顶部 返回列表