51单片机有5个中断源,也就是说,有5种情况会使单片机去处理中断程序。
52单片呢,有6个中断源,比51单片机多一个T2(定时器2)
52单片机中断源:
0. INT0->外部中断0, 由p3.2端口线引入,低电平或下降沿引起
1. INT1->外部中断1, 由p3.3短路线引入,低电平或下降沿引起
2. T0 ->定时器/计数器0中断, 由T0计数器计数满回零引起
3. T1 ->定时器/计数器1中断, 由T1计数器计数满回零引起
4. T2 ->定时器/计数器2中断, 由T2计数器计数满回零引起
5. TI/RI ->串行口中断, 串行端口完成一帧的字符发送/接受后引起
注:寄存器的缩写转为词组为自己所想,木头依据的。
定时器的功能是,定时一个时间然后在时间到的时候引起中断,然后我们可以在中断程序中写代码来完成计时器到达后该做什么事情。
第一个问题就是中断,既然会引起中断,那么就应该打开中断。
中断允许寄存器(IE 感觉是: interrupt enable....) 字节地址A8H,位地址为别是A8H---AFH,可进行位寻址。
D7 D6 D5 D4 D3 D2 D1 D0
EA --- ET2 ES ET1 EX1 ET0 EX0
EA(interrupt (enable) all) 全局中断允许位
EA = 1 打开全局中断控制
EA = 0 关闭全局中断控制
ET2(interrupt (enable) timer 2)定时器/计数器2 中断允许位
ET2 = 1 打开T2中断
ET2 = 0 关闭T2中断
(ET1 ET0同ET2)
ES.(interrupt (enable) serial)串行口中断允许位
ES = 1 打开串口中断
ES = 0 关闭串口中断
EX1(interrupt (enable) external 1)外部中断1中断允许位
EX1 = 1 打开外部中断
EX1 = 0 关闭外部中断
(EX0 同EX1)
第二个问题就是定时器所定时的时间。
定时器有4中工作方式,由M1M0设定,对于不同的方式,有不同的设置初值的计算方法。
定时器模式时候,定时器是对内部的机器周期计数(1个机器周期等于12个震荡周期,即计数频率为晶振频率的1/12)。计数值N乘以机器周期Tcy就是定时时间t。
定时器/计数器工作方式寄存器TMOD( timer mode)字节地址89H不能进行位寻址
D7 D6 D5 D4 D3 D2 D1 D0
GATE C/T M1 M0 GATE C/T M1 M0
D7-D4 定时器1
D3-D0 定时器0
GATE 门控制位
0 定时器/计数器启动与停止仅仅受TCON寄存器的TRX来控制
1 定时器/计数器启动与停止由TCON寄存器中TRX和外部中断引脚上的电平状态来共同控制
C/T 定时器和计数器模式选择
1 计数器模式
0 定时器模式
M1 M0
0 0 方式0,为13位定时/计数
0 1 方式1,为16位定时/计数
1 0 方式2,为8为初值自动重装的8位计数器
1 1 方式3,仅试用与T0,分为两个8位计数器,T1停止计数。
TCON定时器/计数器控制寄存器
D7 D6 D5 D4 D3 D2 D1 D0
TF1 TR1 TF0 TR0 IE1 IT1 IE0 IT0
定时器1(定时器0):
TF1(TF0)
定时器溢出标志,当定时器1计数满溢出则置1,进入中断程序后,由硬件清零。
TR1(TR0)
当GATA = 1 并且INT1为高电平,TR1 = 1 启动定时器1
当GATA = 0, TR1 = 1 启动定时器1
外部中断1(外部中断0):
IE1(IE0)
外部中断1请求标志
IT1(IT0)
外部中断1出发方式选择位
IT1 = 1 电平触发方式,引脚INT1为低电平有效
IT1 = 0 跳变沿触发方式,引脚INT1上的电平从高到低的负跳变有效。
设置初始值问题:(定时器方式1)
机器周期:Tcy
定时器产生一次中断的时间:t
那么计数个数: N = t/Tcy
如果晶振频率为11.0592 ,那么Tcy = 12 * 1/(11.0592) 约等于1.09us。
假设时间t = 50ms 则N = 50 000 / 1.09 约等于 45872。
定时器方式1为16位定时器,16位的取值范围(0 - 65535)共65536计数。
N + x = 65536
x = 65536 - N
THX = x / 256
TLX = x % 256
第三个问题是如何写中断程序
void 函数名() interrupt 中断号
{
}
中断源 序号 级别(从高到低)
INT0 0
T0 1
INT1 2
T1 3
TI/RI 4
T2 5
如果所要设置的定时时间超过了16bit所设置的最大时间可以在中断函数内进行操作。
比如上面设置的50ms,我们要设置为1s。 1s = 20 * 50ms
void main()
{
int num = 0;
。。。。
。。。。
}
void timer0 interrupt 1
{
TH0 = ...
TL0 = ...
num++;
if(num == 20)
{
num = 0;
...
. ..定时1s的操作
}
}
实例:
led 以1s 间隔闪烁
#include<reg52.h>
sbit led1 = P1^0;
unsigned char num;
void main()
{
TMOD = 0x01;
TH0 = (65536 - 45872) / 256;
TL0 = (65536 - 45872) % 256;
EA = 1;
ET0 = 1;
TR0 = 1; ///GATA = 0;复位时候默认设置
while(1);
}
void timer0 interrupt 1
{
TH0 = (65536 - 45872) / 256;
TL0 = (65536 - 45872) % 256;
num++;
if(num == 20)
{
num = 0;
led1 = ~led1
}
}