找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 666|回复: 5
打印 上一主题 下一主题
收起左侧

小白求助 关于51单片机串口数据处理

[复制链接]
跳转到指定楼层
楼主
判断从串口接收到的两个字节,即4位16进制的数据,如果第一个字节对了led1亮然后判断第二个,第二个字节对了led3亮。
但是令我很好奇的是某些数据是对的,另一些却不能正确判断
如fafb, e1d1 ,等,灯可以正常亮起。f开头的字节都可以
但是数字开头的字节,比如5a7b,1111等就不行。


正常

以下是我的单片机程序(初学者,很拉,不同的地方很多)
#include <reg51.h>

#define uchar unsigned char
#define uint  unsigned int

sbit led0 = P0^0; //接收到数据时闪烁
sbit led1 = P0^1;
sbit led2 = P0^2;
sbit led3 = P0^3;
sbit led4 = P0^4;

uchar num1,num2;//读取SBUF
void UART_init(){        TR1=0;
        TMOD =0x20;          //T1工作模式2  8位自动重装
        TH1 = 0xfd;
        TL1 = 0xfd;         //0xfd波特率9600。
        ET1 = 0;
        TR1 = 1;                //启动T1定时器
         
        PCON =0x00;         //若0x80 SMOD置1,波特率加倍
        REN=1;                 //看似无用实则不可缺失
        SCON = 0x50;                //串口允许接收
        EA  = 1;                //开总中断
        ES  = 1;                //串口中断打开
}
void main()
{        
        UART_init(); //串口初始化
        while(1)
        {
        }        
}


void UART() interrupt 4
{         
        while(!RI);        //检测是否接收完成
                RI = 0;
                led0 = ~led0;
                num1 = SBUF;        
                P1 = ~num1;
        
                if(num1==0x5A)
                {   led1=0;  //第一个字节对了之后led1亮
                        while(!RI);
                        led2=0;
                        RI=0;
                        num2=SBUF;
                        if(num2==0xA5)
                        led3=0;                 //第二个字节对了之后led3亮
                }
                else {led1=1;led2=1;led3=1;}
        
}
分享到:  QQ好友和群QQ好友和群 QQ空间QQ空间 腾讯微博腾讯微博 腾讯朋友腾讯朋友
收藏收藏 分享淘帖 顶 踩
回复

使用道具 举报

沙发
ID:94031 发表于 2023-6-7 18:27 | 只看该作者
在串口中断里应该只处理数据接收,LED处理放在main循环里,不要因为LED处理影响数据接收。
回复

使用道具 举报

板凳
ID:1082596 发表于 2023-6-7 20:06 | 只看该作者
xuyaqi 发表于 2023-6-7 18:27
在串口中断里应该只处理数据接收,LED处理放在main循环里,不要因为LED处理影响数据接收。

判断和LED处理已放进主循环,并且仅判断一个字节。
仍只有部分数据led1可正常亮起,如ff.fb等
请问这是什么原因呢?我该如何解决嘞。求大佬指点
这是修改后的程序
void main()
{       
        UART_init(); //串口初始化
        while(1)
        {  
                if(num1==0x5A)
                {   led1=0;  //第一个字节对了之后led1亮
                }
                else led1=1;
       
        }       
}

void UART() interrupt 4
{         
        while(!RI);        //检测是否接收完成
                RI = 0;       
                num1 = SBUF;
                       
}
回复

使用道具 举报

地板
ID:1082659 发表于 2023-6-7 21:04 | 只看该作者
串口中断函数接收第一个字节之后,开启定时器计数。接受下一个字节的时候清空定时器计数。如此,当没有数据接收后,计时器无法清零,当计时器计数超过设定的数值之后,触发定时器溢出中断,此时数据即接收完毕
回复

使用道具 举报

5#
ID:1082596 发表于 2023-6-7 21:53 | 只看该作者
我把接收到的字节数据赋给了P2,P2接了8个LED灯。注意到一个现象,从串口接收到的数据,最高位会被莫名其妙地置1。比如5A(01011010),会被认为是DA(11011010)。其他的数据也是如此。这可能就是为什么部分数据可以成功识别(最高位已经是1的,如fa,e1等),而剩下的不能成功(最高位不是1的,如5A)
可是我没写让最高位 置一的程序
???
如下图所示。接收到的是5A(01011010),显示的却是DA(11011010)
感谢各位大佬的解答

1.png (14.96 KB, 下载次数: 19)

1.png
回复

使用道具 举报

6#
ID:1082596 发表于 2023-6-7 21:54 | 只看该作者
刘宇杰找实训 发表于 2023-6-7 21:04
串口中断函数接收第一个字节之后,开启定时器计数。接受下一个字节的时候清空定时器计数。如此,当没有数据 ...

谢谢解答
回复

使用道具 举报

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

本版积分规则

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

Powered by 单片机教程网

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