什么是串口通信?
串口通信又叫串行通信,是相对于并行通信来的,并行通信是将数据的位在不同的数据线上进行同时传输,如下图:
优点: 控制简单, 传输速度快;
缺点: 传输线较多,长距离传输时,成本高,并且各位同时接收困难(可能会受到干扰或每个线的导电不一样导致到达的时间不一致)
串行通信是将数据字节分成一位一位的形式在一条传输线上逐个传输,如下图:
优点:传输线少,长距离传输时成本低,并且可以利用现成的电话线网络设备;
缺点: 数据传输控制比并行复杂,速度比并行低;
所以计算机内部用并行线比较多,而计算机外部,由于传输线的长度不确定,可能会很长,用串行比较多,如USB,可能20厘米,也可能2米或更长,而且如果用并行线做USB会粗很多,硬件成本也会上升很多。
串行通信的传输方式
- 单工是指数据传输仅能沿一个方向,不能实现反向传输。
- 半双工是指数据传输可以沿两个方向,但需要分时进行。
- 全双工是指数据可以同时进行双向传输。
传输速率
比特率是每秒钟传输二进制代码的位数,单位是:位/秒(bps)。如每秒钟传送240个字符,而每个字符格式包含10位(1个起始位、1个停止位、8个数据位),这时的比特率为:
10位×240个/秒 = 2400 bps
波特率计算
在串行通信中,收发双方对发送或接收数据的速率要有约定。通过软件可对单片机串行口编程为四种工作方式,其中方式0和方式2的波特率是固定的,而方式1和方式3的波特率是可变的,由定时器T1的溢出率来决定。
串行口的四种工作方式对应三种波特率。由于输入的移位时钟的来源不同,所以,各种方式的波特率计算公式也不相同。
(fosc是51单片机的频率,如12MHz,11.0592MHz等,计算时要把M转换为1000000)
方式0的波特率 = fosc/12
方式2的波特率 =(2SMOD/64)· fosc
方式1的波特率 =(2SMOD/32)·(T1溢出率)(8bit数据位)
方式3的波特率 =(2SMOD/32)·(T1溢出率))
SMOD是倍频标记,值为0或1;如果为0则20=1;如果为1,则21=2;
如果频率为12MHz,则方式0的波特率固定为1Mbps,方式1的波特率固定为固定为375000或187500; 方式1为10位收发器(1位起始位,8位数据位,1位停止位);方式3位11位收发器(1位起始位,8位数据位,1位停止位)。
当T1作为波特率发生器时,最典型的用法是使T1工作在自动再装入的8位定时器方式(即方式2,且TCON的TR1=1,以启动定时器)。这时溢出率取决于TH1中的计数值。
T1 溢出率 = fosc /{12×[256 -(TH1)]}
在单片机的应用中,常用的晶振频率为:12MHz和11.0592MHz。所以,选用的波特率也相对固定。常用的串行口波特率以及各参数的关系如表所示。
串口如何使用?
串行口工作之前,应对其进行初始化,主要是设置产生波特率的定时器1、串行口控制和中断控制。具体步骤如下:
- 确定T1的工作方式(编程TMOD寄存器);
- 计算T1的初值,装载TH1、TL1;
- 启动T1(编程TCON中的TR1位);
- 确定串行口控制(编程SCON寄存器);
- 串行口在中断方式工作时,要进行中断设置(编程IE、IP寄存器)。
下面写一个最简单的串口使用程序,通过串口和计算机进行通信,把从计算机受到的值返回给计算机,代码如下:
#include<reg52.h>
typedef unsigned char u8;
void UsartInit()
{
TMOD=0x20; //设置工作模式1
TH1=0xFD; //设置波特率为9600
TL1=0xFD; //当TH1到0后,用TL1的值重新初始化
PCON=0x80;
TR1=1; //启动定时器1
SCON=0x50;// 设置为模式1
ES=1; //使能串口中断
EA=1; //使能中断总开关
}
void Usart() interrupt 4 //串口中断函数,终端号为4
{
u8 temp;
temp=SBUF; //从串口读一个字节
RI=0; //串口接收标记,软件置为0,这样下次收到数据时变为1,进入该中断
SBUF=temp; //往串口写数据,虽然和上面都是SBUF,但是他们是物理上的两个SBUF,一个读,一个写
while(!TI); //TI为串口发送标记,当发送完数据后,变为1,while循环等待TI发送结束
TI=0; //软件置0,否则会立刻进入该中断函数。
}
void main()
{
UsartInit();
while(1);
}