UAV2201~UAV2205编程训练51定时器
例子001、51单片机定时器基础训练
下面是基本的 51 定时器控制代码LED闪烁0.5s
#include <reg52.h> // 8051 头文件
// 定义时钟频率为 12MHz
#define FOSC 12000000UL
// 定义定时器重装值
#define TIMER_RELOAD_VALUE 65536-50000
sbit LED=P1^0; // 定义 LED 灯连接的端口
unsigned char cnt;
// 初始化定时器0
void Init_Timer0()
{
TMOD |= 0x01; // 将定时器0工作方式设置为模式1
TH0 = TIMER_RELOAD_VALUE / 256; // 计算定时器重装值的高8位并赋值
TL0 = TIMER_RELOAD_VALUE % 256; // 计算定时器重装值的低8位并赋值
EA = 1; // 开启全局中断
ET0 = 1; // 开启定时器0中断
TR0 = 1; // 开启定时器0
}
// 定时器0中断处理函数
void Timer0_ISR() interrupt 1
{
TH0 = TIMER_RELOAD_VALUE / 256; // 计算定时器重装值的高8位并赋值
TL0 = TIMER_RELOAD_VALUE % 256; // 计算定时器重装值的低8位并赋值
cnt++;
if(cnt==10)
{
cnt = 0;
LED = ~LED; // LED 灯取反
}
}
// 主函数
void main()
{
Init_Timer0(); // 初始化定时器0
while(1); // 保持程序运行
}
这份代码中,使用定时器0来控制 LED 灯的闪烁。定时器的工作方式被设置为模式1,并且每次重装时赋值为 TIMER_RELOAD_VALUE,即计算出的定时时间。开启定时器0中断后,每当定时器0计数到 TIMER_RELOAD_VALUE 时,会触发中断处理函数 Timer0_ISR(),在其中将计数值重新赋为 TIMER_RELOAD_VALUE 并将 LED 灯进行取反操作。
在你的具体应用中,你可以根据需要更改定时时间和控制操作。
例子002、运用的定时器查询方式和中断方式,实现流水灯每隔0.5s流动或者数码管每隔1s计数
#include <reg52.h> //#include <intrins.h> unsigned char Tab[]={0xC0,0xF9,0xA4,0xB0,0x99,0x92, 0x82,0xF8,0x80,0x90,0x88,0x83,0xC6,0xA1,0x86,0x8E}; //共阳极8段 unsigned char cnt,i; void main() { TMOD = 0x01; //设定时器0为mode1 TH0 = (65536-50000)/256; TL0 = (65536-50000)%256; EA = 1; //开总中断 ET0 = 1; //开定时器0中断 TR0=1; //启动定时器0 TF0=0; //清定时器溢出标志位 P0=0xff; //1111 1111关闭LED P1=0X00; while(1) { while(TF0==0); TF0=0; TH0=(65536-50000)/256; // 定时器 T0的高 8 位赋初值 TL0=(65536-50000)%256; // 定时器 T0的低 8 位赋初值 cnt++; if(cnt>10) { cnt=0; P0 = Tab[i]; if(++i>9)i=0; } } } //void time0(void) interrupt 1 //{ // TH0=(65536-50000)/256; // 定时器 T0 的高 8 位赋初值 // TL0=(65536-50000)%256; // 定时器 T0 的低 8 位赋初值 // cnt++; // if(cnt>10) // { // cnt=0; // if(++i>9)i=0; // P2 = ~(1<<i); // } //}
例子003、两位数码管60s计时
使用time0定时,50ms计数20次,作为1s时钟(模式1),
使用time1定时,250us计数32次,作为数码管动态扫描8ms(模式2)
#include <reg52.h> unsigned char Tab[]={0xC0,0xF9,0xA4,0xB0,0x99,0x92, 0x82,0xF8,0x80,0x90,0x88,0x83,0xC6,0xA1,0x86,0x8E}; //共阳极8段 char dis[2]={0xc0,0xc0};//显示存储数据,初始显示00 char cnt0,cnt1,second,scan=0; //变量初始化默认0 void main() { TMOD = 0x21; //设T0为mode1,设T1为mode2, TH0 = (65536-50000)/256; TL0 = (65536-50000)%256; TH1 = 256-250; TL1 = 256-250; EA = 1; //开总中断 ET0 = 1;ET1 = 1;//开T0/T1中断 TR0 = 1;TR1 = 1;//启动T0/T1 TF0=0;TF1=1; //清定时器溢出标志位 while(1) { ; } } void time0(void) interrupt 1 //1s { TH0=(65536-50000)/256; // 定时器 T0 的高 8 位赋初值 TL0=(65536-50000)%256; // 定时器 T0 的低 8 位赋初值 if(++cnt0 == 20) //若中断20次就1s { cnt0 = 0; //重新计数 second++; if(second==60) { second = 0; } } dis[0] = Tab[second/10]; dis[1] = Tab[second%10]; } void time1(void) interrupt 3 //动态扫描每隔8ms { if(++cnt1 == 32) //若中断32次就8ms { cnt1 =0; //重新计数 if(++scan == 3)scan =1; P0 = 0xff; //关闭数码管 P1 = ~scan; P0 = dis[scan -1]; } }
例子004、四位数码管60s计数(含ms两位数)
#include <reg52.h> unsigned char Tab[]={0xC0,0xF9,0xA4,0xB0,0x99,0x92, 0x82,0xF8,0x80,0x90,0x88,0x83,0xC6,0xA1,0x86,0x8E}; //共阳极8段 char dis[4]={0xc0,0xc0,0xc0,0xc0};//显示存储数据,初始显示00 char cnt0,cnt1,second,scan=0; //变量初始化默认0 void main() { TMOD = 0x21; //设T0为mode1,设T1为mode2, TH0 = (65536-50000)/256; TL0 = (65536-50000)%256; TH1 = 256-250; TL1 = 256-250; EA = 1; //开总中断 ET0 = 1;ET1 = 1;//开T0/T1中断 TR0 = 1;TR1 = 1;//启动T0/T1 TF0 = 0;TF1 = 1; //清定时器溢出标志位 while(1) { ; } } void time0(void) interrupt 1 //1s { TH0=(65536-10000)/256; // 定时器 T0 的高 8 位赋初值 TL0=(65536-10000)%256; // 定时器 T0 的低 8 位赋初值 if(++cnt0 == 100) //若中断20次就1s { cnt0 = 0; //重新计数 second++; if(second==60) { second = 0; } } dis[3] = Tab[second/10]; dis[2] = Tab[second%10]&0x7f; dis[1] = Tab[cnt0/10]; dis[0] = Tab[cnt0%10]; } void time1(void) interrupt 3 //动态扫描每隔8ms { if(++cnt1 == 32) //若中断32次就8ms { cnt1 =0; //重新计数 if(++scan == 4)scan =0; P2 = 0xff; //关闭数码管 P1 = ~(1<<scan); P2 = dis[scan]; } }
例子005、四位数码管60s计数含两小数位(定时器1中断,使用延迟10ms动态扫描,外部中断0开始/暂停,外部中断1复位清零)
#include <reg52.h> unsigned char Tab[]={0xC0,0xF9,0xA4,0xB0,0x99,0x92, 0x82,0xF8,0x80,0x90,0x88,0x83,0xC6,0xA1,0x86,0x8E}; //共阳极8段 unsigned char count,miao;//秒的小数点后两位计数count void delay(unsigned int z) //当z=1,延迟时间10ms { unsigned char i,j,k; for(i=z;i>0;i--) for(j=4;j>0;j--) for(k=248;k>0;k--); } void main() { TMOD |= 0x10; // 将定时器1工作方式设置为模式1 TH1 = (65536-10000) / 256; // 计算定时器重装值的高8位并赋值50ms TL1 = (65536-10000) % 256; // 计算定时器重装值的低8位并赋值50ms EA = 1; // 开启全局中断 EX0=1;EX1=1; //开外部中断0/1 IT0=1;IT1=1; //外中断0/1设置边沿触发 ET1 = 1; // 开启定时器1中断 TR1 = 1; // 开启定时器1 while(1) { P2 = Tab[miao/10]; P1 = ~(1<<3); delay(1); P1 = 0xff; P2 = (Tab[miao%10])&0x7f; P1 = ~(1<<2); delay(1); P1 = 0xff; P2 = Tab[count/10]; P1 = ~(1<<1); delay(1); P1 = 0xff; P2 = Tab[count%10]; P1 = ~(1<<0); delay(1); P1 = 0xff; } } void time1() interrupt 3 { TH1 = (65536-10000) / 256; // 计算定时器重装值的高8位并赋值 TL1 = (65536-10000) % 256; // 计算定时器重装值的低8位并赋值 count++; if(count == 100) //中断进入100次就是1s { count = 0; miao++; if(miao>60)miao=0; } } void int0(void) interrupt 0 { TR1 = ~TR1; } void int1(void) interrupt 2 { miao = 0; count =0; }