7.定时器
定时器作用:
1.用于计时系统,可实现软件计时,或者使程序每隔一固定时间完成一项操作;
2.替代长时间的Delay,提高CPU运行效率和处理速度。
3.切换多任务。
定时器框图:
定时器在单片机内部就像一个小闹钟一样,根据时钟的输出信号,每隔‘1秒’,计数单元的数值就增加1,
当计数单元数值增加到‘设定的闹钟提醒时间’时,计数单元就会向中断系统发出中断申请,
产生“响铃提醒”,使程序跳转到中断服务函数中执行。
时钟:提供计数单元的时钟脉冲
系统时钟,即晶振周期,本开发板的晶振为12MHz.时钟12分频。
↓
计数单元:时钟计数
↓
中断系统:产生中断,执行定时任务。
中断系统是为使CPU具有 紧急事件的实时处理能力而设置的。
处理完以后,再回到原来被中断的地方,继续原来的主工作。
模式1: 16位定时器/计数器(最常用)
计数器到最大值,产生中断信号。
单片机通过寄存器值得修改,来实现内部不同的电路连接。
寄存器是连接软硬件的媒介。
7.1 按键控制led流水灯模式。
// 闹钟响了,执行中断任务。中断子程序。 在main里面实现。。
void Timer0_Routine() interrupt 1
{
static unsigned int T0Count; // 累加计数器。
// 重新配置寄存器。
TH0 = 64535/256; // 高位,最大能计数65535
TL0 = 64535%256 +1;
T0Count++;
if(T0Count >= 1000) {
T0Count = 0;
P2_0 = ~P2_0; // 1s 亮灭
}
}
void main(){
// 配置寄存器。
Timer0_init();
while(1) {
}
}
模块化:
// Timer0.h
void Timer0_init();
// Timer0.c
void Timer0_init(){ // 定时器0 初始化。
// TMOD =0x01; //配置寄存器:0000 0001
TMOD = TMOD & 0xF0; // TMOD低4位清零,高4位保持不变
TMOD = TMOD | 0x01; // TMOD最低位 置1, 高4位保持不变
TF0 =0;
TR0 =1;
// 设置起始值,64535离计数器溢出差值1000,所以计时单位是1ms。
TH0 = 64535/256; // 高位,最大能计数65535. 0xFC
TL0 = 64535%256 +1; // 0x18
ET0 =1;
EA =1;
PT0 =0;
}
7.2.按键控制
//Key.c 按键模块
// 获取独立按键的键码,范围0-4,无按键按下返回0.
unsigned char getKey(){
unsigned char KeyNumber =0;
// 消除抖动,按键抬起相应事件。按键检测。
if(P3_1==0){Delay(20); while(P3_1==0);Delay(20); KeyNumber=1;}
if(P3_0==0){Delay(20); while(P3_0==0);Delay(20); KeyNumber=2;}
if(P3_2==0){Delay(20); while(P3_2==0);Delay(20); KeyNumber=3;}
if(P3_3==0){Delay(20); while(P3_3==0);Delay(20); KeyNumber=4;}
return KeyNumber;
}
// main.c
#include <INTRINS.H> // 循环移位函数,用于方便实现流水灯。
unsigned char KeyNum; // 记录按下了那个按键。
unsigned char LEDMode; // 实现流水灯模式控制。
void main() {
Timer0_init();
P2 = 0xFE; // 初始亮灯。
while(1) {
KeyNum = Key();
if(KeyNum==1){ // 控制向左,向右流水灯效果。
LEDMode++;
if(LEDMode>=2){LEDMode=0;}
}
//if(KeyNum==2) P2_2 =~P2_2;
//if(KeyNum==3) P2_3 =~P2_3;
//if(KeyNum==4) P2_4 =~P2_4;
}
}
// 闹钟响了,执行中断任务。中断子程序。 在main里面实现。。
void Timer0_Routine() interrupt 1
{
static unsigned int T0Count; // 累加计数器。
// 重新配置寄存器。
TH0 = 64535/256; // 高位,最大能计数65535
TL0 = 64535%256 +1;
T0Count++;
if(T0Count >= 1000) {
T0Count = 0;
if(LEDMode==0){ // 左右循环移位函数,实现流水灯。
P2_0 = _crol_(P2, 1);
}
if(LEDMode==1){
P2_0 = _cror_(P2, 1);
}
}
}
7.3时钟实现。
// 需要依赖Delay.h, LCD1602.h, Timer0.h
unsigned char Sec,Min,Hour;
void main() {
LCD_Init();
LCD_ShowString(1,1, "Clock:");
LCD_ShowString(2,1, " : :"); // 显示时间中间的冒号
Timer0_init();
while(1) {
LCD_ShowNum(2,1, Hour, 2);
LCD_ShowNum(2,4, Min, 2);
LCD_ShowNum(2,7, Sec, 2);
}
}
// 中断函数
void Timer0_Routine() interrupt 1
{
static unsigned int T0Count; // 累加计数器。
// 重新配置寄存器。
TH0 = 64535/256; // 高位,最大能计数65535
TL0 = 64535%256 +1;
T0Count++;
if(T0Count >= 1000) { //每隔1秒,处理。
T0Count = 0;
Sec++;
if(Sec>=60){ // 秒到达60,分钟+1
Sec=0;
Min++;
if(Min>=60){ // 分钟到达60,小时+1
Min =0;
Hour++;
if(Hour>=24){ // 时到达24,清零
Hour =0;
}
}
}
}
}








网友评论