单片机交流
直播中

青sky

9年用户 1284经验值
擅长:模拟技术
私信 关注
[问答]

基于51单片机的定时器定时1秒如何去实现?

基于51单片机的定时器定时1秒如何去实现?
基于51单片机的数码管切换0-F如何去实现?

回帖(1)

闫玮婧

2021-7-19 11:06:29
1、定时器定时1秒
我们先来计算定时中用的初值。先讲原理,帮助大家理解。
要定时一秒,直接一步到位,用定时器不行,因为:
16位定时器的溢出值是65536(2的16次方)
晶振11.0592MHZ(MHZ,后面乘10的6次方转化为HZ),
机器周期=1/11059200,
时钟周期=12*机器周期=12/11059200,
最多65536 X12/11059200=0.071秒,到不了1秒
所以,我们这里采用0.02秒X50=1秒的方法
初值计算:
(65536-x)*12/11059200=0.02
x=47104(十进制)=B800(十六进制)
所以,采用T0为模式1(T0十六位定时模式)
高八倍TH0=0xB8
第八位TL0=0x00


#include 《reg52.h》***it LED0 = P1^0;unsigned char cnt = 0; //定义一个计数变量,记录T0溢出的次数,单片机一次性到不了1秒,所以要倍数乘一下void main(){ TMOD = 0x01; //设置T0为模式1 TH0 = 0xB8; //高八位初值 TL0 = 0x00; //第八位初值 TR0 = 1; //启动T0定时器 while(1) { if(TF0 == 1) { TF0 = 0; //T0溢出,清除中断标志位,这里是定时程序,所以这条要加,如果是中断程序硬件自动清零,这条不用 TH0 = 0xB8; //重新赋初值,因为每次溢出后会自动清零 TL0 = 0x00; cnt++; //0.02秒加一次 if (cnt 》= 50) //0.02*50=1秒 { cnt = 0; //达到 50 次后计数值清零 LED0 = ~LED0; //LED0每隔一秒取反一次:一秒亮,一秒灭 } } }} 现象:LED0每隔一秒取反一次:一秒亮,一秒灭
2.数码管每隔一秒切换
数码管知识之前发过了,这里不重复
#include 《reg51.h》#define uint unsigned int //定义无符号整型的写法#define uchar unsigned char //定义无符号字符型的写法 ***it DU = P2^6;***it WE = P2^7;uchar code table[] = {0x3F, 0x06, 0x5B, 0x4F, 0x66,//0-40x6D, 0x7D, 0x07, 0x7F, 0x6F,//5-90x77, 0x7C, 0x39, 0x5E, 0x79,0x71//A-F};//这里用code是把它放到ROM区,节省RAM区uchar cnt = 0; //记录T0中断次数uchar sec = 0; //记录经过的秒数void main(){ WE = 1; //打开位控 P0 = 0XFE; //1111 1110 根据原理图顺序,为左边第一个数码管 WE = 0; //关闭位控 TMOD = 0x01; //设置T0为模式1 TH0 = 0xB8; //高八位初值 TL0 = 0x00; //第八位初值 TR0 = 1; //启动T0定时器 while(1) { if(TF0 == 1) { TF0 = 0; //T0溢出,清除中断标志位,这里是定时程序,所以这条要加,如果是中断程序硬件自动清零,这条不用 TH0 = 0xB8; //重新赋初值,因为每次溢出后会自动清零 TL0 = 0x00; cnt++; //0.02秒加一次 if (cnt 》= 50) //0.02*50=1秒 { cnt = 0; // 达到 50 次后计数值清零 sec++; if(sec 》 15) //当秒数超过15,重新从0开始 { sec = 0; } } } DU = 1; //打开段控 P0 = table[sec]; DU = 0; //关闭段控 }} 显示效果:0-F,这里就发个一张
举报

更多回帖

发帖
×
20
完善资料,
赚取积分