简述单片机串行口的工作方式

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了简述单片机串行口的工作方式相关的知识,希望对你有一定的参考价值。

简述单片机串行口的工作方式

89系列单片机的串行通信有4种工作方式:

1、方式0是同步移位寄存器方式,帧格式8位,波特率固定为fosc/12。

2、方式1是8位异步通信方式,帧格式10位,波特率可变:T溢出率/n(n= :32或16)。

3、方式2是9位异步通信方式,帧格式11位,波特率固定: fosc/n(n=32 或16)。

4、方式3是9位异步通信方式,帧格式11位,波特率可变:T溢出率(m=32或16)。

方式1、2、3的区别主要表现在帧格式及波特率两个方面。

单片机应用范围:

单片机渗透到我们生活的各个领域。导弹的导航装置,飞机上各种仪表的控制,计算机的网络通讯与数据传输,工业自动化过程的实时控制和数据处理,广泛使用的各种智能IC卡,民用豪华轿车的安全保障系统,录像机、摄像机、全自动洗衣机的控制等等。

还有自动控制领域的机器人、智能仪表、医疗器械以及各种智能机械。因此,单片机的学习、开发与应用将造就一批计算机应用与智能化控制的科学家、工程师。

参考技术A 51 单片机内部有一个全双工串行接口。什么叫全双工串口呢?一般来说,只能接受或只能发送的称为单工串行;既可接收又可发送,但不能同时进行的称为半双工;能同时接收和发送的串行口称为全双工串行口。串行通信是指数据一位一位地按顺序传送的通信方式,其突出优点是只需一根传输线,可大大降低硬件成本,适合远距离通信。其缺点是传输速度较低。

串口可以有底下四种工作方式
1、方式0
串行接口的工作方式0为移位寄存器I/O方式。在串行口外接移位寄存器以扩展I/O接口,也可以外接串行同步I/O的设备。
(1)方式0输出
  串行口以方式0发送时,数据以RXD端串行输出,TXD端输出同步信号。当一个数据写入串行口发送缓冲器以后,就启动串行口发送器以振荡频率的十二分之一的波特率,将数据从RXD端串行输出。
(2)方式0输入
  当串行口定义为方式0并置位REN后,便启动串行口以方式0接收数据,此时RXD端为数据输入端,TXD端为同步脉冲信号输出端。接收器以振荡率的十二分之一的波特率接收RXD端输入的数据信息。但接收器接收到8位数据时,置1中断标志RI。
2、方式1
串行接口定义为工作方式1时,则被控制为8位的异步通讯接口,传送一帧信息为10位,其中1位为起始位,8位数据位(先低位后高位),1位停止位。
(1)方式1输出
串行接口以方式1发送时,数据由TXD端输出。CPU执行一条数据写入发送缓冲
器SBUF的指令(例如,MOV  SBUF,A),数据字节写入SBUF后,便启动串行口发送器发送,发送完一帧信息,置1放送中断标志TI。
(2)方式1输入
串行口以方式1接收时,数据从RXD端输入。在REN置1以后,就允许接收器接收。接收器以所建立的波特率的16倍分频计数器,以便实现时间同步。计数器的16个状态把一位的时间等分成16份,在每位时间的第7、8和9个计数状态,位检测器采样RXD的值,接收的值是3次采样中取至少二次相同的值,以排除噪声的干扰。如果在起始接收的值不是0,则起始位无效,复位接收电路。在检测到另一个1到0的跳变时,再重新启动接收器。如果接收到值为0,起始位有效,则开始接收本帧的其余信息。当RI=0并且接收到的停止位为1(或SM2=0)时,停止位进入RB8,接收到的8位数据进入接收缓冲器SBUF,置位RI中断标志。接着接收便搜索另一帧信息的起始位。
3、方式2和方式3
串行接口工作方式2和方式3时,则被定义为9位的异步通信接口。传送一帧信息为11位,其中1位起始位,8位数据位(从低位至高位),1位是附加的可程控为1或0的第9位数据,1位停止位。
方式2和方式3的差别仅仅在于波特率不一样,方式2的波特率是固定的,波特率为2SMOD/64(振荡频率);方式3的波特率是可变的,波特率=2SMOD/32(T1的溢出率)。
方式2和方式3在发送和接收时唯一的区别就是波特率不同。
(1)方式2和方式3发送
方式2或方式3发送时,数据由TXD端输出,发出一帧信息为11位,附加的第9位数据是SCON中的TB8,CPU执行一条数据写入发送缓冲器SBUF的指令,就启动发送器发送,发送完一帧信息,置“1”TI中断标志。
(2)方式2和方式3接收
串行口被定义为方式2或方式3接收时,数据从RXD端输入,置REN=1以后,开始接收过程。当检测到RXD端从高到低的负跳变时,确认起始位有效,开始接收本帧的其余信息。在接收完一帧信息后,在RI=0、SM2=0时,或接收到第9位数据为“1”时,8位数据装入接收缓冲器,第9位数据装入SCON中RB8,并置RI=1。若不满足上述的两个条件,接收到的信息将会丢失,也不置位RI

STC51从入门到精通(汇编)~~~ 第八讲:串行通信技术


目录

​8.1 80C51单片机串行通信技术的特点​

​8.2 串行通信基本知识​

​8.2.1 数据通信​

​8.2.2 串行通信的传输方式​

​8.2.3 异步通信和同步通信​

​8.3 串行接口的组成和特性​

​8.3.1 串行口的结构​

​8.3.2 串行口控制器及控制寄存器​

​8.4  串行通信接口的工作方式​

​8.4.1 工作方式0​

​8.4.2 工作方式1​

​8.4.3 工作方式2和工作方式3​

​8.5  波特率设计​

​8.5.1 波特率的计算方法​

​8.5.2 波特率的产生  ​

​8.6 C语言程序示例​


8.1 80C51单片机串行通信技术的特点

  • 80C51单片机具有一个全双工串行通信接口,即能同时进行串行发送和接收。
  • 可以作UART(通用异步接收和发送器)
  • 可以作同步位移寄存器用。
  • 可以实现点对点的单机通信、多机通信和80C51与系统机的单机或多机通信。

8.2 串行通信基本知识

8.2.1 数据通信

通信方式有两种,即并行通信串行通信:

       并行通信是指数据的各位同时进行传送(发送或接收)的通信方式。其优点是传送速度快;缺点是数据有多少位,就需要多少根传送线。

       串行通信指数据是一位一位按顺序传送的通信方式。它的突出优点是只需一对传输线(利用电话线就可作为传送线),这样就大大降低了传送成本,特别适用于远距离通信;其缺点是传送速度较低。

8.2.2 串行通信的传输方式

  • 单工(或单向)配置,只允许数据向一个方向传送
  • 半双工(或半双向)配置,允许数据向两个方向中的任一方向传送,但每次只能有一个发送,一个接收;
  • 全双工(全双向)配置,允许同时双向传送数据,因此,全双工配置是一对单向配置,它要求两端的通信设备都具有完整和独立的发送和接收能力。

8.2.3 异步通信和同步通信

1、异步通信

STC51从入门到精通(汇编)~~~

  • 帧格式:一个字符由四部分组成:起始位、数据位、奇偶校验位和停止位。
  • 起始位(0):占用一位,用来通知接收设备一个待接收的字符开始到达。
  • 数据位:5~8位数据(规定低位在前,高位在后)
  • 奇偶校验位(可省略):也可用来确定一帧中的字符所代表信息的性质(地址/数据等)。
  • 停止位(1):停止位用来表征字符的结束。停止位可以是1位、1.5位或2位。接收端收到停止位后,知道上一字符已传送完毕

2、同步通信

STC51从入门到精通(汇编)~~~

3、波特率

1、波特率的定义每秒钟传送二进制数码的位数(亦称比特数),单位是b/s

2、假设数据传送速率是120字符/s,而每个字符格式包含10个代码(1个起始位、1个终止位、8个数据位)。这时,传送的波特率为

            (10b/字符)×120字符/s = 1200 b/s

8.3 串行接口的组成和特性

8.3.1 串行口的结构

STC51从入门到精通(汇编)~~~

  • 组成:两个物理上独立的串行数据缓冲寄存SBUF、发送控制器、接收控制器、输入移位寄存器和输出控制门。
  • 发送缓冲寄存器SBUF只能,不能读;
  • 接收缓冲寄存器SBUF只能,不能写。
  • 两个缓冲寄存器共用一个地址99H,可以用读/写指令区分。
  • 串行发送时,通过MOV SBUFA写指令,写入发送SBUF(99H),再由TxD一位一位地向外发送;
  • 串行接收时,RxD一位一位地接收数据,直到收到一个完整的字符数据后通知CPU,再通过MOV  ASBUF读指令,CPU从接收SBUF(99H)读出数据,送到累加器A中。

8.3.2 串行口控制器及控制寄存器

1、串行口控制寄存器SCON(98H)

STC51从入门到精通(汇编)~~~

SM0、SM1:串行口工作方式控制位,两位对应四种工作方式,如下表所示(fosc是晶振频率)。

STC51从入门到精通(汇编)~~~

8.4  串行通信接口的工作方式

8.4.1 工作方式0

      SM0 SM1=00时,串行接口选择工作方式0,为同步移位寄存器输入/输出方式,常用于扩展I/O口。串行数据通过RXD输入或输出,而TXD用于输出移位时钟,作为外接部件的同步信号。发送或接收的是8位数据(低位在前,高位在后)。

STC51从入门到精通(汇编)~~~

8.4.2 工作方式1

  1. 工作方式1SM0 SMl= 01,为可变波特率8位异步通信方式
  2. 发送数据由TXD端输出,接收数据由RXD端输入。
  3. 方式1以10位为一帧传输,设有1个起始位(0)8个数据位和1个停止位(1)。其帧格式起始位(0),8个数据位和1个停止位(1)。

8.4.3 工作方式2和工作方式3

SM1 SM0= 10串行接口选择工作方式2

SM1 SM0= 11串行接口选择工作方式3

方式2或方式3是一个9位的异步串行通信接口TXD为数据发送端,RXD为数据接收端。

方式2波特率固定为fosc/64或fosc/32

方式3波特率由定时器T1或T2 (80C52)的溢出率所确定

方式2和方式3以11位为1帧传输,设有1个起始位(0)8个数据位,1个附加第9位和1个停止位(1)

8.5  波特率设计

8.5.1 波特率的计算方法

1. 方式0波特率

方式0波特率 = fosc 12

若振荡器频率fosc = 12MHz,则波=fosc/12=12MHz/12=1MHz/s,即1μs移位一次。

2. 方式2波特率

方式2波特率 = (2^SMOD/64) × fosc

SMOD0时,波特率等于振荡器频率的1/64SMOD1时,波特率等于振荡器频率的1/32

3. 方式1和方式3的波特率

串行口方式1和方式3的波特率由定时器T1T2(89C52等单片机)的溢出率和SMOD所确定。

8.5.2 波特率的产生  

1. 用定时器T1产生波特率

方式1和方式3波特率 =(2^SMOD/32) ×(T1溢出率)

溢出周期 =12/振荡器频率×(256-X)

溢出率为溢出周期的倒数,所以有

波特率 = 2^SMOD ×振荡器频率/[32×12×(256-X)]

定时器T1在工作方式2时的初值为

X = 256 - fosc×(SMOD+1)/(384×波特率)

8.6 C语言程序示例

/*******************************************************************************
================================================================================
【平 台】STC89C51_sumjess平台
【编 写】sumjess
【软件版本】V2.0
【最后更新】2019年06月10日
【相关信息参考下列地址】
【网 站】
http://www.51hei.com/bbs/mcu-2-1.html
---------------------------------------------------------------------------------
【dev.env.】MDK4.02及以上版本
【Target 】STC89C51
第一次修订:2019/05/09
第二次修订:2019/05/21
第三次修订:2019/06/10
【problem 】
(1)库内补充的不全面;
(2)库内解释部分不全面;
(3)库内还存在一定的bug;
【direction】
下一步的目标就是把库继续集成!
【explain 】
为了方便使用,我也自己写了很多的库,和优化了算法和表示方式!
【warning】
目前程序中暂无错误 !
---------------------------------------------------------------------------------
没有完美的代码,只有不断的奉献,大家一起努力;
赠人玫瑰手留余香,欢迎大家反馈bug!
================================================================================
********************************************************************************/
#include <reg52.h> //编译器自带的库用 < > 编译器包含C52的定义
#include "UART_Sum.h"
//
//STC51只有一个串口 RXD---P3.0 TXD---P3.1
//
/*以下为四种波特率的计算公式:
//
//方式0的波特率 = f(osc)/12
//方式1的波特率 = 2^(SMOD)/32 x (T1溢出率)
//方式2的波特率 = 2^(SMOD)/64 x f(osc)
//方式3的波特率 = 2^(SMOD)/32 x (T1溢出率)
//
//式中f(osc)为系统晶振频率,通常为12MHz或11.0592MHz;SMOD是PCON寄存器的最高位- SMOD=0;串口方式1,2,3时,波特率正常。SMOD=1;串口方式1,2,3时,波特率加倍。
// T1溢出率即定时器T1溢出的频率-只要算出T1定时器
//每溢出一次所需的时间T,那么T的倒数1/T就是他的溢出率。

//只有定时器2可以减少由于时间上带来的误差,因为方式二可以自动装载 */


// 在在具体操作串行口之前,需要对单片机的一些与串口有关的特殊寄存器做初始化设置,主要是设置产生波特率的定时器1、串行口控制和中断控制,具体步骤如下:
// 一、确定T1的工作方式(编程TMOD寄存器);
// 二、计算T1的初值,装载TH1,TL1;
// 三、启动T1(编程TCON中的TR1位);
// 四、确定串行口工作方式(编程SCON寄存器);
// 五、串行口工作在中断方式时,要进行中断设置(编程IE,IP寄存器)。

// 常用波特率初值表
//
//波特率 晶振 初值 误差(%) 晶振 初值 误差(12MHz晶振)(%)
//(bps) (MHz) (SMOD=0) (SMOD=1) (MHz)(SMOD=0) (SMOD=1) (SMOD=0) (SMOD=1)
//300 11.0592 0xA0 0X40 0 12 0X98 0X30 0.16 0.16
//600 11.0592 0XD0 0XA0 0 12 0XCC 0X98 0.16 0.16
//1200 11.0592 0XE8 0XD0 0 12 0XE6 0XCC 0.16 0.16
//1800 11.0592 0XF0 0XE0 0 12 0XEF 0XDD 2.12 -0.79
//2400 11.0592 0XF4 0XE8 0 12 0XF3 0XE6 0.16 0.16
//3600 11.0592 0XF8 0XF0 0 12 0XF7 0XEF -3.55 2.12
//4800 11.0592 0XFA 0XF4 0 12 0XF9 0XF3 -6.99 0.16
//7200 11.0592 0XFC 0XF8 0 12 0XFC 0XF7 8.51 -3.55
//9600 11.0592 0XFD 0XFA 0 12 0XFD 0XF9 8.51 -6.99
//14400 11.0592 0XFE 0XFC 0 12 0XFE 0XFC 8.51 8.51
//19200 11.0592 —— 0XFD 0 12 —— 0XFD —— 8.51
//28800 11.0592 0XFF 0XFE 0 12 0XFF 0XFE 8.51 8.51

/*
方式0时,串行口为同步移位寄存器的输入/输出方式,主要用于扩展并行输入或输出口。
!!!注意!!!串行口工作模式0并不是一个同步串口通信方式,他主要用途是与外面的同步移位寄存器相连。 具体见本篇程序下文件夹的word
数据由RXD(P3.0)引脚输入或输出,同步移位脉冲由TXD(P3.1)引脚输出。发送和接收均为8位数据,低位在先,高位在后。
方式0的波特率 = f(osc)/12
*/
void Init_UART_0(void) //使用方式1 --- 1次中断为5ms,200次为1s

SCON=0; //设置T1定时器工作方式2
EA=1; //开总中断
ES=1; //开串口中断
TI=0;

#if 0
/配合主函数定时使用示例
输出波形///
void main()

Init_UART_0();
while(1)

SBUF=0xaa; //发送接收到的数据
delay(1);


void serial() interrupt 4

TI=0;

#endif
/*
方式1的波特率 = 2^(SMOD)/32 x (T1溢出率)
方式1是10位数据的异步通信口,其中1位起始位,8位数据位,1位停止位。
TXD(P3.1)为数据发送引脚,RXD(P3.0)为数据接收引脚。
其传输波特率是可变的,对于51单片机,波特率由定时器1的溢出率决定。
通常我们在做单片机与单片机串口通信、单片机与计算机串口通信、计算机与计算机串口通信时,基本都选择方式1,因此这种方式大家务必要完全掌握。
*/
void Init_UART_1(void) //使用方式1 --- 1次中断为5ms,200次为1s

TMOD=0x20; //设置T1定时器工作方式2
TH1=0xfd; //T1定时器装初值
TL1=0xfd; //T1定时器装初值
TR1=1; //启动T1定时器
REN=1; //允许串口接收
SM0=0; //设定串口工作方式1
SM1=1; //设定串口工作方式1
EA=1; //开总中断
ES=1; //开串口中断

#if 0
//如果不使用可不写中断服务函数/
/配合主函数定时使用示例
//收到什么发什么///
uchar b=0,flag=0;
void main()

Init_UART_1();
while(1)

if(flag==1)

ES=0; //发送数据时,关串口中断
flag=0; //清除标志位
SBUF=b; //发送接收到的数据
while(!TI);//直到发送完毕,发送结束TI为1
TI=0; //置0,准备下一次发送
ES=1; //开启串口中断



void serial() interrupt 4

b=SBUF; //赋值,读取接收到的数据
flag=1; //写入标志位
RI=0; //置0等待下次中断


#endif

/*
方式2,3都为11位数据的异步通信口。
TXD(P3.1)为数据发送引脚,RXD(P3.0)为数据接收引脚。
这两种方式下,起始位1位,数据9位(含1位附加的第9位,发送时为SCON中的TBS,接收时为RBS),停止位1位,一帧数据为11位。
方式2的波特率固定为晶振频率的1/64或1/32,方式3的波特率由定时器Tl的溢出率决定。
方式2和方式3的差别仅在于波特率的选取方式不同,在两种方式下,接收到的停止位与SBUF,RBS及RI都无关。
方式2的波特率 = 2^(SMOD)/64 x f(osc)
*/
void Init_UART_2(void) //使用方式2 --- 具体情况时,需修改

SCON = 0x50; //REN=1允许串行接受状态,串口工作模式2 (1010 0000) SM0 SM1 SM2 REN
TMOD|= 0x20; //定时器工作方式2
PCON|= 0x80; //波特率提高一倍
TH1 = 0xF4; //波特率2400、数据位8、停止位1。效验位无 (12M)
TL1 = 0xF4; //因为 PCON|= 0x80; 波特率提高一倍为4800
TR1 = 1; //开启定时器1
ES = 0; //开串口中断
EA = 0; // 开总中断

#if 0
void main()

Init_UART_2();
while(1)

SBUF=0x01; //发送接收到的数据
delay(1);


void serial() interrupt 4

TI=0;

#endif
/*
方式2,3都为11位数据的异步通信口。
TXD(P3.1)为数据发送引脚,RXD(P3.0)为数据接收引脚。
这两种方式下,起始位1位,数据9位(含1位附加的第9位,发送时为SCON中的TBS,接收时为RBS),停止位1位,一帧数据为11位。
方式2的波特率固定为晶振频率的1/64或1/32,方式3的波特率由定时器Tl的溢出率决定。
方式2和方式3的差别仅在于波特率的选取方式不同,在两种方式下,接收到的停止位与SBUF,RBS及RI都无关。
方式2的波特率 = 2^(SMOD)/64 x f(osc)
*/
void Init_UART_3(void) //使用方式3 --- 具体情况时,需修改

TMOD = 0x20; // 定时器1 方式 2
SM0=1; // 设定串口工作方式3
SM1=1; // 设定串口工作方式3
TH1 = 0XFD; // 定时器1初值
TL1 = 0XFD; // 定时器1初值
EA=1; // 开总中断
ES = 1; // 串口中断
TR1 = 1; // 开启定时器1
TI=0; //置0,准备下一次发送

#if 0
void main()

Init_UART_3();
while(1)

SBUF=0xaa; //发送接收到的数据
delay(1);


void serial() interrupt 4

TI=0;

#endif

 

以上是关于简述单片机串行口的工作方式的主要内容,如果未能解决你的问题,请参考以下文章

求助:单片机串行口输出的数据是啥类型

AVR--IO结构分析

arduino IO口

单片机串口中断接收

单片机单片机知识点提纲3

async/await 如何以串行和并行方式工作?