1.什么是串口
2.波特率
3.51单片机的串口
4.串口的应用
1:什么是串口
数据的传输有并口传输和串口传输.
并行传输:一次传输8位数据,传输数据快,但浪费io口资源.
串行传输:一位一位传输节省传输线,串行通信适合于远距离传送
串口通信协议:
串口通信协议是指规定了数据包的内容,内容包含了起始位、主体数据、校验位及停止位,双方需要约定一致的数据包格式才能正常收发数据的有关规范。在串口通信中,常用的协议包括RS-232、RS-422和RS-485
- 串行通信有SPI、IIC、UART等多种
- 串行通信的制式有:单工、半双工、全双工三种
- 计算机的串行通信接口是RS-232的标准接口,而单片机的UART接口则是TTL电平,两者的电气规范不一致,所以要完成两者之间的数据通信,就需要借助接口芯片在两者之间进行电平转换,常用的有MAX232芯片
单工,半双工,全双工:
如图:分别是单工,半双工,全双工.
UART串口协议:
串行通信可以分为:异步传送和同步传送
通用异步收发器(Universal Asynchronous Receiver/Transmitter),通常称作UART,是一种串行、异步、全双工的通信协议,在嵌入式领域应用的非常广泛
UART作为异步串行通信协议的一种,工作原理是将传输数据的每个二进制位一位接一位地传输。在UART通信协议中信号线上的状态为高电平时代表‘1’,信号线上的状态为低电平时代表‘0’。比如使用UART通信协议进行一个字节数据的传输时就是在信号线上产生八个高低电平的组合。
2.波特率
串口通信的数据传送速率称为波特率(Baud rate),是指每秒钟传送二进制数码的位数,单位是bps(bit per second),即位/秒
3.51单片机的串口
与51单片机串行相关的SFR特殊寄存器:
- SBUF 寄存器:它是两个在物理上独立的接收、发送缓冲器,可同时发送、接收数据,可通过指令对SBUF 的读写来区别是对接收缓冲器的操作还是对发送缓冲器的操作。从而控制外部两条独立的收发信号线RXD、TXD,同时发送、接收数据,实现全双工
- SCON:用以设定串行口工作方式,接收/发送控制及设置状态标志的特殊功能寄存器
设置串行口的波特率:
例如要设置9600的波特率方式1中:
利用上面公式能算出TH1要=0xFD.
在串口通信的程序设计中,主要有串口初始化和数据收发两个部分。
在初始化函数中,基本步骤如下:
<1> 设置定时器1的工作模式,也就是对TMOD寄存器赋值。
<2> 计算波特率参数,并赋值给TH1和TL1寄存器。
<3> 打开定时器1。
如果使用的是STC 12系统单片机,则要设置AUXR寄存器。
<4> 设置SCON寄存器。
<5> 使能串口中断ES。
<6> 使能总中断EA。
数据的发送通常采用查询方式,而数据的接收则采用中断方式
从图中可得知,当发一个数据给SBUF时RI会置1跳到串口中断,需要在软件中清0.也就是SBUF得到一个接受的指令相当于一个变量 dat,我将这个变量赋值给SBUF:dat=SBUF这就是数据的接收, SBUF中的数据是dat传送的SBUF接收了dat的数据,
相反而言当把SBUF的值送出去TI就会置1会去串口中断,需要软件清0,想当SBUF=dat;把SBUF发送出去,也就是SBUF在前面就是发送在后面就是接收.发送和接收都会跳转到串口中断.
在单片机串口中用定时器1的工作2模式8位定时重装的功能来产生波特率,且在IE寄存器中有控制串口中断的ES.
不管需要写什么程序,串口的初始化都是差不多的.
void InitUART(void)
{
TMOD = 0x20;
SCON = 0x50;
TH1 = 0xFD;
TL1 = TH1;
PCON = 0x00;
EA = 1;
ES = 1;
TR1 = 1;
}
void main(void)
{
InitUART();
}
void UARTInterrupt(void) interrupt 4
{
if(RI)
{
RI = 0;
//add your code here!
}
else
TI = 0;
}
void SendOneByte(unsigned char c)
{
SBUF = c;
while(!TI);
TI = 0;
}
下面我们利用上位机发送数据来控制LED的亮灭
#include<reg52.h>
#define uchar unsigned char
#define uint unsigned int
uchar a;
void init()
{
P2=(P2&0x1f)|0xa0;
P0=0x00;
}
void inituart()
{
TMOD=0x20;
SCON=0x50;
TH1=0xFD; //波特率9600
TL1=0xFD;
ES=1;
EA=1;
TR1=1;
}
void sendbyte(uchar dat)
{
SBUF=dat;
while(TI==0);
TI=0;
}
void serviceuart() interrupt 4
{
P2=(P2&0x1f)|0x80;
if(RI==1)
{
P0=SBUF;
RI=0;
a=SBUF;
sendbyte(a);
}
}
void main()
{
init();
inituart();
sendbyte(0X55);
sendbyte(0X66);
while(1);
}