1.再遇多文件编程
因为定时器经常在后面的教程中使用到,所以我们也把这部分功能代码单独使用文件封装起来。
在第六章的教程中已经教过大家多文件创建,这里点到为止。
创建好“timer.c”和“timer.h”
添加进工程中
2.timer.c的代码
#include <reg52.h> #include <function.h> //详见第六章第8讲 u8 T0RH,T0RL,T1RH,T1RL; void TIM0_Init(u32 us,int trim)//trim:微调 { u32 tmp; //临时变量 tmp = 11059200 / 12; //定时器计数频率 tmp = ( tmp * (us/100) )/10000; //计算所需的计数值 tmp = 65536 - tmp; //计算定时器重载值 tmp = tmp+trim; //微调计数值使其定时更精确到我们想要的定时时间 T0RH = (unsigned char)(tmp>>8); //定时器重载值拆分为高低字节 T0RL = (unsigned char)tmp; TMOD &= 0xF0; //清0低四位 TMOD |= 0x01; //设置定时器0为工作模式1 TH0 = T0RH; //加载T0重载值 TL0 = T0RL; ET0 = 1; //闭合定时器0中断的开关 TR0 = 1; //启动定时器0 } void TIM1_Init(u32 us,int trim)//trim:微调 { u32 tmp; //临时变量 tmp = 11059200 / 12; //定时器计数频率 tmp = ( tmp * (us/100) )/10000; //计算所需的计数值 tmp = 65536 - tmp; //计算定时器重载值 tmp = tmp+trim; //微调计数值使其定时更精确到我们想要的定时时间 T1RH = (unsigned char)(tmp>>8); //定时器重载值拆分为高低字节 T1RL = (unsigned char)tmp; TMOD&=0x0F;//清0高四位 TMOD|=0x10;//设置定时器1为工作模式1 TH1 = T1RH;//加载T1重载值 TL1 = T1RL; ET1 = 1; //闭合定时器1中断的开关 TR1 = 1; //启动定时器1 }
“TMOD&=0xF0;”的作用跟数码管显示小数点的代码技巧一样,保持前面4位的值不变,清0后四位,然后“TMOD|=0x01;”就是不改变原来高四位的值,然后把低四位设成 0001。
如果在TIM0_Init()函数中只写“TMOD=0x01;”
在TIM1_Init()函数中只写“TMOD=0x10;”
然后初始化时像这样按顺序来写
TIM0_Init(20000,20);//定时20ms,20微调使定时精度更高
TIM1_Init(50000,20);//定时50ms,20微调使定时精度更高
那么执行TIM1_Init()的函数内容时就会执行“TMOD=0x10;”把人家低四位给清0了,原本想让定时器0工作在模式1,现在低2位的值变了也就不是工作在模式1了。
所以“TMOD&=0x0F; TMOD|=0x10;”的写法是不干涉互相的位。
我们定义了“T0RH,T0RL,T1RH,T1RL”四个8位的全局变量(R:reload)用来在中断函数里重新赋值。
因为工作模式1都是需要在中断函数中重新赋初值,所以这四个变量是存取初始化时给THx和TLx的初值。
3.timer.h的代码
#ifndef __TIMER_H__ #define __TIMER_H__ extern u8 T0RH,T0RL,T1RH,T1RL; void TIM0_Init(u32 us,int trim);//trim:微调 void TIM1_Init(u32 us,int trim);//trim:微调 #endif
4.main.c的代码
这样,实现间隔50ms的流水灯在书写上就相当简洁了
#include <reg52.h> #include <function.h> //详见第六章第8讲 #include <timer.h> void main() { LED_Init(); //初始化LED硬件模块 EA = 1; //闭合总中断开关 TIM0_Init(50000,20);//用定时器0定时50ms,20是微调使中断函数里的i均匀地50.00ms后自加,精度更高 while(1); } void TIM0_IRQHandler() interrupt 1 { static u8 i; TH0 = T0RH; //重新加载重载值 TL0 = T0RL; P0=~(0x01<<i); i++; if(i>=8)i=0; }
C语言网提供由在职研发工程师或ACM蓝桥杯竞赛优秀选手录制的视频教程,并配有习题和答疑,点击了解:
一点编程也不会写的:零基础C语言学练课程
解决困扰你多年的C语言疑难杂症特性的C语言进阶课程
从零到写出一个爬虫的Python编程课程
只会语法写不出代码?手把手带你写100个编程真题的编程百练课程
信息学奥赛或C++选手的 必学C++课程
蓝桥杯ACM、信息学奥赛的必学课程:算法竞赛课入门课程
手把手讲解近五年真题的蓝桥杯辅导课程