文章目录
- 定时器2中断的开启
- 借用isp软件生成代码
- 下面进行定时器2中断开启
- 最终开启定时器2中断的代码
- 定时器2中断服务函数的编写
- 查手册得到定时器2中断查询次序号
- 查手册得次序号为12
- 通过公式计算
- 中断服务函数编写
- 结合之前学的点亮LED
- 现象演示
定时器2中断的开启
借用isp软件生成代码
此代码仅仅是开启定时器2的定时功能
void Timer2Init(void) //1毫秒@12.000MHz
{
AUXR |= 0x04; //定时器时钟1T模式
T2L = 0x20; //设置定时初始值
T2H = 0xD1; //设置定时初始值
AUXR |= 0x10; //定时器2开始计时
}
下面进行定时器2中断开启
打开STC15系列单片机用户手册
可以看到 IE(可位寻址) 和 IE2(不可位寻址) 两个中断允许控制寄存器;
可位寻址与不可位寻址的意思就是:是否可以按位进行赋值操作;
这里需要打开定时器2的中断开关,因此 IE2 的 ET2位 赋值为1,又因为IE2寄存器不可位寻址,则IE2必须整个字节进行赋值,即 IE2 |= 0x04;这样赋值。
打开定时器2中断后,还必须开启CPU响应所有中断(总中断允许位),因此 IE 的 EA位 赋值为1,又因为IE寄存器可位寻址,则IE中的每一位可以单独赋值,即"EA = 1"这样赋值。
最终开启定时器2中断的代码
void Timer2Init(void) //1毫秒@12.000MHz
{
AUXR |= 0x04; //定时器时钟1T模式
T2L = 0x20; //设置定时初始值
T2H = 0xD1; //设置定时初始值
AUXR |= 0x10; //定时器2开始计时
//***************************从此往上 只是单纯的开定时器2
IE2 |= 0x04; //开定时器2 的 中断
EA = 1; //总中断
}
定时器2中断服务函数的编写
查手册得到定时器2中断查询次序号
(当然也有计算公式)
查手册得次序号为12
通过公式计算
中断地址向量=0003H+ 中断序号×8
所以:中断序号 = (中断地址向量 - 0003H)/8;
例如: 定时器2中断(即中断序号为12) 其中断地址向量为0063H,0063H-0003H=0060H=96,96/8 = 12,因此定时器2中断号就为12.
中断服务函数编写
void Timer2Handler() interrupt 12
{
//这里因为设置的是16位自动重载,不需要像传统51那样给定时器赋初值
}
结合之前学的点亮LED
(三)点亮你的LED
Led1闪烁的代码:
#include <STC15F2K60S2.H>
typedef unsigned char u8;
typedef unsigned int u16;
void DeviceCtrl(u8 p2data,u8 p0data)
{
P0 = p0data; //给数据
P2 = (P2&0x1f)|p2data; // (开门)
P2 &= 0x1f; //(关门)
}
void Timer2Init(void) //1毫秒@12.000MHz
{
AUXR |= 0x04; //定时器时钟1T模式
T2L = 0x20; //设置定时初始值
T2H = 0xD1; //设置定时初始值
AUXR |= 0x10; //定时器2开始计时
//***************************从此往上 只是单纯的开定时器2
IE2 |= 0x04; //开定时器2 的 中断
EA = 1; //总中断
}
void main()
{
DeviceCtrl(0xa0,0x10);//buzz --close relay --open
DeviceCtrl(0x80,0xfe);//open led1
Timer2Init();
while(1){
}
}
void Timer2Handler() interrupt 12
{
static u16 one_sec = 0;
one_sec++;
if(one_sec<=1000){
DeviceCtrl(0x80,0xfe);//open led1 亮
}else if(one_sec<=2000){
DeviceCtrl(0x80,0xff);//灭
}else{
one_sec = 0 ;
}
}
现象演示
(四)开启定时器2中断
----- 如有错误欢迎大家批评指正!!!