本笔记仅供学习交流
欢迎大家观看学习蓝桥杯小蜜蜂欧浩源老师的教学视频
参考放前面
【基础技能09】定时器的基本原理与应用
参考网址【新提醒】【蓝桥杯单片机08】定时器的基本原理与应用 - - 21ic电子技术开发论坛https://bbs.21ic.com/icview-2477676-1-1.html
基本原理
本质其实就是倒计时
想想一个时钟 可以手动调整指针,这个钟只会不断的往前走 走到12点就叫
我们想实现15分钟计时 是不是需要把分针拨到9的位置上?对吧 然后ta走15分钟到12点 直接开叫
定时器也是这个原理
先看看定时器相关寄存器
举个例子 如果我们想每过50ms count就加1 应该怎么操作呢
首先
50ms就是50000个定时器计时单位 一个计时单位是1微秒 要计时15分钟 就是60-15=45 45的位置就是9 所以我们的初值就是9 (这样就确定初值了)
我们应该初始化定时器。对应来说就是先拨弄好闹钟指针(设定定时器初值),然后再打开闹钟开关(打开定时器开关)让指针走起来,再打开响铃模式(就是打开中断开关),闹钟就可以倒计时响铃了。(先开响铃模式还是闹钟开关不影响)
具体代码如下
void init_t0(){//初始化定时器函数
TMOD=0x01;//设置定时器模式 这个是16位定时器 手动装载初值
TH0=(65536-50000)/256;//设置初值 转换成16进制 存放高位
TL0=(65536-50000)%256;//低位
ET0=1;//允许定时器0中断
EA=1;//总中断开关
TR0=1;//定时器!启动!!!!
}
unsigned char count=0;
void servicetimer0() interrupt 1{// 定时中断函数的标志 不可以忘记写
TH0=(65536-50000)/256;//因为不会自动装载初值 所以需要手动装载
TL0=(65536-50000)%256;
count++;
}
任务1
代码
#include "reg52.h"
#include <intrins.h>
sbit l1=P0^0;
sbit l8=P0^7;
void selecthc573(channel){//锁存器
switch(channel){
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;
}
}
void init_t0(){//初始化定时器
TMOD=0x01;//打开定时器
TH0=(65536-50000)/256;//设置初值
TL0=(65536-50000)%256;
ET0=1;//打开中断
EA=1;
TR0=1;
}
unsigned char count=0;
void servicetimer0() interrupt 1{
TH0=(65536-50000)/256;//因为不会自动装载初值 所以需要手动装载
TL0=(65536-50000)%256;
count++;
if(count%10==0){
l1=~l1;
}
if(count==100){
l8=~l8;
count=0;
}
}
void main(){
selecthc573(4);//打开LED
init_t0();//初始化定时器
while(1){
//什么也不用写 会触发定时器中断的
}
}
任务2
代码
#include "reg52.h"
#include <intrins.h>
unsigned char code smg_duanma[18]={
0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,
0x80,0x90,0x88,0x80,0xc6,0xc0,0x86,0x8e,
0xbf,0x7f};
sbit s4=P3^3;
sbit s5=P3^2;
unsigned char tms_5=0;
unsigned char t_sec=0;
unsigned char t_min=0;
void selecthc573(unsigned char channel){
switch (channel){
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;
}
}
void display_smg(unsigned char value,unsigned char pos){
selecthc573(6);
P0=0x01<<pos;//选择数码管
selecthc573(7);
P0=value;//输入相应的数值
}
void delay() //@11.0592MHz
{
unsigned char data i, j;
_nop_();
i = 2;
j = 15;
do
{
while (--j);
} while (--i);
}
void delay_k() //@11.0592MHz
{
unsigned char data i, j;
i = 180;
j = 73;
do
{
while (--j);
} while (--i);
}
void init_t0(){
TMOD=0x01;
TH0=(65535-50000)/256;
TL0=(65535-50000)%256;
ET0=1;
EA=1;
TR0=1;
}
void timer_ser() interrupt 1{
TH0=(65535-50000)/256;
TL0=(65535-50000)%256;
tms_5++;
if(tms_5==20){
t_sec++;
tms_5=0;
if(t_sec==60){
t_min++;
t_sec=0;
if(t_min==100){
t_min=0;
}
}
}
}
void keyscan(){
if(s4==0){//秒表启动与暂停
delay_k();
if(s4==0){
TR0=~TR0;
}
}
if(s5==0){//秒表清零
delay_k();
if(s5==0){
tms_5=0;
t_sec=0;
t_min=0;
}
}
}
void time_show(){
display_smg(smg_duanma[tms_5%10],7);
delay();
display_smg(smg_duanma[tms_5/10],6);
delay();
display_smg(smg_duanma[16],5);
delay();
display_smg(smg_duanma[t_sec%10],4);
delay();
display_smg(smg_duanma[t_sec/10],3);
delay();
display_smg(smg_duanma[16],2);
delay();
display_smg(smg_duanma[t_min%10],1);
delay();
display_smg(smg_duanma[t_min/10],0);
delay();
}
void main(){
init_t0();
selecthc573(4);
P0=0xff;
while(1){
time_show();
keyscan();
}
}
结果
任务1
忘记拍了。。。不好意思
任务2
定时器综合功能演示
我这个按键消抖做的不是很好 ,但是我更换了好几次的延时时间长度,还是不行。。。无奈
我会接着更新的!!!加油!!