一、串口的原理
SM0、SM1——串行口工作模式
SM0 | SM1 | 模式 | 特点 |
0 | 0 | 模式0 | 移位寄存器方式,用于I/O口扩展 |
0 | 1 | 模式1 | 8位UART,波特率可变 |
1 | 0 | 模式2 | 9位UART,波特率为时钟频率/32或/64 |
1 | 1 | 模式3 | 9位UART,波特率可变 |
TI、RI——发送、接收中断标志位
TI | TI=0 允许发送=>TI=1 发送完成后硬件自动置1=>TI=0 用软件清0(方式0:当串行发送第8位数据结束) |
RI | RI=0 允许接收=>RI=1 接收完成后硬件自动置1=>RI=0 用软件清0(方式0:当串行接收第8位数据结束) |
电源控制寄存器PCON
PCON | D7 | D6 | D5 | D4 | D3 | D2 | D1 | D0 |
87H | SMOD |
常用的波特率初值表
当SMOD位为1,则波特率加倍。
二、串口中断的实现
1、仿真
2、运行时,没有终端窗口弹出,可以根据以下步骤设置
终端跳出
3、波特率
4、将AT89C51的晶振频率改成11.0592MHz
5、代码与仿真结果
#include <reg51.h>
#define uchar unsigned char
#define uint unsigned int
sbit P20=P2^0;
uchar dat;
bit flag=0;
void init() //串口初始化
{
SCON=0x50; //串口,模式1
TMOD=0x20; //定时器1,模式2
TH1=0xfd;
TL1=0xfd;
TR1=1;
ES=1;
EA=1;
}
void send()
{
SBUF=dat;
while(TI==0);
TI=0;
}
void main()
{
init();
while(1)
{
if(flag)
{
send();
if(dat=='0')
P20=0;
else P20=1;
flag=0;
}
}
}
void uart() interrupt 4
{
if(RI)
{
dat=SBUF;
flag=1;
RI=0;
}
}