定时器 2
原理图
示例
配置定时器 2:
- 16 位自动重装定时器;
- 时钟源等于内部系统时钟;
- 允许其在计数溢出之后请求中断;
- 每次中断反转一次 P1.1 的输出电平。
main.c 文件:
sfr IE = 0xA8;
sfr IE2 = 0xAF;
#define GLOBAL_IE_EA (0x80)
#define T2_IE2_ET2 (0x04)
sfr T2L = 0xD7;
sfr T2H = 0xD6;
sfr AUXR = 0x8E;
#define T2_AUXR_T2R (0x10)
#define T2_AUXR_T2CT (0x08)
#define T2_AUXR_T2x12 (0x04)
sfr P1 = 0x90;
sbit LED = P1^1;
void main() {
AUXR &= ~T2_AUXR_T2CT;
T2H = (65536 - 10000) >> 8;
T2L = (65536 - 10000) & 0xFF;
AUXR |= T2_AUXR_T2R;
IE2 |= T2_IE2_ET2;
IE |= GLOBAL_IE_EA;
while(1) {}
}
void timer2InterruptService() interrupt 12 {
LED = !LED;
}
使用 STC-ISP 下载程序,频率设为 12.000 MHz:
注意:虽然 STC-ISP 提示下载失败!但是,我发现单片机仍然按照我的设想执行程序,这里可能是 STC-ISP 有问题。
对 T2 的时钟源进行 12 分频(AUXR &= ~T2_AUXR_T2x12; ),测量 P1.1 输出:
注意:虽然在原理图中,我给单片机的电源符号是 5V,但是在实际测试中,我使用的是 USB 转串口模块上提供的 3.3V(实测没有 3.3V),这并不妨碍单片机正常运行。
不对 T2 的时钟源进行分频(AUXR |= T2_AUXR_T2x12; ),测量 P1.1 输出:
模块化处理
把所有的代码写在一个 main.c 文件是非常不好的习惯,我们需要将上例中的定时器 2 模块化处理:
- 将 6 ~ 40 行提取到 stc15w204s.h 头文件中;
- 将 46 ~ 54 行封装成函数,在 timer2.c 文件中实现,在 timer2.h 头文件中声明。
工程结构:
stc15w204s.h 头文件:
- 声明有关定时器 2 的特殊功能寄存器;
- 声明有关定时器 2 的特殊功能寄存器的位掩码;
- 以及其他。
#ifndef __STC15W204S_H
#define __STC15W204S_H
sfr IE = 0xA8;
sfr IE2 = 0xAF;
#define GLOBAL_IE_EA (0x80)
#define T2_IE2_ET2 (0x04)
sfr T2L = 0xD7;
sfr T2H = 0xD6;
sfr AUXR = 0x8E;
#define T2_AUXR_T2R (0x10)
#define T2_AUXR_T2CT (0x08)
#define T2_AUXR_T2x12 (0x04)
sfr P1 = 0x90;
typedef enum {
FALSE = 0,
TRUE = !FALSE
} boolean;
#define enableInterrupts(enable) if(enable) { \
IE |= GLOBAL_IE_EA; \
} else { \
IE &= ~GLOBAL_IE_EA; \
}
#endif
timer2.h 头文件:
#ifndef __STC15W204S_TIMER_2_H
#define __STC15W204S_TIMER_2_H
#include "stc15w204s.h"
typedef enum {
TIMER2_PRESCALER_DIVIDED_BY_1 = ((unsigned char)0x00),
TIMER2_PRESCALER_DIVIDED_BY_12 = ((unsigned char)0x01)
} Timer2Prescaler;
typedef struct {
void (*asTimer)(boolean);
void (*setCounter)(unsigned int);
void (*setTimer)(unsigned int);
void (*setPrescaler)(Timer2Prescaler);
void (*start)(boolean);
void (*enableInterrupt)(boolean);
} Timer2;
extern Timer2 timer2;
void Timer2Constructor();
#endif
timer2.c 文件:
#include "timer2.h"
Timer2 timer2;
void asTimer(boolean isTimer) {
if(isTimer) {
AUXR &= ~T2_AUXR_T2CT;
} else {
AUXR |= T2_AUXR_T2CT;
}
}
void setCounter(unsigned int counter) {
T2H = (counter) >> 8;
T2L = (counter) & 0xff;
}
void setPrescaler(Timer2Prescaler prescaler) {
switch(prescaler) {
case TIMER2_PRESCALER_DIVIDED_BY_1:
AUXR |= T2_AUXR_T2x12;
break;
case TIMER2_PRESCALER_DIVIDED_BY_12:
AUXR &= ~T2_AUXR_T2x12;
break;
}
}
void start(boolean start) {
if(start) {
AUXR |= T2_AUXR_T2R;
} else {
AUXR &= ~T2_AUXR_T2R;
}
}
void enableInterrupt(boolean enable) {
if (enable) {
IE2 |= T2_IE2_ET2;
} else {
IE2 &= ~T2_IE2_ET2;
}
}
void Timer2Constructor() {
timer2.asTimer = &asTimer;
timer2.setCounter = &setCounter;
timer2.setTimer = &setCounter;
timer2.setPrescaler = &setPrescaler;
timer2.start = &start;
timer2.enableInterrupt = &enableInterrupt;
}
将定时器 2 的功能模块化处理之后,main.c 文件如下:
#include "timer2.h"
sbit LED = P1^1;
void main() {
Timer2Constructor();
timer2.asTimer(TRUE);
timer2.setPrescaler(TIMER2_PRESCALER_DIVIDED_BY_1);
timer2.setTimer(65536 - 10000);
timer2.start(TRUE);
timer2.enableInterrupt(TRUE);
enableInterrupts(TRUE);
while(1) {}
}
void timer2InterruptService() interrupt 12 {
LED = !LED;
}
参考
宏晶科技 STC - STC15 系列单片机器件手册
|