前言

人类生存于世,少不了沟通。沟通使人类互相认知,传递信息,提升生活品质。但然单片机也需要,不然单单一个机器,无法构成一个系统,发挥更大的力量。只有单片机与外围设备传递信息,互相反馈才会有一个完美的系统。串行口通信就被发明出来,下面来了解串行口通信(uart)。

几个概念

为了能更好理解串行口通信,在介绍它之前,先来看看几个概念,补充知识,方便深入明白uart工作原理。

通信方式


通信方式有两种,分别是并行通信串行通信
并行通信:并行是指多比特数据同时通过并行线进行传送,这样数据传送速度大大提高,但并行传送的线路长度受到限制,因为长度增加,干扰就会增加,数据也就容易出错。
串行通信:串行通信是指 使用一条数据线,将数据一位一位地依次传输,每一位数据占据一个固定的时间长度。其只需要少数几条线就可以在系统间交换信息,特别适用于计算机与计算机、计算机与外设之间的远距离通信。
拿汽车通道来说,并行通信就是多车道,多辆车一起行驶,而串行通信就是单车道,只能一辆一辆车通过。

串行通信制式


串行通信制式有单工通信,半双工通信,双工通信三种。
单工通信:单工通信信道是单向信道,发送端和接收端的身份是固定的,发送端只能发送信息,不能接收信息;接收端只能接收信息,不能发送信息,数据信号仅从一端传送到另一端,即信息流是单方向的。
半双工通信:半双工数据传输指数据可以在一个信号载体的两个方向上传输,但是不能同时传输。例如,在一个局域网上使用具有半双工传输的技术,一个工作站可以在线上发送数据,然后立即在线上接收数据,这些数据来自数据刚刚传输的方向。像全双工传输一样,半双工包含一个双向线路(线路可以在两个方向上传递数据)。
双工通信:双工通信是指在同一时刻信息可以进行双向传输,和打电话一样,说的同时也能听,边说边听。这种发射机和接收机分别在两个不同的频率上(两个频率差有一定要求)能同时进行工作的双工机也称为异频双工机。
三种通信制式很容易理解,对照上图看,单工通信不就是单方面通信,只能发出指令或接收指令。半双工通信就是能接收又能发送,但是不能同时进行。双工就最厉害,可以同时发送和接收指令。

串行通信分类

串行通信有两种,一位异步串行通信,二为同步串行通信。
异步串行通信:异步串行通信是指通信双方以一个字符(包括特定附加位)作为数据传输单位且发送方传送字符的间隔时间不一定,具有不规则数据段传送特性的串行数据传输。
同步串行通信:所谓同步通信是指在约定的通信速率下,发送端和接收端的时钟信号频率和相位始终保持一致(同步),这就保证了通信双方在发送和接收数据时具有完全一致的定时关系。
两种串行通信不同就只有时间,在发送字符时,异步可以是不同时间间隔发送,但同步只能以固定的时间间隔发送。

波特率

波特率:波特率表示每秒钟传送的二进制位数,是衡量数据传送速率的指标,它用单位时间内载波调制状态改变的次数来表示。
相互通信的甲乙双方必须具有相同的波特率,不然无法成功完成串行通信。

概述

52单片机具有一个全双工串行通信口。一个全双工UART(通用异步接收发送器)的串行I/O口,用于实现单片机之间或单片机与微机之间的串行通信;片内振荡器和时钟产生电路,石英晶体和微调电容需要外接。最佳振荡频率为6M—12M。管脚RXD( P3.0),TXD(P3.1)与串口通信有关。波特率可以设置。

内部结构


串行口通信与三个寄存器有关,分别是:

 1. PCON寄存器2. SCON寄存器3. SBUF特殊功能寄存器

寄存器

PCON电源管理寄存器


SMOD:该位与串口通信有关。
SMOD=0; 串口方式1,2,3时,波特率正常。
SMOD=1; 串口方式1,2,3时,波特率加倍
LVDF:低电压检测标志位,同时也是低电压检测中断请求标志位
GF1,GF0:两个通用工作标志位,用户可以自由使用。
PD:掉电模式设定位。
PD=0 单片机处于正常工作状态。
PD=1 单片机进入掉电(Power Down)模式 ,可由外部中断或硬件复位模式唤醒,进入掉电模式后,外部晶振停振,CPU、定时器、串行口全部停止工作,只有外部中断工作。在该模式下,只有硬件复位和上电能够唤醒单片机。
IDL:空闲模式设定位。
IDL=0 单片机处于正常工作状态。
IDL=1 单片机进入空闲(Idle)模式,除CPU不工作外,其余仍继续工作,在空闲模式下可由任一个中断或硬件复位唤醒。

这个寄存器只有SMOD位与串行口通信有关。系统复位默认为SMOD=0。当为用52单片机的定时器2产生波特率时,波特率不受SMOD影响。用定时器1产生波特率时,不去设置,就默认为0,波特率正常,设置为1时,波特率加倍。

SCON串行口控制寄存器


SM0,SM1:共同决定串行口工作模式。
SM2:多机通信控制位。在方式0中,SM2一定要等于0。在方式1中,当SM2为1时则只有接收到有效停止位时,RI才置1。在方式2或3中,当SM2为1且接收到的第9位数据RB8为0时,RI才置1。
REN:接收允许控制位。由 软件置位以允许接收,又由 软件清零来禁止接收。
TB8:要发送数据的第9位。在方式2或3中,要发送的第9位数据,根据需要由软件置1或清零软件置1或清零。例如,可约定作为奇偶校验位,或在多机通信中作为区别地址帧或数据帧的标志位。(很少用)
RB8:接收到的数据的第9位。在方式0中不使用RB8。在方式1中,若SM2为0,RB8为接收到的停止位。在方式2或3中,RB8为到的第9位数据。(很少用)
TI:发送中断标志。在方式0中,第8位发送结束时,由 硬件置位。在其它方式的发送停止位前,由 硬件置位。TI置位既表示一帧信息发送结束,同时也向CPU申请中断。可根据需要,用软件查询的方法获得数据已发送完毕的信息,或用中断的方式来发送下一个数据。TI必须用 软件清零
RI:接收中断标志位。在方式0中,当接收完第8位数据后,由 硬件置位。在其它方式中,在接收到停止位的中间时刻由硬件置位(例外情况见对SM2的说明)。RI表示一帧数据接收完毕,可用查询的方法获知或者用中断的方法获知。RI也必须用 软件清零

由于52单片机内部有一个硬件模块,让它自动接收数据,接收完了,通知我们一下就可以了,就不需要再手动配置TB8,RB8。只要配置好SCON,内部就自动帮弄好了。

SBUF特殊功能寄存器


SBUF是指串行口中的两个缓冲寄存器,一个是发送寄存器,一个是接收寄存器,在物理结构上是完全独立的,但地址是重叠的。它们都是字节寻址的寄存器,字节地址均为99H。只要在编写程序时,用不同指令即可操作两个寄存器。
比如,SBUF=A;这个是指将A的数据移入发送寄存器,然后发送寄存器再把数据发送出去。A=SBUF;则是指将接受寄存器中的数据赋值给A。

串行口方式1


串行口为10位通用异步接口。发送或接收一帧数据信息为10位,包括1位起始位“0”、8位数据位、1位停止位“1”。发送数据:数据从TXD端口输出,当数据写入发送缓冲器SBUF时,就启动发送器发送。发送完一帧数据后,置中断标志TI=1,申请中断,通知CPU可以发送下一个数据了。接收数据:首先使REN=1(允许接收数据),串行口从RXD接收数据,当采样到1至0跳变时,确认是起始位“0”,就开始接收一帧数据,当接收完一帧数据时,置中断标志RI=1,申请中断,通知CPU从SBUF取走接收到的数据 。

计算波特率


溢出速率即溢出频率,只要算出定时器每溢出一次所需要的时间T,那溢出率就是1/T。计算在没有波特率加倍(SMOD=0)的情况下,波特率为9600bps时怎样赋值计数器。这里说明一下,由于波特率是需要很精确的,不然通信会出错。如果采用定时器工作模式1,采用人工重载,会有较大误差,因为进入中断函数也需要时间,累积时间就会出错。所以这里运用工作模式2,8位自动重装。计数器自动重装不需人工干预,减少误差。
对照上面公式,波特率不加倍,SMOD=0,工作模式2,那n=8,波特率=9600,就可以算出x=253,十六进制为fd。

编写步骤

  1. 设置串行口方式
  2. 设置定时器工作模式
  3. 计数器寄存器赋值
  4. 中断寄存器控制
  5. 启动定时器中断
  6. 发送函数
  7. 接收函数

范例1

#include<reg52.h>
unsigned char date; //定义变量数据中断
bit flag;  //定义变量标志
void send (); //声明发送函数
void receive (); //声明接收函数
void initialize (); //声明初始化函数
main()
{       initialize();  //调用初始化函数while(1){send();       //调用发送函数receive(); //调用接收函数}
}
void initialize()  //初始化函数
{SCON=0X50;       //0011 0000 串行口工作模式1TMOD = 0X20;    //定时器1工作模式2,8为自动重装TH1 = 0xFD;       //设定定时初值        波特率为9600TL1 = 0xFD;        //设定定时器重装值TR1 = 1;     //启动定时器1IE=0;
}
void send()      //发送函数
{if(flag==1)     //证明已经接收数据{  SBUF=date;   //将接收的数据发送出去while(!TI);     //等待发送中断TI=0;          //软件置0flag=0;          //清零}}
void receive()     //接收函数
{while(!RI);      //等待接收中断date=SBUF;     //将收到的数据存进接收缓冲寄存器RI=0;        //软件置0flag=1;      //将标志位置1
}

范例1是将接受的数据原封不动发送出去。采用查询法,故不需要打开串口中断,不用中断函数。只需不断查询TI,RI的值,就知道数据接收发送情况。

范例2

#include<reg52.h>
unsigned char date;
bit flag;
main ()
{SCON=0X50;        //初始化TMOD=0X20;TH1=0XFD;                                  TL1=0XFD;IE=0X90;TR1=1;while(1);
}
void interrupt_uart() interrupt 4    //中断函数
{if(RI==1)         //判断有无数据接收{date=SBUF;    //将寄存器的值赋给变量RI=0;          //置0flag=1;        //标志位置1}if(flag==1)             //已接收数据{SBUF=date;          //将数据发出while(!TI);TI=0;flag=0;}
}

与范例1如出一撤,就不详细注释。

总结

在串口通信中,方式1是最常用的,要认真理解方式1。串行数据一位一位的已经不用处理了,52单片机已经有一个模块处理完了。只要知道接收一个数据,产生一次接收中断,要软件置0.,发送一个数据会产生一次发送中断,也要软件置0。自行置0,处理好数据就OK。下一篇将介绍其他三种方式,欢迎关注。

uart串行口通信(一)相关推荐

  1. max232c语言,串行口通信(STC89C52+MAX232):串行口通信硬件设计详解

    一. STC89C52与MAX232连接原理图 二. 串行口通信原理 1. 基本通信方式 a. 并行通信 定义: 将数据字节的各位用多条数据线同时进行传送, 每一位数据都需要一条传输线, 还需要一条信 ...

  2. 20.串行口通信原理及操作流程

    c 第六章:串行口通信原理及操作流程 6.1并行与串行基本通行方式 单片机通信是指单片机与计算机或单片机与单片机之间的信息交换,后者的通信通常用的较多. 通信有并行和串行龄种方式,在单片机系统以及现代 ...

  3. 51单片机—详细(存储器RAM/ROM、引脚、中断系统、定时/计数器、串行口通信)

    目录 一.数据存储器RAM 1.拓展RAM 2.片内256字节 1.高128位(80H~FFH) 2.低128位(00H~7FH) 二.程序存储器ROM 三.引脚 1.4组8位并行I/O口 2.其他引 ...

  4. 51单片机学习 串行口通信实验

    文章目录 一.实验目的 二.原理 三.实验内容 一.实验目的 掌握串行口工作方式的程序设计,掌握单片机通信程序设计方法. 二.原理 发送指令:MOV SBUF,A 接收指令:MOV A,SBUF 1. ...

  5. python与单片机如何进行串行口通信_51单片机的串行口通信方式

    介绍:串行口是单片机与外界进行信息交换的工具. 8051单片机的通信方式有两种: 并行通信:数据的各位同时发送或接收. 串行通信:数据一位一位次序发送或接收.参看下图: 串行通信的方式: 异步通信:它 ...

  6. 串行口通信c语言代码,问一下单片机串行口通信用c语言实现的问题

    该楼层疑似违规已被系统折叠 隐藏此楼查看此楼 这个是上面项目中用的子程序: /************************************************************* ...

  7. 串行口发送子程序C语言,基于C语言的RS232串行接口通信实现

    摘要:串口通信是一种广泛使用且实用的通信方式,介绍RS232串行通信的联结方式,研究利用c语言编程实现RS232串行通信的过程.结合实际应用,在约定双方串行通信协议的基础上,运用C语言开发的串行通信软 ...

  8. 串行异步通信_单片机串行口介绍

    串行口是单片机与外界进行信息交换的工具,8051单片机的通信方式有两种: 并行通信:数据的各位同时发送或接收. 串行通信:数据一位一位次序发送或接收. 串行通信的方式 异步通信 用一个起始位0表示字符 ...

  9. 树莓派 SPI,I2C,UART串行总线介绍

    很多人对总线,串行等概念不熟悉特别是SPI,I2C,UART,GPIO等概念. 因此我收集了一些资料,用于总结.希望对大家有所帮助. 首先看一下树莓派上的接口: GPIO引脚 x 26 UART总线 ...

最新文章

  1. python发明者叫什么-编程语言简史:有人不喜欢花括号,于是他发明了 Python
  2. spark提交应用的全流程分析
  3. Spring,Reactor和ElasticSearch:使用伪造的测试数据进行标记
  4. mcq 队列_MCQ | 基础知识 免费和开源软件| 套装4
  5. ningx修改mysql数据库密码_windows下面的php+mysql+nginx
  6. 【论文写作】文献资料的作用只是添砖加瓦
  7. Javascript分号,加还是不加?
  8. IntelliJ中可能的东西在Eclipse中是不可能的?
  9. 后缀树(Suffix tree)
  10. TF-tf.keras.layers.Dense
  11. javascript中数组循环的方式
  12. Java入门到精通(干就完了)
  13. 单片机上面的继电器工作原理及其作用
  14. 玻利亚(Polya)的《怎样解题》
  15. 单元测试、集成测试、系统测试的不同
  16. 美式英语 [t] 的发音
  17. 业绩差距拉大 11家消费金融公司座次洗牌
  18. 巾帼绽芬芳 一起向未来(中篇)
  19. UML建模工具-火龙果软件
  20. java中使用length获取二维数组的长度

热门文章

  1. 用于物联网安全性和匿名性的轻量级可扩展区块链 LSB A Lightweight Scalable Blockchain for IoT security and anonymity
  2. vue中获取组件的位置
  3. 模拟仿造wifi信号登录界面(实验)
  4. 如何在 XAMPP 中使用 不同的 PHP 版本
  5. 【微信小程序】(三)订阅消息实现
  6. 从键盘输入5个英文单词,输出其中以元音字母开头的单词
  7. (免费分享)C#多店进销存管理系统源码 连锁店进销存ERP源码
  8. 27行代码批量将PPT转成PDF,属实强大啊!
  9. 0代码定制物联网远程控制APP——物联网平台ThingsCloud简单入门
  10. linux终端游戏编程,GitHub - zhaodianbo/richman: 一个Linux终端的大富翁游戏,C语言编程练习...