51单片机学习笔记——串口通信

一、通信传输方式

并行通信与串行通信

通信传输方式可分成串行通信和并行通信:

  • 并行通常将数据字节的各位用多条数据线传送。并行通信控制简单,传输速度快;但对传输线路要求高,成本较高,且接收方同时接收存在困难,抗干扰能力差。适合近距离、大量、快速的信息交换。
  • 串行通信将数据字节分成一位一位的形式在一条传输线上逐个传送。传输线少,长距离成本低,可利用电话网等现成设备,但数据的传送控制比并行通信复杂,且传送效率低。适合长距离,低速率的通信。

同步通信与异步通信

串行通信可以分为同步通信与异步通信:

  • 异步通信是以字符(构成的帧)为单位进行传输,字符与字符之间的间隔是任意的,但是字符之间的位间隔必须固定时间传送。异步通信不要求收发双方时钟严格一致,实现容易,设备开销较小,但每个字符要附加2-3位起止位,各帧之间有间隔,传输效率不高。
  • 同步通信在通信时要建立发送方时钟对接收方时钟的直接控制,使得双方达到完全同步。此时传输数据的位之间的距离均为位间隔的整数倍,分为外同步和自同步。可以实现点对多点通信,传送效率很高,但实现的软硬件成本较高。

串行通信传输方向

  • 单工数据传输仅能沿一个方向,不能实现反向传输。如:电视,广播
  • 半双工是指数据传输可以沿两个方向,但要分时进行。如:对讲机
  • 全双工是指数据可以同时进行双向传输。如:电话

串行通信的校验

  • 奇偶校验
    数据尾随的一位为奇偶校验位,被传输数据中1的个数是奇数或偶数进行校验,采用奇数为奇校验,反之为偶校验。若1的个数不一致,则数据传输过程中出现了差错。
  • 代码和校验
    发送方把所发数据块求和(或各字节异或),产生一个字节校验字符,附加到数据块末尾,由接收方校验。
  • 循环冗余校验
    通过某种数学运算实现有效信息与校验位之间的循环校验,广泛用于同步通信中。哈希函数的一种。

二、电平转换与波特率

  • 电平标准
    TTL电平:+5V等价于逻辑“1”,0V等价于逻辑“0”。但电平是个电压范围,因此规定标准的TTL输出高电平>2.4V,输出低电平<0.4V;输入高电平>=2.0V,输入低电平<=0.8V。
    CMOS电平:同样采用+5V等价于逻辑“1”,0V等价于逻辑“0”。输出高电平>=4.45V,输出低电平<=0.5V;输入高电平>=3.5V,输入低电平<=1.5V。
    同时还有3.3V等低压的LVTTL,LVCMOS电平。
    RS-232C电平:-15V ~ -3V等价于逻辑“1”,+3V ~ +15V等价于逻辑“0”。

  • 电平转换
    由于单片机串口采用TTL电平标准,计算机USB接口或RS-232C接口采用RS-232C电平标准,二者在通信时需要进行电平转换。有MAX232,CH340等转接芯片。

  • 波特率
    比特率为每秒中传输二进制代码的位,单位:位/秒(bps)。严格上讲波特率与比特率不是一种物理量,不过在串口通信中,二者恰好相等且都可以表示数据的传输速率。波特率与传送距离成反比。在串口通信中,发送方和接收方的必须波特率相同才能正确的传输数据。
    如果想深究波特率和比特率,可以看看这篇博客,解释的很清晰。

三、51单片机的串口通信

概况

51单片机的串行口是全双工类型的,一般RXD引脚为P3.0,TXD引脚为P3.1。RXD为Receive Data,TXD为Transmit Data。

1、寄存器

控制寄存器SCON
  • SCON寄存器各位定义如下:
位序号 D7 D6 D5 D4 D3 D2 D1 D0
位符号 SM0 SM1 SM2 REN TB8 RB8 TI RI
  • 其中,SM0,SM1控制串行口的工作方式:
SM0 SM1 方式 功能 波特率
0 0 0 同步移位寄存器方式(通常用于扩展I/O口) fosc/12
0 1 1 10位异步收发(8位数据),波特率可变 2SMOD/32×T1溢出率
1 0 2 11位异步收发(9位数据),波特率固定 2SMOD/64×fosc
1 1 3 11位异步收发(9位数据),波特率可变 2SMOD/32×T1溢出率

上表中,fosc为系统晶振频率,SMOD为电源管理寄存器PCON中的一位,用于控制串口通信方式1,2,3的波特率。SMOD=0时,波特率正常,SMOD=1时,波特率加倍。PCON寄存器中仅有SMOD与串口通信有关。T1溢出率为定时器T1溢出的频率,定时器T1溢出一次的时间T的倒数1/T即溢出率。

位符号 解释 功能
SM2 多机通信控制位 主要应用与方式2和3.SM2=1,检测RB8的值决定是否接受数据,SM2=0,无论是什么数据都接收
REN 允许串行接收位 REN=1,允许串行口接收数据;REN=0,禁止串行口接收数据
TB8 方式2,3中的发送数据的第9位 方式2,3中可用作校验位,多机通信时可作为地址帧/数据帧的标志位
RB8 方式2,3中的接收数据的第9位 可作为校验位或地址帧/数据帧标志位,在方式1时,若SM2=0,则RB8接收到的是停止位
TI 发送中断标志位 在方式0中,当串行发送第8位结束时,或其他方式串行发送停止位开始时,硬件使TI置1,向CPU发出中断申请
RI 接收中断标志位 在方式0中,当串行发送第8位结束时,或其他方式串行接收停止位中间时,硬件使TI置1,向CPU发出中断申请
数据缓冲寄存器SBUF

SBUF是串行口中的两个缓冲寄存器,一个是发送寄存器,一个是接收寄存器,在物理结构上是完全独立的,但地址是重叠的。它们都是字节寻址的寄存器,字节地址均为99H。

2、方式1时序图

方式1是最常用的串口通信方式。

  • 输入时序图

51单片机学习笔记——串口通信_第1张图片

  • 输出时序图
    51单片机学习笔记——串口通信_第2张图片
  • 方式1的串口通信初始化步骤
步骤 解释
1 确定定时器T1的工作方式(编程TMOD寄存器)
2 计算定时器T1的初值,装载TH1,TL1
3 启动定时器T1(编程TCON中的TR1位)
4 确定串口的工作方式(编程SCON寄存器)
5 在进入串口中断后,要进行中断设置(编程IE,IP寄存器)

注:TMOD寄存器,IE寄存器,IP寄存器的具体操作在之前中断的笔记中有记录。

3、例程:计算机与单片机的串口通信

#include "reg52.h"	
typedef unsigned int u16;	  
typedef unsigned char u8;

/*串口初始化函数*/
void UsartInit()
{
	TMOD=0X20;			//设置定时器工作方式2
	TH1=0XF4;			//定时器初始值设置
	TL1=0XF4;			//晶振11.0592,波特率初值设置为2400
	PCON=0X80;			//直接操作PCON寄存器,使得SMOD=1,波特率加倍.为4800
	TR1=1;				//打开计数器
	SCON=0X50;			//设置为工作方式1
	ES=1;				//打开接收中断
	EA=1;				//打开总中断
}

void main()
{	
	UsartInit();  		//串口初始化
	while(1);		
}

void Usart() interrupt 4
{
	u8 receiveData;		
	receiveData=SBUF;	//储存接收到的数据
	RI = 0;				//清除接收中断标志位
	SBUF=receiveData;	//将接收到的数据放入到发送寄存器
	while(!TI);			//等待发送数据完成
	TI=0;				//清除发送完成标志位
}

4、例程:printf实现串口输出

先看一下stdio.h中putchar的部分源码,putchar函数的功能是将参数写入输出流,51单片机的输出流为寄存器SBUF。

char putchar (char c){
	if (c == '\n')
	{			
		if (RI)
		{
			if (SBUF == XOFF)
			{
				do
				{
					RI = 0;
					while (!RI);
				}
				while (SBUF != XON);
				RI = 0; 
			}
		}
		while (!TI);			//必须先将TI置1,否则会在这里死循环
		TI = 0;
		SBUF = 0x0d;           //打印回车
	}
	if (RI)
	{
		if (SBUF == XOFF)
		{
			do
			{
				RI = 0;
				while (!RI);
			}
			while (SBUF != XON);
			RI = 0; 
		}
	}
	while (!TI);			//必须先将TI置1,否则会在这里死循环
	TI = 0;
	return (SBUF = c);
}

可以看到,在putchar函数中,通过while(!TI)来检测中断标志,所以在使用putchar函数之前,要将TI置1。而printf(),puts()等函数都是调用putchar实现的,所以调用之前也要使TI=1。而在写入SBUF后,TI会硬件置1,因此不必再反复操作TI。
下面是使用printf输出Hello world!的例程:

#include "reg52.h"	
#include 
typedef unsigned int u16;	  
typedef unsigned char u8;


void UsartInit()		//串口初始化函数 
{
	TMOD=0X20;			//设置定时器工作方式2
	TH1=0XF4;			//定时器初始值设置
	TL1=0XF4;			//晶振11.0592,波特率初值设置为2400
	PCON=0X80;			//直接操作PCON寄存器,使得SMOD=1,波特率加倍.为4800
	TR1=1;				//打开计数器
	SCON=0X50;			//设置为工作方式1
	ES=1;				//打开接收中断
	TI=1;				//必须设置中断标记位
	EA=1;				//打开总中断
}

void delay(u16 ms)		//延时函数
{
	u16 i,j;
	for(i=ms;i>0;i--)
		for(j=110;j>0;j--);
}


void main()
{	
	UsartInit();  	//串口初始化
	while(1)
	{
		delay(500);
		printf("Hello world!\n");
	}
}

四、串行通信接口标准

单片机与单片机之间也可以通过串行通信进行数据传输。
前面的电平转换部分简要介绍了集中串口通信标准中的电平标准,但实际上还规定了引脚信号等其他内容。

  • TTL通信
    采用TTL电平通信,只需将单片机A的TXD端与单片机B的RXD端相连;单片机A的RXD端与单片机B的TXD端相连即可。
  • RS-232通信
    RS-232通信标准是美国工业电子协会制定的通信标准。曾经采用25针接口(左)通信,后简化为9针的接口(右)。
    51单片机学习笔记——串口通信_第3张图片
    是不是感觉和显卡的VGA接口有点像?但VGA接口有15针。二者并不是一个东西。
    51单片机学习笔记——串口通信_第4张图片
    上图中左为RS-232C(母),右为VGA(母)。
    采用RS-232C标准传输,传输距离远,但传输速率低,有电平偏移,抗干扰能力差。
  • RS-422通信
    与RS-232不同的是,采用了差分传输方式,有较高的抗干扰性能,而且提高了通信速率和传输距离。与RS-232采用了相同的9针接口,但引脚意义不同。
  • RS-485通信
    RS-485同样采用差分传输方式,与RS-422不同的是,能支持多个分节点进行信息传输。可以实现多机通信。

五、单片机多机通信

  • 主从式结构

单片机构成的多机通信系统中常采用总线型主从式结构。所谓主从式,就是在多个单片机组成的系统中,只能有一个主机,其他的都是从机,从机要服从主机的控制,这就是总线型主从式结构。
51单片机学习笔记——串口通信_第5张图片

  • 从机状态字
位序号 D7 D6 D5 D4 D3 D2 D1 D0
位符号 ERR TRDY RRDY

主机与其他从机通信时,在总线上发送数据和地址联络信号,从机确定地址后才能接收数据。确认地址后通过更改从机状态字来控制从机的数据传输。
若ERR=1,从机接收到非法命令。
若TRDY=1,从机发送准备就绪。
若RRDY=1,从机接收准备就绪。

在51单片机中,多机串口通信采用方式2或方式3。

你可能感兴趣的:(51单片机学习笔记——串口通信)