第十五届蓝桥杯单片机组——定时器的基本原理与应用

  • Home
  • 跨服战场
  • 第十五届蓝桥杯单片机组——定时器的基本原理与应用

文章目录

一、定时器介绍二、定时器的应用2.1 定时功能❗注意事项!❗什么是1T和12T

2.2 计数功能❗注意点

三、利用定时器计数功能实现555频率测量

一、定时器介绍

在没有钟表的时候,定时的方式通过有一注香的时间,或者一桶水的时间。前者烧香不断减少是减法,后者滴水不断增加是加法。 定时/计数器,是一种能够对内部时钟信号或外部输入信号进行计数,当计数值达到设定要求时,向CPU提 出中断处理请求,从而实现定时或者计数功能的外设。定时/计数器的最基本工作原理是进行计数。作为定时器时,计数信号的来源选择周期性的内部时钟脉冲;用作计数器时,计数信号的来源选择非周期性的外部输入信号。 不管是定时器还是计数器,本质上都是计数器。

二、定时器的应用

定时器有两个功能,分别是定时和计数功能,定时是对内部时钟而计数是对外部时钟。

2.1 定时功能

举个例子,比如我想每隔2ms实现做某一件事,那么我们就在初始化的时候设置定时时长为2ms就可以。比赛的时候不推荐大家自己算TLx和THx的值,直接用STC烧录工具就可以直接实现,顺带着帮你把中断服务函数格式都写了。

1.系统时钟频率为12Mhz,看板子最左侧的晶振。 2.设置时间单位为ms 3.定时器输入时钟12分频(12T) 4.使能定时器中断

❗注意事项!

用STC软件生成的初始化代码中只开启了定时器中断,并没有开启总中断,所以需要我们在调用Timer0_Init()后添加一行代码(EA=1;),或者直接在Timer0_Init()中添加EA=1也行。 此外AUXR寄存器在reg52.h中没有定义,所以需要自己定义一下,或者将reg52.h改为stc15f2k60s2.h虽然比较长,但是多写几遍就记住了。

❗什么是1T和12T

在51中,1T模式是指每一个系统基本时钟执行1个动作,12T指每12个系统基本时钟执行1个动作。IAP12f2k60s2是工作在1T模式,所以它的运行速度比stc89c51\52快12倍。我们在定时器初始化中设置AUXR为12T并不会改变系统指令的运行速度,它只是改变了定时器输入信号,将输入信号进行12分频。

为什么选择12T,因为这样定时器就可以计数更长的时间,比1T模式下多12倍呢!

#include // AUXR寄存器需要用到这个头文件

void Timer0_Isr(void) interrupt 1

{

}

void Timer0_Init(void) //2ms@12.000MHz

{

AUXR &= 0x7F; //Timer clock is 12T mode,不会改变系统运行速度

TMOD &= 0xF0; //Set timer work mode

TL0 = 0x30; //Initial timer value

TH0 = 0xF8; //Initial timer value

TF0 = 0; //Clear TF0 flag

TR0 = 1; //Timer0 start run

ET0 = 1; //Enable timer0 interrupt

EA=1; // 开启总中断

}

2.2 计数功能

一样的我们利用软件生成初始化代码,在此基础上做一些修改就可以了。

❗注意点

1.开发板上只将定时器0的时钟输入引脚拉了出来,所以只能使用定时器0来实现外部时钟计数。 2.要使定时器的输入信号不分频,也就是设置为1T模式 3.切记不能设置成为自动重转载模式!!! 4.修改TMOD让定时器输入信号为外部信号

前面三点在烧录软件中操作,第四点在keil中改写。

根据寄存器说明,将生成代码中的TMOD |= 0x01;改为TMOD |= 0x05;

三、利用定时器计数功能实现555频率测量

可以直接复制到main.c中直接用。

#include

#include

unsigned char count_t=0;

unsigned int count_f=0;

unsigned int last_f=0;

unsigned char code dat[]={0xc0, 0xf9, 0xa4, 0xb0, 0x99,

0x92, 0x82, 0xf8, 0x80, 0x90,

0x88,0x80,0xc6,0xc0,0x86,0x8e,

0xbf,0x7f};

void Delay()

{

unsigned char i, j;

_nop_();

_nop_();

i = 22;

j = 128;

do

{

while (--j);

} while (--i);

}

void selectHC573(unsigned char num)

{

switch(num)

{

case 4:

P2=(P2 & 0x1f) | 0x80;

break;

case 5:

P2=(P2 & 0x1f) | 0xa0;

break;

case 6:

P2=(P2 & 0x1f) | 0xc0;

break;

case 7:

P2=(P2 & 0x1f) | 0xe0;

break;

case 0:

P2=(P2 & 0x1f) | 0x00;

break;

}

}

void system_Init()

{

selectHC573(5);

P0=0x00;

selectHC573(0);

}

void display_SMG_Bit(unsigned char dat, unsigned pos)

{

/*消影法2*/

P0=0xff;

selectHC573(7);

selectHC573(0);

P0=0x01<<(pos-1);

selectHC573(6);

selectHC573(0);

P0=dat;

selectHC573(7);

selectHC573(0);

}

void display_D_SMG(unsigned int dat1)

{

display_SMG_Bit(dat[15],1);

Delay();

display_SMG_Bit(0xff,2);

Delay();

display_SMG_Bit(0xff,3);

Delay();

if(dat1>9999)

{

display_SMG_Bit(dat[dat1/10000],4);

Delay();

}

if(dat1>999)

{

display_SMG_Bit(dat[dat1/1000%10],5);

Delay();

}

if(dat1>99)

{

display_SMG_Bit(dat[dat1/100%10],6);

Delay();

}

if(dat1>9)

{

display_SMG_Bit(dat[dat1 / 10 % 10],7);

Delay();

}

display_SMG_Bit(dat[dat1 % 10],8);

Delay();

}

void Timer1_Isr(void) interrupt 3

{

count_t++;

if(count_t==99)

{

count_t=0;

count_f=TH0;

count_f=(count_f<<8)|TL0;

last_f=count_f;

TL0=0;

TH0=0;

}

}

void Timer0_Init(void) //1ms@12.000MHz

{

AUXR |= 0x80; //imer clock is 1T mode

TMOD &= 0xF0; //Set timer work mode

TMOD |= 0x05; //Set timer work mode

TL0 = 0x00; //Initial timer value

TH0 = 0x00; //Initial timer value

TF0 = 0; //Clear TF0 flag

TR0 = 1; //Timer0 start run

}

void Timer1_Init(void) //10ms@12.000MHz

{

AUXR &= 0xBF; //Timer clock is 12T mode

TMOD &= 0x0F; //Set timer work mode

TL1 = 0xF0; //Initial timer value

TH1 = 0xD8; //Initial timer value

TF1 = 0; //Clear TF1 flag

TR1 = 1; //Timer1 start run

ET1 = 1; //Enable timer1 interrupt

EA=1;

}

void main()

{

system_Init();

Timer0_Init();

Timer1_Init();

//开启总中断

while(1){

display_D_SMG(last_f);

}

}