一、前言
C8051F340单片的定时器0有4种工作方式,分别是:
方式0——13 位计数器/定时器
方式1——16 位计数器/定时器
方式2——自动重装载的 8 位计数器/定时器
方式3——两个 8 位计数器/定时器
本文介绍工作在方式2——8 位自动重装载计数器/定时器的情况。
方式 2 将定时器 0 配置为具有自动重新装入计数初值能力的 8 位定时
器。TL0 保持计数值,而 TH0 保持重载值。当 TL0 中的计数值发生溢出(从全‘1’到 0x00)时,定时器溢出标志 TF0(TCON.5)被置位,TH0 中的重载值被重新装入到 TL0。如果允许中断,在 TF0 被置位时将产生一个中断。TH0 中的重载值保持不变。为了保证第一次计数正确,必须在允许定时器之前将 TL0 初始化为所希望的计数初值。
二、程序展示
1、程序简介
通过定时器0计时,控制LED灯的闪烁(100ms闪烁一次)。使用单片机内部的12M晶振,进行硬件48分频,并进行软件8分频,目的是为了让计时器能够计100ms级。
X*48 * 8/12000000=0.001(100ms) X=31,也就是计数器需要计31次数,定时器0总共可以计2的8次方次数,也就是256次,因为是从0开始计,最多计导255次,现需要计31次,则计时器的初始值应该为255-31=224次。
2、头文件部分
#include <C8051F340.h>
#define SYSCLK 12000000/8 //软件进行8分频
#define TIMER0_PRESCALE 48 //通过寄存器设置的分频数
#define LED_CHG_RATE 100 //设置LED灯的闪烁频率,100代表100ms
#define TIMER0_TICK_PER_MS SYSCLK/TIMER0_PRESCALE/1000
#define REG1 TIMER0_TICK_PER_MS
#define REG2 0xFF-REG1
#define RELOAD_HIGH REG2 // 高位重载
sbit LED1 = P2^2; //通过P2.2输出驱动LED灯闪烁
void Port_Init (void); //端口初始化
void Timer0_Init (void); //定时器0初始化
3、主程序部分
{
PCA0MD &= ~0x40; // 关闭看门狗
Timer0_Init (); // 定时器0初始化
Port_Init (); // 端口初始化
EA = 1; // 允许中断
while (1);
}
4、端口初始化
void Port_Init (void)
{
XBR1 = 0x40;
P2MDOUT = 0x0C; //设置P2.2推挽输出
}
5、定时器0初始化程序
void Timer0_Init(void)
{
TH0 = RELOAD_HIGH;
TL0 = TH0;
TMOD = 0x02; // 设置工作在8位模式
CKCON = 0x02; // 设置系统时钟48分频
ET0 = 1; // 定时器0终端允许
TCON = 0x10; // 定时器0打开
}
6、定时器0中断程序
void Timer0_ISR (void) interrupt 1
{
static int counter = 0;
if((counter++) == LED_CHG_RATE)
{
LED = ~LED; // LED灯闪烁
counter = 0;
}
}
8位的计数器最多只能计255488/12000000*1000=8.16ms,前面设置的TH0的值是让其1ms中断一次,通过软件counter++到100次,来达到计时100ms的目的。