80C51中断系统
结构
80C51有5个中断源(89C52有6个),2个优先级,可实现二级中断嵌套
TCON中断标志
IT0(TCON.0),外部中断0触发方式控制位
IE0(TCON.1),外部中断0中断请求标志位
IT1(TCON.2),外部中断1触发方式控制位
IE1(TCON.3),外部中断1中断请求标志位
TF0(TCON.5),定时/计数器T0溢出中断请求标志位
TF1(TCON.7),定时/计数器T1溢出中断请求标志位
中断源响应优先级
中断响应条件
- 中断源有中断请求
- 此中断源的中断允许位置1
- CPU开中断(即EA = 1)
定时/计数器的结构
定时/计数器的实质是加1计数器(16位),有由高8位和低8位两个寄存器组成,TMOD是定时/计数器的工作方式及寄存器,确定工作方式和功能,
TCON是控制寄存器,控制T0,T1的启动和停止及设置出标志位。
TMOD
- GATE 门控位
- C/T 模式选择位 1定时器模式,0计数器模式
- M0M1工作方式位
00 方式0 13位定时计数器
01 方式1 16位定时计数器
10 方式2 8位自动重装定时计数器
11 方式3 T0分为两个独立的8位定时计数器,T1停止计数
定时/计数器初始化
- 对TMOD赋值,以确定T0和T1的工作方式。
- 计算初值,并将其写入TH0,TL0或TH1,TL1
假设晶振12 计满时间为t = 65535 * 1/12(震荡周期) * 12 = 65535
- 中断方式,对IE赋值,开放中断
- 使TR0或TR1置位,启动定时/计数器
定时器实现延时
#include <reg52.h>
#define uint unsigned int
#define uchar unsigned char
sbit LE_D = P2^6; //数码管段 该LE控制数码管显示的数字
sbit LE_W = P2^7; //数码管位 该LE控制数码管显示的位置
uint num = 0;
uint time = 0;
//数码管从0->9
uchar code table[] = {0xC0,0xF9,0xA4,0XB0,0x99,0x92,0x82,0xF8,0x80,0x98};
//数码管的数次从0开始每隔1s加1,用定时器实现
void main(){
//中断函数初始化
EA = 1; //开总中断
ET0 = 1; //开T0定时/计数器中断
TR0 = 1; //启动TO TR0为T0运行控制位,置1开始工作
TMOD = 0x01;//设置T0的工作方式 0000 0001
TH0 = 0x3C; //65535 - 50000 = 15535 (50000为50mS)为3CAF TH0为高8位所以赋值3C
TL0 = 0xAF; //TL0低8位所以赋值AF
//数码管显示的位置
LE_W = 1; //开位锁存器
P0 = 0x01; //第一个数码管显示数字
LE_W = 0; //关锁存器
//数码管显示的初始数字
LE_D = 1;
P0 = table[0];
LE_D = 0;
while(1){
if(time == 20){ //进入20次中断后,(每次中断为50mS) 20*50=1000ms = 1s
time = 0; //time清零,重新开始定时
LE_D = 1; //开锁存器
P0 = table[num];//锁存器存入table[num]
LE_D = 0; //关寄存器
num++; //使数码管显示的数字+1
}
if(num == 10){ //当数码管显示的数字为9时num清0 又从0开始
num = 0;
}
}
}
//定时器中断函数
void exter1() interrupt 1{ //1为定时/计数器0(T0)
TH0 = 0x3C; //每次进入定时器函数说明TH0,TL0已加满后清0,所以重新赋值
TL0 = 0xAF; //TL0低8位
time++; //没进入一次中断给time+1
}