中断,定时器
一.中断
1.中断原理
单片机通常只会执行主函数的内容,如果在主函数正在执行某一行代码,在没有中断系统的前提下,代码只能一行一行执行,没有应对突发问题的能力。例如我打算设计一个程序通过按键来执行一些东西,如果单片机没有跑到按键的代码上,按键是无效的。虽然大多数情况下单片机的处理速度很快,但是如果出现延时代码,就会发生主函数刷新速度不够快。如果我们把按键放在中断执行,那么按键将具备打断系统当前执行的代码的能力,具有很高的实时性。(实际上比较好的做法是将重要的执行函数放在主函数内,通过定时器中断来控制每个执行函数是否被执行。具体的大家可以看看《时间触发嵌入式系统设计模式》这本书。)
总的来说,中断系统就是一个打断CPU工作去进行其他工作的系统,工作完成后回到原来的位置。根据用户手册可以配置中断系统。
二.定时器
1.定时器原理
在STC15F2K60S2中,定时器0有4种工作模式,定时器1有3种工作模式,定时器2只有1种工作模式,STC15F2K60S2没有定时器3,4。
作为定时器,一定有一个可以表示时间的结构,就是系统时钟。
系统时钟是由主时钟分频得到的,主时钟有两种来源:内部高精度R/C时钟和外部时钟(一般选择内部时钟,在ISP软件中可以选择内部时钟频率)。
系统时钟是对主时钟分频后供给CPU,定时器等实际工作时钟。
总的来说,定时器中断也是一种中断系统,它可以通过计时达到中断系统的效果。
2.定时器模块化编程
(1).编程原理
- 确定工作的方式,通过TMOD控制。
- 选择1T或12T方式,计算定时初值,写入TH,TL。
- 开放中断。
- 选择T1CLKO是否打开。
- 启动定时器。
实际上,我们可以通过ISP软件来自动生成代码
(2).定时器模块化编程代码
//定时器底层驱动代码 Tim.c
#include "Timer.h"
void Timer1Init(void) //1毫秒@12.000MHz
{
AUXR &= 0xBF; //定时器时钟12T模式
TMOD &= 0x0F; //设置定时器模式
TL1 = 0x18; //设置定时初值
TH1 = 0xFC; //设置定时初值
TF1 = 0; //清除TF1标志
TR1 = 1; //定时器1开始计时
ET1 = 1; //打开中断
}
//定时器底层驱动代码 Tim.h (关于多文件编程的问题大家可以看看翁恺老师的C语言教程的第12章)
#include "stc15f2k60s2.h"
void Timer1Init(void);
这个底层驱动代码大家可以通过STC-ISP软件进行一键生成。
对于新手来说,大家没必要细究这个底层代码是如何实现的。当你有一定的基础以后,可以对照上面的图片和STC15的用户手册来仔细看一看怎样对寄存器编程。
//main.c
#include "Tim.h"//头文件
void main(void)
{
Timer1Init();//定时器1初始化
EA = 1;//打开总中断
while(1)//里面放执行函数
{
}
}
/* Timer1_interrupt routine */
void tm1_isr() interrupt 3//里面放定时器处理代码
{
}
注意“interrupt 3“ 一定不要写错,定时器1对的就是3。
这个代码就是给大家一个基本的框架,可以自己去研究研究。对于一个单片机,GPIO和定时器是非常重要的,大家可以多看一看一些讲解的视频和文档,如果真完全展开,外部中断和定时器中断能讲的东西太多了,这里就是给大家一个简单的讲解。