1、通信
通信的方式可以分为多种,按照数据传送方式可分为串行通信和并行通信;
按照通信的数据同步方式,可分为异步通信和同步通信;
按照数据的传输方向又可分为单工、半双工和全双工通信
1.1 通信速率
衡量通信性能的一个非常重要的参数就是通信速率,通常以比特率(Bitrate)来表示。比特率是每秒钟传输二进制代码的位数,单位是:位/秒( bps)
如:每秒钟传送 240 个字符,而每个字符格式包含10位(1个起始位、1个停止位、8个数据位),这时的比特率为:10位×240个/秒=2400bps
波特率表示每秒钟传输了多少个码元。而码元是通信信号调制的概念,通信中常用时间间隔相同的符号来表示一个二进制数字,这样的信号称为码元。
如:常见的通信传输中,用0V表示数字0,5V 表示数字1,那么一个码元可以表示两种状态0和1,所以一个码元等于一个二进制比特位,此时波特率的大小与比特率一致;如果在通信传输中,有0V、2V、4V以及6V分别表示二进制数00、01、10、11,那么每个码元可以表示四种状态,即两个二进制比特位,所以码元数是二进制比特位数的一半,这个时候的波特率为比特率的一半
由于很多常见的通信中一个码元都是表示两种状态,所以我们常常直接以波特率来表示比特率
1.2 串口通信简介
串口通信(Serial Communication),是指外设和计算机间通过数据信号线、地线等按位进行传输数据的一种通信方式,属于串行通信方式。串口是一种接口标准,它规定了接口的电气标准,没有规定接口插件电缆以及使用的协议
串口通信中通常使用的是异步串口通信,即没有时钟线,所以两个设备要通信,必须要保持一致的波特率
1.3 串口内部结构
(1)51单片机均有的5个中断来介绍,其内部结构框图如下所示:
RXD和TXD对应的是P3.0和P3.1口的附加功能,RI(SCON.0)或TI(SCON.1),串行口中断请求标志。当串行口接收完一帧串行数据时置位RI或当串行口发送完一帧串行数据时置位TI,向CPU申请中断,中断号为4
(2)串口内部结构图如下所示:
右边的TXD和RXD为单片机IO口,TXD对应的是P3.1管脚,RXD对应的是P3.0管脚
串口内部结构中有TH1和TL1,所以需要定时器T1
2、串口相关寄存器
2.1 串口控制寄存器 SCON
(1)SM0和SM1为工作方式选择位
(2)SM2:多机通信控制位,主要用于方式2和方式3
当SM2=1时可以利用收到的RB8来控制是否激活RI(RB8=0时不激活RI,收到的信息丢弃;RB8=1时收到的数据进入SBUF,并激活RI,进而在中断服务中将数据从SBUF读走)
当SM2=0时,不论收到的RB8为0和1,均可以使收到的数据进入SBUF,并激活RI(即此时RB8不具有控制RI激活的功能)。通过控制SM2,可以实现多机通信。
(3)REN:允许串行接收位。
由软件置REN=1,则启动串行口接收数据;
若软件置REN=0,则禁止接收。
(4)TB8:在方式2或方式3中,是发送数据的第9位,可以用软件规定其作用。可以用作数据的奇偶校验位,或在多机通信中,作为地址帧/数据帧的标志位。 在方式0和方式1中,该位未用到。
(5)RB8:在方式2或方式3中,是接收到数据的第9位,作为奇偶校验位或地址帧/数据帧的标志位。在方式1时,若SM2=0,则RB8是接收到的停止位。
(6)TI:发送中断标志位。在方式0时,当串行发送第8位数据结束时,或在其它方式,串行发送停止位的开始时,由内部硬件使TI置1,向CPU发中断申请。在中断服务程序中,必须用软件将其清0,取消此中断申请。
(7)RI:接收中断标志位。在方式0时,当串行接收第8位数据结束时,或在其它方式,串行接收停止位的中间时,由内部硬件使RI置1,向CPU发中断申请。也必须在中断服务程序中,用软件将其清0,取消此中断申请
2.2 电源控制寄存器 PCON
SMOD:波特率倍增位。在串口方式1、方式2、方式3时,波特率与SMOD有关,当SMOD=1时,波特率提高一倍。复位时,SMOD=0
3、计算波特率
波特率的计算公式:
方式0的波特率=fosc/12
方式1的波特率=((2^SMOD)/32)*(T1溢出率)
方式2的波特率=((2^SMOD)/64)*fosc
方式3的波特率=((2^SMOD)/32)*(T1溢出率)
其中T1溢出率=fosc/{12×[256-(TH1)]}
一般借助51波特率初值计算软件得到一个波特率初值
为什么要计算一个初值?
在串口通信中,通过波特率软件计算出一个初值,通常是为了配置定时器1所需的波特率
这个初值对于确保数据的正确传输至关重要,因为它直接影响到定时器的溢出率,进而决定了串口通信的波特率
初值的作用有:确定波特率、同步数据传输、避免数据丢失或错误
4、串口初始化步骤
①确定T1的工作方式(TMOD寄存器)
②确定串口工作方式(SCON寄存器)
③计算T1的初值(设定波特率),装载TH1、TL1
④启动T1(TCON中的TR1位)
⑤如果使用中断,需开启串口中断控制位(IE寄存器)
eg:设置串口为工作方式1、波特率为9600、波特率加倍、使用中断
void uart_init(u16 baud){ //baud:初值,由波特率计算工具得到
TMOD|=0X20; //定时器1的工作方式为2 定时器
SCON=0x50; //SCON寄存器的工作方式为1 串口
PCON=0x80; //PCON寄存器,波特率加倍 串口
TH1=baud; //定时计数器1的初值配置 定时器
TL1=baud; 定时器
EA=1; //打开总中断开关 串口
ES=1; //打开接收中断 串口
TR1=1; //打开计算器 定时器(寄存器 TCON)
}
在主函数中调用该函数并传入0XFA值即可,如下:
uart_init(0xfa); //定时器1的工作方式为2;晶振频率:11.0592;波特率:9600;SMOD:1
5、软件设计
要实现的功能是:当串口助手发送数据给单片机,单片机原封不动转发给串口助手显示
#include "reg51.h"
typedef unsigned int u16;
typedef unsigned char u8;
//串口初始化
void uart_init(u16 baud){ //baud:初值,由波特率计算工具得到
TMOD|=0X20; //定时器1的工作方式为2
SCON=0x50; //SCON寄存器的工作方式为1
PCON=0x80; //PCON寄存器,波特率加倍
TH1=baud; //定时计数器1的初值配置
TL1=baud;
EA=1; //打开总中断开关
ES=1; //打开接收中断
TR1=1; //打开计算器
}
void main(){
uart_init(0xfa); //定时器1的工作方式为2;晶振频率:11.0592;波特率:9600;SMOD:1
while(1){
}
}
void uart() interrupt 4{
u16 rec_data=0; //接收数据变量
RI=0; //手动置0,清除接收中断的标志位
rec_data=SBUF; //SBUF接收完数据
SBUF=rec_data; //将总线上的数据再写入SBUF
while(!TI); //系统自动置1
TI=0; //手动置0
}
结果如下图所示: