定时/计数器的核心部件是一个加法计数器,本质是对脉冲进行计数,只是计数脉冲的来源不同。当计数脉冲来自系统时钟时,是定时方式,此时定时/计数器每12个时钟或每1个时钟得到一个计数脉冲,计数值加一;当计数脉冲来自单片机外部引脚,则为计数方式,每来一个脉冲加一。
定时/计数器0(T0)有四种工作方式:16位自动重装模式、16位不可自动重装模式、8位自动重装模式和不可屏蔽中断的16位自动重装模式;T1除了模式3无效(T1在模式3时,停止计数)以外,其他工作方式与T0相同;T2、T3和T4的工作模式固定位16位自动重装模式,可以当定时器使用,也可以串口的波特率发生器和可编程时钟输出。本次的学习板(STC15F2K60S)只有T0、T1和T2。
以下是常用的和定时/计数器有关的寄存器:
?
每个16位定时/寄存器又分别由两个8位专用寄存器组成。其中TH0、TL0(对应定时器0)、TH1、TL1(对应定时器1),其访问地址依次为8AH-8DH。它们可单独访问,主要用于装载定时或计数的初始值。
定时器赋初始值计算:如果需要需要定时为50MS,则计算方式如下:如果晶振是12MHZ,则机器周期为12MHz除以12,就是1MHz,每秒1000000次机器周期,那么50ms就是50000次机器周期。65536-50000=15536(3cb0),TH0=0x3c,TL0=0xb0。1ms就是1000次机器周期。(65536-1000)/256是高位,(65536-1000)%256是低位。也可以用STC-ISP直接计算得到如下图:
?以下是测试代码(效果为流水灯):
#include<STC15F2K60S2.H>
#include<intrins.h>
#define uchar unsigned char
#define uint unsigned int
sbit led_sel=P2^3;
sbit key1=P3^2;
uchar led;
uint UintCnt;
void Init(){
P0M1=0x00;
P0M0=0xff;
P2M1=0x00;
P2M0=0xff;
EA=1;
ET0=1;
led_sel=1;
UintCnt=0;
}
void Timer0Init(void) //1毫秒@11.0592MHz
{
AUXR |= 0x80; //定时器时钟1T模式
TMOD &= 0xF0; //设置定时器模式
TL0 = 0xCD; //设置定时初值
TH0 = 0xD4; //设置定时初值
TF0 = 0; //清除TF0标志
TR0 = 1; //定时器0开始计时
}
void main()
{
Init();
Timer0Init();
led=0x01;
while(1)
{
P0=led;
}
}
void et0() interrupt 1
{
UintCnt++; //计数1ms加一次
if(UintCnt==1000) //计到1000,也就是1秒,led灯跳动一次
{
UintCnt=0;
if(led==0x80)
led=0x01;
else
led=led<<1;
}
}
(若有不足和错误,还请各位斧正)
|