STC89C51RC/RD+ 定时器数量: 3个;
T0模式:工作模式
模式0: 13位计数器;
模式1: 16位计数器;
模式2: 8位计数器 (带重装载功能);
模式3: 2个8位计数器;
T1模式:工作模式
模式0: 13位计数器;
模式1: 16位计数器;
模式2: 8位计数器 (带重装载功能);
T2模式:工作模式
模式0: 16位计数器 (带重装载功能);
模式1: 16位捕获功能;
模式2: 波特率发生器;
计数器对 单片机<内部>的时钟脉冲计数,叫定时器(Timer); // 因为内部时钟频率稳定;
计数器对单片机<外部> 的脉冲计数, 叫计数器(Counter);
CPU比作人, 人睡觉, 需要几点起床, 就设置个几点; 要是没这个闹钟, 上班估计要迟到了;
思考"闹钟"的神奇,
比如洗衣机上的, 洗23分钟,后"嘀 嘀"叫你, 这23分钟你就能干其他的;
比如学校的上下课铃声, 有了它, 整个有了秩序;
注意:
重点关注用到的,用不到的只做了解;
这样才能循序渐进的,掌握改技能;
control = ( (~(GATE ) | (INT0#) ) & TR0;
2个寄存器, TH0,存高8位, TL0,存低8位;
比如: 55555,
转为 16进制 0xD953,
则TH0 = 0xD9; TL0 = 0x53;
置1: 计数器 计数结束, 由硬件电路将TF置1, 并产生中断;
清0: 产生中断后, 硬件自动清零;
滴水时钟
定时器0为例, 使能ET0,和EA后, 在定时器产生中断标志位TF时,CUP就会被中断,去执行中断服务函数;
功能需求: 通过定时器0, 16位定时器模式, 实现LED灯 循环1S亮, 1S灭;
#include
typedef unsigned char uchar8_t;
typedef unsigned short ushort16_t;
sbit LED0 = P3^0;
sbit LED7 = P3^7;
#define FOSC 12000000L
#define TIM_1MS (65536 - FOSC/12/1000) // 1ms time in 12Tmode, 2^16 = 65536, 1s = 1000ms;
ushort16_t cnt = 0;
void Tim0_init_it(void);
/**
* main
*/
int main(void)
{
uchar8_t i = 0;
uchar8_t j = 0;
Tim0_init_it(); //
while (1) {
for (i = 0; i<200; i++) {
for (j = 0; j<200; j++)
/* nothing */ ;
}
LED0 = ~LED0;
}
}
void Tim0_init_it(void)
{
uchar8_t tmp = 0;
/* Tim0 Mode1 */
tmp = TMOD; // read TMOD;
tmp &= 0xF0; // clean Tim0:[GATE, M1,M0];
tmp |= 0x01; // find value;
TMOD = tmp; // set Tim0 as mode1(16bit)
/* Tim0 initial value*/
TL0 = TIM_1MS; // Low Byte;
TH0 = TIM_1MS >> 8; // High Byte;
/* Start Tim0 */
TR0 = 1;
/* Enable interrupt*/
IPH |= 0x02; // PT0H = 1;
PT0 = 1; // Tim0 Priority
ET0 = 1;
EA = 1;
}
void tim0_handle() interrupt 1
{
/* Reload value */
TL0 = TIM_1MS; // Low Byte;
TH0 = TIM_1MS >> 8; // High Byte;
if (cnt == 1000-1) { // 结束条件:cnt 数1000-1个;1000 * 1ms = 1S;
LED7 = ~LED7;
cnt = 0;
} else {
cnt++; // 加一条件:TF0 == 1;
}
}
// end file
注意:
1> 时钟源选择
2> 进入中断后,初始值立马重载;
3> 自己实现的cnt这个计数器 - 3要素:
初始值:cnt == 0;
加一条件: TF == 1;
结束条件: cnt == 1000 - 1; // 为什么减1,因为是从0开始数数的;