串口传输(51单片机版)

介绍

原理

串口传输在51单片机里是非常重要的一点,这常常是在中断、计数器后面学习,因为不可避免的需要用到中断。51单片机的串口,是个全双工的串口,发送数据的同时,还可以接收数据。
当串行发送完毕后,将在标志位 TI 置 1,同样,当收到了数据后,也会在 RI 置 1。只要串口中断处于开放状态,单片机都会进入串口中断处理程序。在单片机的中断程序中,要区分出来究竟是发送引起的中断,还是接收引起的中断,然后分别进行处理。
每当收到一个新数据,就在中断函数中,把 RI 清零,并用一个变量,通知主函数,收到了新数据。
发送数据时,很多的程序都是使用的“查询方式”,就是执行 while(TI ==0); 这样的语句来等待发送完毕。没有发送完的时候就会一直在循环里。

常出现的错误

  1. 有人在发送数据之前,先关闭了串口中断!等待发送完毕后,再打开串口中断。这样,在发送数据的等待期间内,如果收到了数据,将不能进入中断函数,也就不会保存的这个新收到的数据。这种处理方法,就会遗漏收到的数据。
  2. 有人在发送数据之前,并没有关闭串口中断,当 TI = 1 时,是可以进入中断程序的。但是,却在中断函数中,将 TI 清零! 这样,在主函数中的while(TI ==0);将永远等不到发送结束的标志。
  3. 还有人在中断程序中,并没有区分中断的来源,反而让发送引起的中断,执行了接收中断的程序。
  4. 自己常用的方法:
    接收数据时,使用“中断方式”,清除 RI 后,用一个变量通知主函数,收到新数据。
    发送数据时,也用“中断方式”,清除 TI 后,用另一个变量通知主函数,数据发送完毕。
    这样一来,收、发两者基本一致,编写程序也很规范、易懂。更重要的是,主函数中,不用在那儿死等发送完毕,可以有更多的时间查看其它的标志。

实例代码

#include "reg52.h"    //此文件中定义了单片机的一些特殊功能寄存器
typedef unsigned int u16;   //对数据类型进行声明定义
typedef unsigned char u8;
void UsartInit()//设置串口
{
 SCON=0X50;   //设置为工作方式1
 TMOD=0X20;   //设置计数器工作方式2
 PCON=0X80;   //波特率加倍
 TH1=0XF3;    //计数器初始值设置,注意波特率是4800的
 TL1=0XF3;
 ES=1;      //打开接收中断
 EA=1;      //打开总中断
 TR1=1;     //打开计数器
}
void main()
{ 
 UsartInit();  // 串口初始化
 while(1);  
}
void Usart() interrupt 4
{
 u8 receiveData;
 receiveData=SBUF;//出去接收到的数据
 RI = 0;//清除接收中断标志位
 SBUF=receiveData;//将接收到的数据放入到发送寄存器
 while(!TI);    //等待发送数据完成
 TI=0;       //清除发送完成标志位
}

结尾与扩展

如果想进行更深的使用和了解。可以在我们项目实战专栏里查看更多内容。在哪里有更多的代码注释可以帮助理解,还有项目工程源码可供提取。
我把利用串口打印超声波距离等项目实战都放在了那里。

发布了30 篇原创文章 · 获赞 29 · 访问量 9299

猜你喜欢

转载自blog.csdn.net/qq_44629109/article/details/105456954