一、串口
1.1串口基本认知
串行接口简称串口,也称串行通信接口或串行通讯接口(通常指COM接口),是采用串行通信式的扩展接口。串行接口(Serial Interface)是指数据一位一位地顺序传送。其特点是通信线路单,只要一对传输线就可以实现双向通信(可以直接利用电话线作为传输线),从而大大降低了本,特别适用于远距离通信,但传送速度较慢
 小结:
 1).是设备间接线通讯的一种方式
 2).数据是一位一位的传输
 3).双向全双工通讯
 4).传输速度相对较慢
1.2串口标准与协议
串行接口常用接口有RS-232、RS-422、RS-485接口
**RS-232**
 由于RS-232其发送电平与接收电平的差仅为2V至3V左右,所以其共模抑制能力差,再加上双绞线上的分布电容,其传送距离最大为约15米,最高速率为20kb/s。RS-232是为点对点(即只用一对收、发设备)通讯而设计的,其驱动器负载为3~7kΩ。所以RS-232适合本地设备之间的通信。
**RS-422**
 典型的RS-422是四线接口。实际上还有一根信号地线,共5根线。其DB9连接器引脚定义。由于接收器采用高输入阻抗和发送驱动器比RS232更强的驱动能力,故允许在相同传输线上连接多个接收节点,最多可接10个节点。即一个主设备(Master),其余为从设备(Salve),从设备之间不能通信,所以RS-422支持点对多的双向通信。
 RS-422的最大传输距离为1219米,最大传输速率为10Mb/s。其平衡双绞线的长度与传输速率成反比,在100kb/s速率以下,才可能达到最大传输距离。只有在很短的距离下才能获得最高速率传输。一般100米长的双绞线上所能获得的最大传输速率仅为1Mb/s。
 RS-422需要一终接电阻,要求其阻值约等于传输电缆的特性阻抗。在短距离传输时可不需终接电阻,即一般在300米以下不需终接电阻。终接电阻接在传输电缆的最远端。
**RS-485**
由于RS-485是从RS-422基础上发展而来的,所以RS-485许多电气规定与RS-422相仿。如都采用平衡传输方式、都需要在传输线上接终接电阻等。RS-485可以采用二线与四线方式,二线制可实现真正的多点双向通信,而采用四线连接时,与RS-422一样只能实现点对多的通信,即只能有一个主(Master)设备,其余为从设备,但它比RS-422有改进, 无论四线还是二线连接方式总线上可多接到32个设备。
 RS-485与RS-422的不同还在于其共模输出电压是不同的,RS-485是-7V至+12V之间,而RS-422在-7V至+7V之间,RS-485接收器最小输入阻抗为12k剑 鳵S-422是4k健; 旧峡梢运礴S-485满足所有RS-422的规范,所以RS-485的驱动器可以用在RS-422网络中应用。
 RS-485与RS-422一样,其最大传输距离约为1219米,最大传输速率为10Mb/s。平衡双绞线的长度与传输速率成反比,在100kb/s速率以下,才可能使用规定最长的电缆长度。只有在很短的距离下才能获得最高速率传输。一般100米长双绞线最大传输速率仅为1Mb/s
 RS-485需要2个终接电阻,其阻值要求等于传输电缆的特性阻抗。在短距离传输时可不需终接电阻,即一般在300米以下不需终接电阻。终接电阻接在传输总线的两端。

1.3接口电平
RS-232电平
 逻辑1的电平为-3~-15V,逻辑0的电平为+3~+15V,注意电平的定义反相了一次
TTL电平
 +5V等价于逻辑“1”,0V等价于逻辑“0”(采用二进制来表示数据时)。
 输出高电平>=2.4V,输出低电平<=0.4V;
 输入高电平>=2.0V,输入低电平<=0.8V
1.4串口通讯接线
**两个芯片之间的通讯**

芯片与计算机串口连接

二、串口配置与基础印象
2.1基础印象
对于输入输出的数据需要先传送到SBUF寄存器中
想要接收数据
char datas= = SBUF;想要发送数据
  
SBUF = datas2.2串口配置与工作模式
2.2.1:串行口相关寄存器

2.2.2:串行口控制器SCON与PCON
串行口控制器SCON:可寻址位
| SFR name | address | b7 | b6 | b5 | b4 | b3 | b2 | b1 | b0 | 
| SCON | 98H | SM0/FE | SM1 | SM2 | REN | TB8 | RB8 | TI | RI | 
SM0与SM1组合之后的工作方式

REN:允许/禁止串行接口接收控制位,由软件控制,即当REN=1时,则为允许接收,可启动RxD,开始接收消息,反之则禁止接收
TI:发送请求中断标志位。当发送的8位数据结束之后,硬件内部自动置位,TI=1,向主机发送中断请求,相应中断之后必须用软件进行复位,即TI=0。
RI:接收请求中断标志位。当接收的8位数据结束之后,硬件内部自动置位,RI=1,向主机发送中断请求,相应中断之后必须用软件进行复位,即RI=0。
串行口控制器PCON:不可寻址位
| SFR name | address | b7 | b6 | b5 | b4 | b3 | b2 | b1 | b0 | 
| PCON | 87H | SMOD | SMOD0 | - | POF | GF1 | GF0 | PD | IDL | 
SMOD:波特率选择。当软件进行置位后,即SMOD = 1,则串行通讯方式1,2,3比特率加倍;当SMOD=0,则各个工作方式的波特率加倍。
2.2.3:串行口中断控制器
中断允许寄存器IE(可寻址位)
| SFR name | address | b7 | b6 | b5 | b4 | b3 | b2 | b1 | b0 | 
| IE | A8H | EA | - | ET2 | ES | ET1 | EX1 | ET0 | EX0 | 
EA:CPU总中断控制,EA=1,CPU开放中断,EA=0,CPU停止中断;在各个中断中,首先有EA控制,然后在由自己中断进行控制
ES:串口中断允许标志,ES =1,允许中断;ES=0,禁止中断

三.串口配置方式
配置串口要求:晶振频率11.0592Mhz,波特率为9600,选择串口UART1,工作方式配置为1,允许串行接收控制,允许接收与发送中断标志位
SCON位 :0 1 0 1 0 0 1 1
PCON位: 0 1 0 1 0 0 0 0
由波特率计算出定时器初始值:设定时器的初始值为“X”
解出X = 3,定时器溢出率=10#253=16#FD
代码实现
void UartInit(void)		//9600bps@11.0592MHz
{
	PCON &= 0x7F;		//波特率不倍速
	SCON = 0x50;		//8位数据,可变波特率
	AUXR &= 0xBF;		//定时器1时钟为Fosc/12,即12T
	AUXR &= 0xFE;		//串口1选择定时器1为波特率发生器
	TMOD &= 0x0F;		//清除定时器1模式位
	TMOD |= 0x20;		//设定定时器1为8位自动重装方式
	TL1 = 0xFD;		//设定定时初值
	TH1 = 0xFD;		//设定定时器重装值
	ET1 = 0;		//禁止定时器1中断
	TR1 = 1;		//启动定时器1
}
四.程序练习
1.通过串口向电脑每次间隔一秒发送一个字符“A”
#include <reg52.h>
#include "intrins.h"
sfr AUXR = 0x8E;
/*配置C51串口的通信方式*/
void UartInit(void)		//9600bps@11.0592MHz
{
	AUXR = 0x01;
	SCON = 0x40; //配置串口工作方式1,REN不使能接收
	TMOD &= 0xF0;
	TMOD |= 0x20;//定时器1工作方式位8位自动重装
	
	TH1 = 0xFD;
	TL1 = 0xFD;//9600波特率的初值
	TR1 = 1;//启动定时器
}
void Delay1000ms()		//@11.0592MHz
{
	unsigned char i, j, k;
	_nop_();
	i = 8;
	j = 1;
	k = 243;
	do
	{
		do
		{
			while (--k);
		} while (--j);
	} while (--i);
}
void main()
{
	char data_msg = 'a';  //data_msg为内部数据参数,并给定数据字符“a“
	UartInit();
	while(1)
		{
		Delay1000ms();
		//往发送缓冲区写入数据,就完成数据的发送
		SBUF = data_msg;
	  }
}
2.通过串口向电脑每次间隔一秒发送字符
#include <REGX52.H>
#include "intrins.h"
/*配置C51串口的通信方式*/
void UartInit()		//9600bps@11.0592MHz
{
	AUXR = 0x01;
	SCON = 0x40; //配置串口工作方式1,REN不使能接收
	TMOD &= 0xF0;
	TMOD |= 0x20;//定时器1工作方式位8位自动重装
	
	TH1 = 0xFD;
	TL1 = 0xFD;//9600波特率的初值
	TR1 = 1;//启动定时器
}
void Delay1000ms()		//@11.0592MHz
{
	unsigned char i, j, k;
	_nop_();
	i = 8;
	j = 1;
	k = 243;
	do
	{
		do
		{
			while (--k);
		} while (--j);
	} while (--i);
}
/*由于SBUF是8位为一组,因此需要建立一个字节发送函数,以发送相应的字节
形式参数:datas,用于承接发送的实际内容*/
void sendbyte(char datas)
{
	SBUF  = datas;
	while(TI == 0);  //当发送数据的时候,TI=0,这时while循环满足,不执行下面的程序,当TI=1时,while循环不满足,执行下面的程序:复位TI
	TI = 0;
}
/*发送字符串函数
形式参数:char型字符*/
void sendstring(char* str)
{
	sendbyte(*str);
	while(*str !='\0')
	{
		sendbyte(*str);
		str++;
	}		//当字符串没有结尾的时候,则要调用sendbyte函数,进行函数的发送
}
void main()
{
	UartInit();
	while(1)
	{
		Delay1000ms();
		sendstring("youare handsome\r\n")  //向sendstring形式参数中传输实际参数
	}
}









