C51中断、定时器、串口常用特殊寄存器使用以及初始化
1.中断系统系统结构如下:
中断初始化:
void main()
{
IE = 0x81; //假设只用外部中断0,这里就可以让IE为0x81;如果全开的话,可以让IE为0x9f;
IT0 = 1; //这里让IT0 = 1意思是设置其中断触发方式为跳沿触发
}
void zhong_duan_name() interrupt 0 //后面的interrupt n 是一定要写的 n为开启的中断的默认优先级
{
...
}
2.特殊寄存器:
(1)控制中断开启禁止的sfr:
IE D7 D6 D5 D4 D3 D2 D1 D0 //字节地址为A8H
EA - - ES ET1 EX1 ET0 EX0
EA:中断总开关
后边的依次为串口、定时器/计数器1、外部中断1、定时器/计数器0、外部中断0
每一位为1的时候表示中断开启;
使用的话在芯片上有P3口的复用可以查看
(2)中断优先级控制
IP D7 D6 D5 D4 D3 D2 D1 D0 //字节地址为B8H,因为8可以被8整除,所以可以位寻址,即可以直接定义PT0 = 1这种
- - - PS PT1 PX1 PT0 PX0
从PS往后依次为:串口、定时器/计数器1、外部中断1、定时器/计数器0、外部中断0
为1表示优先级高,0表示低;
如果有多个为1,且同时相应,则根据默认优先级来判断:
中断源 优先级 入口地址
外部中断0 0 0003H
定时器/计数器0 1 000bH
外部中断1 2 0013H
定时器/计数器1 3 001bH
串口中断 4 0023H
(3)定时器/计数器状态sfr
TCON D7 D6 D5 D4 D3 D2 D1 D0 //字节地址为88H
TF1 TR1 TF0 TR0 IE1 IT1 IE0 IT0
TF1、TF0:定时器计数器溢出标志位(定时器计数器溢出时置1,需要由软件清零;但作为中断请求位时,进入中断服务程序后硬件自动清零)
TR1、TR0:定时器计数器开启和禁止位
IE1、IE0:外部中断请求标志位
IT1、IT0:外部中断触发方式
(4)定时器/计数器状态sfr
TMOD D7 D6 D5 D4 D3 D2 D1 D0 //字节地址为89H
GATE C/T* M1 M0 GATE C/T* M1 M0 //前面四个为T1 后面四个为T0
定时器方式一举例
假设系统时钟频率采用6MHz,要在P1.0上输出一个周期为2ms的方波。
#include<reg51.h>
sbit P1_0 = P1^0; //引脚定义
void main()
{
IE = 0x82;//开启定时器/计数器中断0
TMOD = 0x01;//GATE = 0 仅由TR0来控制是否计时开始,采用方式1(16位)
TH0 = (65536-500)/256;
TL0 = (65536-500)%256;
TR0 = 1; //定时开始
while(1);
}
void qufan() interrupt 1
{
//因为使用的时中断方式,所以不需要软件继续TF的清零
TH0 = (65536-500)/256;
TL0 = (65536-500)%256;//重新赋初值
P1_0 = ~P1_0;
}
(5)串口控制sfr
SCON D7 D6 D5 D4 D3 D2 D1 D0 //字节地址为98H
SM0 SM1 SM2 REN TB8 RB8 TI RI
SM0、SM1为方式选择位。
SM2为允许方式2和方式3的多机通信控制位
REN:数据接收允许(1)还是不允许(0)
TB8:发送数据位8, RB8:接收数据位8(方式1时接收到的停止位,方式0时不使用RB8)
TI、RI:串口发送和接收中断请求标志位,发送或接收一帧数据后硬件自动置1,需要在中断服务程序中用软件清零)
串口初始化
void main()
{
IE = 0x9
SCON = 0X50;//工作在方式一,允许接收数据(双工通信)
TMOD = 20; //设置工作在定时器T1,方式二(可以自动重载的8位寄存器)
PCON = PCON | 0X80; //设置SMOD为1
TH1 = 0xfa;
TL1 = 0xfa; //初值用来设置波特率的(这里时4800 b/s),波特率就是每秒传送的数据位数
TR1 = 1; //开启计时
while(1);
}
void TR_Byte() interrupt 3
{
if (TI == 1) //CPU发送数据
{
TI = 0; //定时器溢出标志位必须在中断服务程序中由软件清零
P0 = 0xff; //P0作I/O时为准双向口
SBUFF = P0;
}
if (RI == 1) //CPU接收数据
{
RI = 0;
P0 = SBUFF;
}
}