移位寄存器集成到单片机中,数据按位顺序一次传输一个比特

传输控制

时钟脉冲的控制,发送数据的频率

  • 发送数据时: 发送时钟的下降沿将数据串行移位输出
  • 接收数据时: 接收时钟的上升沿开始对数据位采样

串行通信的结构

Pasted image 20240611230912.png

特殊功能寄存器:

1. 引脚

并行 IO 口的 P3 口 数据接收 RXD Receive Data 数据发送 TXD Transmit Data RXD — TXD TXD — RXD

2. 发送接收

发送电路 发送缓冲器 SBUF 99H Transmit Buffer 只能写入 MOV SBUF,A 发送

接收电路 接收缓冲器 SBUF 99H Receive Buffer 只能读出 MOV A,SBUF 接收

名字和地址均相同,都为 8 位寄存器 但是实际上(物理上)有两个 SBUF 通过程序的先后位置,区别 SBUF

  • 输出逻辑电路,一位一位送走
  • 输入移位寄存,实现数据接收

3. 控制寄存器

串行口控制寄存器 SCON
电源控制寄存器 PCON

串行通信的方式

异步通信

Universal Asynchronous Receiver/Transmitter (UART) 只需一对传输线,大大降低了传送成本,特别适用于远距离通信

异步通信以帧为单位 Frame 一帧数据由四部分组成

起始位数据位校验位终止位
0SBUFTB81

起始位 0,终止位 1 为硬件的设置, 由硬件发送,无需软件设值 发送接收数据的第九位为校正位

速率指标

波特率/比特数:Baud Rate 每秒钟发送二进制数码的位数 bits per second
以位/秒为单位记作,即b/s 记为 bps

8051串口.png

波特率:

\dfrac{2^{SMOD}}{32}\times \dfrac{f_{osc}}{12\times(256-X)} \end{align}$$ - $X$ 为定时器设置的初值 - $f_{osc}$ 为外部晶振振荡的频率 本质上是不断地[[分频\|分频]] **11.0592M 分频** 当外部晶振 $f_{osc}=11.0592M\; Hz$ 时 国际上规定的标准串行传输波特率系列为 110、300、600、1200、2400、4800、9600、19200、38400 | 波特率(BPS) | 晶振频率(MHZ) | SMOD | 定时器初值 | | -------- | ----------- | ---- | -------- | | 1200 | 11.0592 | 0 | 0E8H | | **2400** | **11.0592** | 0 | **0F4H** | | 4800 | 11.0592 | 0 | 0FAH | | 9600 | 11.0592 | 0 | 0FDH | | 19200 | 11.0592 | 0 | 0FEH | ### 串行口控制寄存器 SCON **Serial Control Register** 98H | 9FH | 9EH | 9DH | 9CH | 9BH | 9AH | 99H | 98H | | ------ | ------ | ------ | ------ | -------------- | ---------------- | ------ | ------ | | SM0 | SM1 | SM2 | REN | TB8 | RB8 | TI | RI | | 工作方式控制 | 工作方式控制 | 多机通信控制 | 串口接收允许 | 存放**发送数据**的第9位 | 用于存放**接收数据**的第9位 | 发送中断标志 | 接收中断标志 | ` TI ` **发送中断标志** **Transmit Interrupt Flag** 发送缓冲器SBUF已空(=1) Empty **需要软件清零**做好下一次发送准备 ` RI ` **接收中断标志** **Receive Interrupt Flag** 接收缓冲器SBUF已满(=1) Full **需由软件清零**做好下一次接收准备 硬件自动置 1 ,标识数据发送/接受完成 软件手动置 0,为下一次发送/接受做准备 ` REN ` **串口接收允许控制位** ==1== 允许接收 ==0== 禁止接收 ` SM2 ` **多机通信控制位** 单片机组网 ==1== 允许多机通信 ==0== 单机对单机通信 `SM0 SM1` **工作方式控制位** [[数据选择器\|数据选择器]]编码选择 ==0 0== 方式 0 同步移位寄存器 不作为串口通信 ==0 1== **方式 1** 10 位异步收发 波特率由定时器控制 ==1 0== 方式 2 11位异步收发 fosc/32 fosc/64 波特率固定,无需定时器 ==1 1== 方式 3 11 位异步收发 波特率由定时器控制 ### 电源控制寄存器 PCON **Power Control Register** 87H 串行通信**只使用最高位** `SMOD` - ==1== 波特率**加倍** - ==0== 波特率**不变** ### 串行通信工作方式 1 [[内部定时计数器\|内部定时计数器]] 定时器 1 模式 2 产生串行通信的时钟控制脉冲 自动重装载 `TMOD` 0010 0000 ### 程序设计 #### 基本的工作原理 **发送数据的过程** 1. 内部数据并行写入 `SBUF` 2. 数据串行移位送出 3. 中断标志位 `TI` 硬件置 1 4. CPU 响应中断 5. `TI` 软件清零,写入下一数据 **接收数据的过程** 1. 外界数据串行送入移位寄存器 2. 数据并行送入 `SBUF` 3. 标志位 `RI` 硬件置 1 4. CPU 响应中断 5. `RI` 软件清零,读入下一数据 串行通信的时钟控制脉冲 通过[[内部定时计数器\|定时器1模式2]] 方式产生 ```C TMOD=0x20; //定时器1 模式2工作方式 TL1=0xF4; //设置串行波特率 2400BPS TH1=0xF4; //自动重装载 PCON=0x00; //无倍数 2^0 SCON=0x50; //0101 0000 串行通信方式1 TR1=1; //启动定时器1 ``` 两个单片机采用点对点通讯; 单片机工作晶振频率为 11.0592MHz, 串行通信波特率为 2400b/s 。 发送机发送数字 0-9; 接收机接收到数据后将数据回传给发送机,并将接收数据在本机 P1 口显示; 发送机将接收到数据与已经发送数据比较,如果两个数据相等,则确认接收数据正确,并将发送数据通过 P1 口显示; 如果比较后确认数据不等,则在 P1 口显示数字 E ```C //发送程序 #include<reg51.h> unsigned char m=0,k=0; unsigned char dat[10]={0,1,2,3,4,5,6,7,8,9}; void main(void) { TMOD=0x20; //定时器1 模式2工作方式 TL1=0xF4; //设置串行波特率 2400BPS TH1=0xF4; //自动重装载 PCON=0x00; //无倍数 2^0 SCON=0x50; //0101 0000 串行通信方式1,10位异步收发 TR1=1; //启动定时器1 while(1) { SBUF=dat[m]; do{} while(!TI); TI=0; do{} while(!RI); RI=0; k=SBUF; if(k==dat[m]) { P1=dat[m]; m++; if(m==10) m=0; } else P1=0x0e; } } ``` ```C //接收程序 #include<reg51.h> unsigned char m=0,k=0; void main(void) { TMOD=0x20; TL1=0xF4; TH1=0xF4; SCON=0x50; PCON=0x00; TR1=1; while(1) { do{} while(!RI); RI=0; k=SBUF; P1=k; SBUF=k; do{} while(!TI); TI=0; } } ``` ### 校正位 [[特殊功能寄存器\|特殊功能寄存器]] ```C //接收程序的部分代码 sbit p=PSW^0; //设置位 tmp=SBUF; // ACC=tmp; //将数给ACC,就会自动产生奇偶标志位 if(p==RB8) //RB8 存放接收数据的第 9 位 { } ```