51单片机基础(C语言):定时器时钟
1.使用定时器 1 和LCD1602设计一个简易数字时钟。
main.c
#include <REGX52.H>
#include "Delay.h"
#include "LCD1602.h"
#include "Timer0.h"
unsigned char Sec=55,Min=59,Hour=23;
void main()
{
LCD_Init();
Timer0Init();
LCD_ShowString(1,1,"Clock:"); //上电显示静态字符串
LCD_ShowString(2,1," : :");
while(1)
{
LCD_ShowNum(2,1,Hour,2); //显示时分秒
LCD_ShowNum(2,4,Min,2);
LCD_ShowNum(2,7,Sec,2);
}
}
void Timer0_Routine() interrupt 1
{
static unsigned int T0Count;
TL0 = 0x18; //设置定时初值
TH0 = 0xFC; //设置定时初值
T0Count++;
if(T0Count>=1000) //定时器分频,1s
{
T0Count=0;
Sec++; //1秒到,Sec自增
if(Sec>=60)
{
Sec=0; //60秒到,Sec清0,Min自增
Min++;
if(Min>=60)
{
Min=0; //60分钟到,Min清0,Hour自增
Hour++;
if(Hour>=24)
{
Hour=0; //24小时到,Hour清0
}
}
}
}
}
Timer0.c
#include <REGX52.H>
/**
* @brief 定时器0初始化,1毫秒@12.000MHz
* @param 无
* @retval 无
*/
void Timer0Init(void)
{
TMOD &= 0xF0; //设置定时器模式
TMOD |= 0x01; //设置定时器模式
TL0 = 0x18; //设置定时初值
TH0 = 0xFC; //设置定时初值
TF0 = 0; //清除TF0标志
TR0 = 1; //定时器0开始计时
ET0=1;
EA=1;
PT0=0;
}
/*定时器中断函数模板
void Timer0_Routine() interrupt 1
{
static unsigned int T0Count;
TL0 = 0x18; //设置定时初值
TH0 = 0xFC; //设置定时初值
T0Count++;
if(T0Count>=1000)
{
T0Count=0;
}
}
*/
Timer0.h
#ifndef __TIMER0_H__
#define __TIMER0_H__
void Timer0Init(void);
#endif
2. 使用定时器 0 和数码管设计一个数字时钟。
1.动态数码管显示,点亮一瞬间,显示00—00—00
2.定时器中断,每隔一秒秒钟加一,过六十,分钟加一,到达24:00:00,变为00:00:00
比如 00—00—01 00—01—00
3.完成以上两个任务,就完成了与第一个题一样的效果了,
现在加入第三个模块,独立按键模块,我们规定如下:
1.独立按键一:按下按键,暂停,再按下,启动,(刚开始是暂停的)
2.独立按键二:暂停情况,修改时钟个位,个位加一,个位加到10,十位进一,加到24,变为0;
3.独立按键三:暂停情况,修改分钟个位,个位加一,个位加到10,十位进一,加到60,都变0;
4.独立按键四:暂停情况,修改秒钟个位,个位加一,个位加到10,十位进一,加到60,变为0;
下面为现象:
定时器时钟仿真
代码如下:模块化编程,一共用了4个模块,在我模块化编程大全里面有,直接调用即可,分别是
延迟模块,独立按键模块,定时器中断模块,动态数码管模块。
这里我们写main.c的代码:
#include <reg52.h>
#include "Nixie.h"
#include "Timer0.h"
#include "Key.h"
#define uint unsigned int
#define uchar unsigned char
uchar keynumber,Mode;
uint hour_ge=0,hour_shi=0,minute_ge=0, minute_shi=0,second_ge,second_shi;//6个数码管刚好对应每一位
void main()
{
Timer0Init();
while(1)
{
keynumber= Key();
if(keynumber)
{
if(keynumber==1)
{
Mode++;
if(Mode>=2)
{
Mode=0;
}
}
if(keynumber==2)
{
if(Mode==0)
{
hour_ge++;
if(hour_ge>=10)
{
hour_ge=0;
hour_shi++;
}
if(hour_shi==2&&hour_ge==4)
{
hour_shi=0;
hour_ge=0;
}
}
}
if(keynumber==3)
{
if(Mode==0)
{
minute_ge++;
if(minute_ge>=10)
{
minute_ge=0;
minute_shi++;
}
if(minute_shi==6&&minute_ge==0)
{
minute_shi=0;
minute_ge=0;
}
}
}
if(keynumber==4)
{
if(Mode==0)
{
second_ge++;
if(second_ge>=10)
{
second_ge=0;
second_shi++;
}
if(second_shi==6&&second_ge==0)
{
second_shi=0;
second_ge=0;
}
}
}
}
Nixie(1,hour_shi);
Nixie(2,hour_ge);
Nixie(3,10);
Nixie(4,minute_shi);
Nixie(5,minute_ge);
Nixie(6,10);
Nixie(7,second_shi);
Nixie(8,second_ge);
}
}
void Timer0_Routine() interrupt 1
{
static unsigned int T0Count;
TL0 = 0x18; //设置定时初值
TH0 = 0xFC; //设置定时初值
T0Count++;
if(T0Count>=100) //定时器分频,1s
{
T0Count=0;
if(Mode==1)
{
second_ge++; //1秒到,second_ge自增
if(second_ge>=10)
{
second_ge=0; //10秒到,second_ge清0,second_shi自增
second_shi++;;
if(second_shi==6)
{
second_shi=0; //60秒钟到,second_shi清0,minute_ge自增
minute_ge++;
if(minute_ge==10)
{
minute_ge=0;
minute_shi++;
if(minute_shi==6)
{
minute_shi=0;
hour_ge++;
if(hour_ge==10)
{
hour_ge=0;
hour_shi++;
}
if(hour_shi==2&&hour_ge==4)
{
hour_shi=0;
hour_ge=0;
}
}
}
}
}
}
}
}