关于串口数据的发送和接收(调试必备)_串口数据的接收与处理

设置好寄存器后,就可以包含头文件进来STDIO.h,调用函数printf就可以了,下面是效果图

掌握了这个技巧,就可以随时通过printf的方便性,将程序的寄存值,或者内存变量的值输出出来,人机交互非常方便。今天就暂时写在这里,后面会更新关于数据的接收的程序思路。

-------------------------------------续更2020/2/18

串口数据接收的程序设计

在学习串口数据的接收之前,首先我们总结一下之前的printf的发送程序。

1、需要包含STDIO.h库文件

2、需要配置串口波特率等基本设置,并且只是输出的话就将ES置为0

3、在使用printf之前一定要将TI置为1

好了,现在来学习串口数据的接收,串口数据的接收一定会需要串口中断,因为串口数据的发送可以根据意愿去调用,可以不用中断,但是串口数据的接收就非常需要串口中断了,因为你不知道什么时候数据发送过来,如果用查询法的话,每次都要去轮训,并且在没有操作系统的时候,轮训带来的时间延迟是接收数据所不能接受的。因此我们必须将ES置为1

我们来看一下串口中断的向量表

由此可以看见当ES置为1的时候,即ES开关闭合,则RI和TI(接收完成标志和发送完成标志) 都能够触发串口中断,它们都共用串口中断4.但是根据我们之前的发送程序描述,我们的发送是根据printf查询发送的,是根据查询TI是否为1来查询发送。但是如果ES也开启了,TI为1就会造成串口中断的发生,这样对发送的程序会有所影响,因此需要在串口中断中用程序加以避免。具体方法后面介绍。这样接收所需要的第一个步骤就清楚了,即ES = 1.接下来谈一下后面的思路。在打开串口中断允许后,数据来的时候,就会触发接收串口中断,RI会置为1。数据开始接收,但是由于我们不知道数据到底接收到好久才截止,因此不知道什么时候才可以拿完整的数据来用。这个时候,我们可以采用一种定时的思路,比如当接收开始后,即开启一个200ms或者100ms的定时(如果波特率是9600的话,在1s最多可以接收到960个字节(起始位+数据位+停止位 = 10bit),而100ms可以传输96个字节)

在定时结束后就可以给一个标志位,表示接收完成,这个时候就可以拿数据用了。不过仔细想想的话,如果数据只有2个字,但是定时为100ms,那么就有大量的时间被延迟,不能保证数据快速就可以使用,并且如果发送端数据间隔短的话,就会导致数据重叠,让数据失效!所以这种方法是用在安全性和响应要求不严的场合,不建议使用。那么我们就另外想一个办法,因为串口中断接收的时候都会触发中断,那么如果在接收到第一个字节进入中断的时候就清除RI并且开启一个时间更小的定时,然后在里面查询RI是否被置为1(因为一个字节接收完成后RI就会置1,注意从这里开始已经用查询法了)如果在这个小的定时器间隔内再次来数据了,就将重置定时,并且处理数据,清除RI位,重复上面的步骤,直到接收到一个字节后,启动定时后,没有数据来了,这个时候就会超时,超时后就可以置位接收完成标志并推出中断!这样就解决了上一个方法,定时时间过长,延迟过长的问题。我画一个简单的图来说明

我们来总结一下法二

1、ES = 1开启串口中断

2、第一个字节是以中断形式产生,后面的字节都是在中断中通过查询RI来接收

3、需要在接收每个字节后设置小定时,来判断是否接收结束,如果在小定时时间内RI = 1则继续接收重复上面的步骤,如果超时,则表示接收结束!

接下来是程序设计部分

全局变量
bit RxOK = 0; //接收完成标志
uchar Rx[RX_MAX];

//串口初始化
void UartInit(void) //9600bps@11.0592MHz
{
SCON = 0x50; //8位数据,可变波特率,不使用多机通信,允许接收
PCON = 0; //波特率不加倍
TMOD |= 0x20; //定时器1工作在八位自动重载模式下
TH1 = 0xFD; //设定定时初值
TL1 = 0xFD; //设定定时初值
TR1 = 1; //启动R1
ES = 1;

for(i = 0; i < RX_MAX; i++)
{
Rx[i] = ‘\0’;
}

}

void UartHandle() interrupt 4
{
if( RI )
{
//只要是进入RI说明一次数据的接收开始了(注意是一次性全部接收完)
//首先初始化要用到的变量
//数组索引i、一个字节之前用到的定时UartCnt,以及超时标志UartCntOK
uchar i;uint UartCnt = 0;bit UartCntOK = 0;
//首先进入for循环来接收数据
for( i = 0; i < RX_MAX; i++ ) //R_MAX是接收数组的最大值.
{
//将RI置零,以告诉串口发送端,我即将接收你发来的一个字节!
RI = 0;
Rx[i] = SBUF;//将数据接收
while( !RI ) //当RI为零的时候,表示没有数据发来,在while循环中等待数据发来,并开始计时

自我介绍一下,小编13年上海交大毕业,曾经在小公司待过,也去过华为、OPPO等大厂,18年进入阿里一直到现在。

深知大多数Go语言工程师,想要提升技能,往往是自己摸索成长或者是报班学习,但对于培训机构动则几千的学费,着实压力不小。自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!

因此收集整理了一份《2024年Go语言全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友,同时减轻大家的负担。
img
img
img
img
img

既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,基本涵盖了95%以上Golang知识点,真正体系化!

由于文件比较大,这里只是将部分目录大纲截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且后续会持续更新

如果你觉得这些内容对你有帮助,可以添加V获取:vip1024b (备注Go)
img

一个人可以走的很快,但一群人才能走的更远。不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎扫码加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!

ZNEYh-1713015039717)]

一个人可以走的很快,但一群人才能走的更远。不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎扫码加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!

  • 25
    点赞
  • 22
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值