单片机控制多位数码管的电子时钟程序

2025-10-19 07:17:23

1、软件编程:

keil工程C语言代码:

2、/***************************************

项目名称:数码管电子时钟

实现功能:数码管显示时间、日期,时间、日

期可调,可设置闹钟,闹铃响一分钟。

****************************************/

#include <reg52.h>

#define uint unsigned int

#define uchar unsigned char

uint numwe,tt,t,numdu,set,aclock,rili;

unsigned long int time,time1=0;

unsigned long int second,minute,hour,year=2012,month=12,day=31;

uchar code du[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,

    0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71};

uchar code we[]={0xfe,0xfd,0xfb,0xf7,0xef,0xdf,0xbf,0x7f};

uchar  Mth[13]={0,31,28,31,30,31,30,31,31,30,31,30,31};//每月对应的天数

uchar  YMth[13]={0,2,9,2,1,2,1,2,2,1,2,1,2};

sbit dula=P2^0;

sbit wela=P2^1;

sbit KEY0=P3^2;//选位

sbit KEY1=P3^1;//加一

sbit KEY2=P3^0;//设闹铃

sbit KEY3=P3^3;

sbit beep=P2^2;//响铃

void Delay(uint del);//延时程序

void Display(uint sd,uint mm,uint hy);//显示程序

void add();//加一

void alarmclock();//闹钟

void init();//初始化

int clock();//计算时间

void Calender();//计算日期

void main()

{

P2=0xff;

init();

while(1){

add();

if(rili==1)//分日历和时间显示

Display(day,month,year);

else

Display(second,minute,hour);

alarmclock();

}

}

void Display(uint sd,uint mm,uint hy)

{ int y0,y1,y2;

if(rili==1)

{

y0=hy/1000,y1=hy%1000;y2=hy%100;

}

for(numwe=0;numwe<8;numwe++)

{

P0=0xff;

wela=1;

P0=we[numwe];

wela=0;

P0=0xff;

dula=1;

switch(numwe)

{

case 0:

P0=(tt==1&set==1)?0x00:(rili==1)?du[y0]:du[hy/10];break;

case 1:

P0=(tt==1&set==2)?0x00:(rili==1)?du[y1/100]:du[hy%10];break;

case 2:

P0=(rili!=1)?0x40:(tt==1&set==3)?0x00:du[y2/10];break;

case 3:

P0=(tt==1&set==4)?0x00:(rili==1)?du[hy%10]+0x80:du[mm/10];break;

case 4:

P0=(tt==1&set==5)?0x00:(rili==1)?du[mm/10]:du[mm%10];break;

case 5:

P0=(rili!=1)?0x40:(tt==1&set==6)?0x00:du[mm%10]+0x80;break;

case 6:

P0=(tt==1&set==7)?0x00:du[sd/10];break;

case 7:

P0=(tt==1&set==8)?0x00:du[sd%10];break;

}

dula=0;

Delay(5);

}

}

void init()//初始化

{

wela=0;

dula=0;

TMOD=0x01;//设置定时器0为工作方式1

TH0=(65536-50000)/256;//定时器高八位//定时5ms

TL0=(65536-50000)%256;//定时器低八位

IE=0x8f;//开启中断

TCON=0x15;//启动定时器及工作方式

}

int clock()//计算时间

{

if(t==10|t==20) tt=!tt;//闪烁标志位

if(t==20)

{

t=0;

if(!(set!=0&aclock==0))

time++;

if(time>=time1&time<time1+60)

beep=0;

else

beep=1;

Calender();

if(aclock==0)

{

second=time%60;

minute=(time%3600)/60;

hour=time/3600;

if(hour==24)

{

time=0;

hour=0;

}

}

else

{

second=time1%60;

minute=(time1%3600)/60;

hour=time1/3600;

if(hour==24)

{

time=0;

hour=0;

}

}

}

}

void Delay(uint del)

{

uint i,j;

for(i=0; i<del; i++)

for(j=0; j<100; j++);

}

void timer0() interrupt 1//定时器0中断

{

TH0=(65536-50000)/256;//定时器高八位//定时5ms

TL0=(65536-50000)%256;//定时器低八位

t++;

clock();

}

void  settime() interrupt 0//it0

{

if(KEY0==0)

{

Delay(2);

if(KEY0==0)

{ if(rili!=1)

{if(set==2|set==5) set=set+2; else set++;}

else

set++;

if(set==9)

{set=0;t=0;}

//while(!KEY0);

}

}

}

void calendar() interrupt 2//日历

{

if(KEY3==0)

{   

Delay(2);

if(KEY3==0)

rili=!rili;

set=0;aclock=0;

}

}

void Calender()//计算日历

{

if(time==86400)

{

day++;

if((year%4==0&year%100!=0)|(year%400==0)) 

Mth[2]=29;

else

Mth[2]=28;

if(day>Mth[month])

{

day=1;

month++;

if(month>12)

{month=1;

year++;}

}

}

}

void add()//自加一

{

int ge,ge1,ge2,shi,shi1,shi2,bai2,qian2;

if(rili==1)

{

ge=day%10;ge1=month%10;ge2=year%10;

shi=day/10;shi1=month/10;shi2=year%100/10;

bai2=year%1000/100;qian2=year/1000;

}else

{

ge=second%10;ge1=minute%10;ge2=hour%10;

shi=second/10;shi1=minute/10;shi2=hour/10;

}

if(KEY1==0)

{

Delay(2);

if(KEY1==0)

{

if(rili==1)

{

if((year%4==0&year%100!=0)|(year%400==0)) 

YMth[2]=10;

else

YMth[2]=9;

switch(set)

{

case 1:qian2=(qian2+1)%10;break;

case 2:bai2=(bai2+1)%10;break;

case 3:shi2=(shi2+1)%10;break;

case 4:ge2=(ge2+1)%10;break;

case 5:shi1=(shi1+1)%2;break;

case 6:ge1=(shi1==1)?(ge1+1)%3:(ge1+1)%10;break;

case 7:shi=(month==2)?(shi+1)%3:(shi+1)%4;break;

case 8:ge=(shi==3)?(ge+1)%YMth[month]:(month==2)?(ge+1)%YMth[2]:(ge+1)%10;break;

}

year=qian2*1000+bai2*100+shi2*10+ge2;

month=shi1*10+ge1;

day=shi*10+ge;

}else

{

switch(set)

{

case 1: shi2=(shi2+1)%3;break;

case 2: ge2=(ge2+1)%4;break;

case 4: shi1=(shi1+1)%6;break;

case 5: ge1=(ge1+1)%10;break;

case 7: shi=(shi+1)%6;break;

case 8: ge=(ge+1)%10;break;

}

second=shi*10+ge; minute=shi1*10+ge1;hour=shi2*10+ge2;

if(aclock==0)

time=hour*3600+minute*60+second;

else

time1=hour*3600+minute*60+second;

}

while(!KEY1);

}

}

}

void alarmclock()//设置闹铃

{

if(KEY2==0)

{

Delay(2);

if(KEY2==0)

{

while(!KEY2);

aclock=1;

rili=0;

set=0;

while(1)

{

if(rili==1)

Display(day,month,year);

else

Display(second,minute,hour);

add();

if(KEY2==0)

{

while(!KEY2);

aclock=0;

set=0;

   break;

}

}

}

}

}

3、引脚连接说明:

1、PO口接8为共阴数码管;

2、P2^0与P2^1分别为数码管的段锁存与位锁存;

3、P3^0为闹钟显示功能按键

  P3^1为设置时钟时的数字调整,单向增大

  P3^2为设置键,可对闹钟,日期,时间选择进行设置

  P3^3为日立与时间的转换查看键

4、闹钟可选用led灯或者蜂鸣器,默认提醒时长为1分钟

4、软件仿真与实验效果:

单片机控制多位数码管的电子时钟程序

单片机控制多位数码管的电子时钟程序

声明:本网站引用、摘录或转载内容仅供网站访问者交流或参考,不代表本站立场,如存在版权或非法内容,请联系站长删除,联系邮箱:site.kefu@qq.com。
猜你喜欢