专注电子技术学习与研究
当前位置:单片机教程网 >> MCU设计实例 >> 浏览文章

24小时单片机时钟终于搞定了

作者:余春雨老师   来源:本站原创   点击数:  更新时间:2014年04月26日   【字体:

此程序的电路图下载:http://www.51hei.com/f/ks51.pdf   只需要看数码管部分即可,其他部分可忽略掉. 

 
#include <reg52.h> //stc89c51单片机头文件
 
 
typedef unsigned char uchar;
typedef unsigned int uint;
typedef unsigned long ulong; //变量类型宏定义
 
 
sbit ENLED = P1^4;
sbit ADDR0 = P1^0;//管脚定义,作用为使能74hc138,让38译码器开始工作
sbit ADDR1 = P1^1;
sbit ADDR2 = P1^2;
sbit ADDR3 = P1^3; //管脚定义,作用为选定38译码器输出Y0-Y7,以便选定要显示的数码管(位选择)
 
 
uchar led_char[] = {
0xC0, 0xF9, 0xA4, 0xB0,
0x99, 0x92, 0x82, 0xF8,
0x80, 0x90, 0x88, 0x83,
0xC6, 0xA1, 0x86, 0x8E}; //数码管字符真值表 0-F
 
 
uchar led_buf[] = {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF}; //数码管字符初始化,为关闭状态
 
 
uchar cnt = 0; //T1定时器溢出计数
uchar key = 0; //数码管动态扫描开关
ulong sec = 0; //时间变量 
uchar hh = 8; //小时初值
uchar mm = 30; //分钟初值
uchar ss = 40; //秒数初值
 
 
void main()
{
sec = hh *3600 + mm * 60 + ss;//时间计算公式
EA = 1; //打开中断开关
 
 
ENLED = 0;
ADDR3 = 1; //使能74hc138,让38译码器开始工作
 
 
TMOD = 0x10;//定时器工作模式设定
TH1 = 0xEE;
TL1 = 0x00;//定时初值设置
 
 
ET1 = 1; //打开定时器1中断开关
TR1 = 1; //定时器1开始计时
 
 
while(1)
{
if(200 == cnt)
{
cnt = 0;
sec++;
if(sec < 86400)
{
led_buf[0] = led_char[sec%10];
led_buf[1] = led_char[sec%60/10];
led_buf[2] = led_char[sec%3600/60%10];
led_buf[3] = led_char[sec%3600/600];
led_buf[4] = led_char[sec/3600%10];
led_buf[5] = led_char[sec/3600/10]; //时间显示字符计算
}
    if(sec == 86400)
{
sec = 0;
}
}
}
 
 
 
 
}
void interruptTimer0() interrupt 3 //定时器1中断服务程序
{
  TH1 = 0xEE;
TL1 = 0x00; //定时初值设置
cnt++;
 
 
P0 = 0xFF; //数码管消除鬼影
 
 
switch(key)
{
case 0: ADDR2 = 0;ADDR1 = 0;ADDR0 = 0;P0 = led_buf[0];key++;break;
case 1: ADDR2 = 0;ADDR1 = 0;ADDR0 = 1;P0 = led_buf[1];key++;break;
case 2: ADDR2 = 0;ADDR1 = 1;ADDR0 = 0;P0 = led_buf[2];key++;break;
case 3: ADDR2 = 0;ADDR1 = 1;ADDR0 = 1;P0 = led_buf[3];key++;break;
case 4: ADDR2 = 1;ADDR1 = 0;ADDR0 = 0;P0 = led_buf[4];key++;break;
case 5: ADDR2 = 1;ADDR1 = 0;ADDR0 = 1;P0 = led_buf[5];key = 0;break;
default:break;
} //数码管动态扫描、显示时间值
}
关闭窗口

相关文章