蓝桥杯串口中断程序设计
一、寄存器信息
1.串行控制寄存器SCON
D7 | D6 | D5 | D4 | D3 | D2 | D1 | D0 |
---|---|---|---|---|---|---|---|
SM0 | SM1 | SM2 | REN | TB8 | RB8 | TI | RI |
SM0与SM1:决定串行口的四种工作方式
SM0 | SM1 | 方式 | 功能说明 |
---|---|---|---|
0 | 0 | 0 | 同步移位寄存器 |
0 | 1 | 1 | 10位异步收发(8位数据),波特率可变(由定时器1溢出率决定) |
1 | 0 | 2 | 11位异步收发(9位数据),波特率固定 |
1 | 1 | 3 | 11位异步收发(波特率可变),由定时器1的溢出率控制 |
SM2:在方式2和3中,若SM2=1且接收到的第九位数据(RB8)为1,才将接收到的前8位数据送入接收SBUF中,并置位RI产生中断请求;否则丢弃前8位数据。若SM2=0,则不论第九位数据(RB8)为1还是为0,都将前8位送入接收SBUF中,并产生中断请求。
REN:允许接收位,REN置0 禁止接收数据:REN置1 允许接收数据
TB8:在方式2和方式3中,是被发送的第9位数据,可根据需要由软件置1或清零,也可以作为奇偶校验位,在方式1中是停止位。
RB8:在方式2和方式3中,是被接收的第9位数据(来自第TB8位);在方式1中,RB8收到的是停止位,在方式0中不用。
TI:串行口发送中断请求标志位:,当发送完一帧串行数据后,由硬件置1;在转向中断服务程序后,用软件清0。
RI:串行口接收中断请求标志位: 当接收完一帧串行数据后,由硬件置1;在转向中断服务程序后,用软件清0。
2.电源管理寄存器PCON
考虑第一位SMOD就行,该位置1时波特率加倍,置0时波特率正常
3.定时/计数器工作模式寄存器TMOD
B7 | B6 | B5 | B4 | B3 | B2 | B1 | B0 |
---|---|---|---|---|---|---|---|
GATE | C/T’ | M1 | M0 | GATE | C/T’ | M1 | M0 |
高四位设置定时器1;低四位设置定时器0
GATA:置0时 定时/计数器工作;置1时 需要在INT0(P32)为高电平条件下才工作
C/T’:置0时 定时模式;置1时计数模式
M1和M0:工作方式控制位,共四种工作方式
M1 | M0 | 工作模式 |
---|---|---|
0 | 0 | 16位自动重新加载模式 |
0 | 1 | 16位不可重新加载模式,溢出时需软件重新写入TH1,TL1初值 |
1 | 0 | 八位自动重新加载模式 |
1 | 1 | ,,, |
二、波特率计算
不同定时器模式对应的波特率
方式0的波特率 = fosc/12
方式2的波特率 =(2SMOD/64)· (T1溢出率)
方式1的波特率 =(2SMOD/32)·(T1溢出率)
方式3的波特率 =(2SMOD/32)·(T1溢出率)
T1 溢出率计算公式
T1 溢出率 = fosc /{12×[256 -(TH1)]}
三、STC-ISP的使用
初始化程序可直接由该软件生成(注意串口1的中断号是4)
四、程序例程
向PC机发送数据
void main()
{
UartInit();
EA=1;
ES=1;
while(1)
{
if(s4==0) //加个软件延时最好
{
SBUF=dat; //送数据出去要放到缓冲区里
while(!TI); //如果T1值1说明有数据要送,就一直等数据发完就可以退出循环
TI=0;
}
}
}
void UartInit(void) //9600bps@11.0592MHz
{
SCON = 0x50; //8位数据,可变波特率
AUXR |= 0x01; //串口1选择定时器2为波特率发生器
AUXR |= 0x04; //定时器2时钟为Fosc,即1T
T2L = 0xE0; //设定定时初值
T2H = 0xFE; //设定定时初值
AUXR |= 0x10; //启动定时器2
}
PC机向下位机发送数据
void main()
{
UartInit();
EA=1;
ES=1;
while(1)
{
P2=0x80; //译码器输出选择Y4 ,p27,p27,p25控制译码器输出
P0=dat; //用八个led查看结果
}
}
void UartInit(void) //9600bps@11.0592MHz
{
SCON = 0x50; //8位数据,可变波特率
AUXR |= 0x01; //串口1选择定时器2为波特率发生器
AUXR |= 0x04; //定时器2时钟为Fosc,即1T
T2L = 0xE0; //设定定时初值
T2H = 0xFE; //设定定时初值
AUXR |= 0x10; //启动定时器2
}
void uart() interrupt 4
{
if(RI)
{
RI=0;
dat=SBUF;
}
}