单片机时钟程序.docx
- 文档编号:6082168
- 上传时间:2023-01-03
- 格式:DOCX
- 页数:14
- 大小:19.91KB
单片机时钟程序.docx
《单片机时钟程序.docx》由会员分享,可在线阅读,更多相关《单片机时钟程序.docx(14页珍藏版)》请在冰豆网上搜索。
单片机时钟程序
c51单片机晶振为
#include<>
#defineHOUR11
#defineHOUR00
#defineMIN12
#defineMIN08
#defineSEC12
#defineSEC00
#defineuintunsignedint
#defineulintunsignedlongint
#defineucharunsignedchar
sbitdula=P2^6;
sbitwela=P2^7;
sbitbeep=P2^3;
inti;
ulintsharp,second,count=0,sec0=SEC0,sec1=SEC1,min0=MIN0,min1=MIN1,hour0=HOUR0,hour1=HOUR1;//秒计数全局变量
ucharcodesegment[]={0xfe,0xfd,0xfb,0xf7,0xef,0xdf};
ucharcodetime[]={
0x3f,0x06,0x5b,0x4f,
0x66,0x6d,0x7d,0x07,
0x7f,0x6f};
voiddelay(uint);//程序毫秒延时
voidbeeper(uchar);//开蜂鸣器毫秒
voidinit();//初始化函数
voiddisplay();//从数码管上显示
voidcounter();//计算进行进程中的时、分、秒值
voidscan();//扫描键盘
voidmain()
{
init();
while
(1)
{
scan();//扫描键盘看是不是有键按下
for(i=6;i>0;i--)//动态扫描6位数码管
{
display();//显示时、分、秒
}
}
}
voidinit()
{
second=hour1*36000+hour0*3600+min1*600+min0*60+sec1*10+sec0;
TMOD=0x01;
TH0=(65536-46080)/256;
TL0=(65536-46080)%256;
EA=1;
ET0=1;
TR0=1;
}
voiddelay(uintz)//程序毫秒延时
{
uintx=0,y=0;
for(x=z;x>0;x--)
for(y=110;y>0;y--);
}
voidtimer0()interrupt1
{
TH0=(65536-46080)/256;
TL0=(65536-46080)%256;
count++;
if(count==20)//判定是不是到1秒
{
counter();//计算进行进程中的时、分、秒值
if(sharp!
=hour0)beeper(1000);//判定小时的值是不是改变,变那么启动蜂鸣器
}
}
voidbeeper(uchartt)
{
uchart=tt;
count=0;
beep=0;//开蜂鸣器
delay(t);
beep=1;//关蜂鸣器
}
voiddisplay()
{
P0=0xff;//位消影(低电平选择位)
//送位选信号
wela=1;
P0=segment[i-1];
wela=0;
P0=0x00;//段消影(高电平选择段)
//送段选信号
dula=1;
switch(i)
{
case6:
P0=time[sec0];break;
case5:
P0=time[sec1];break;
case4:
P0=time[min0];break;
case3:
P0=time[min1];break;
case2:
P0=time[hour0];break;
case1:
P0=time[hour1];break;
}
delay
(1);
P0=0x00;//配合上面用于消隐
dula=0;
}
voidcounter()
{
second++;
if(second==86400)second=0;
count=0;
sharp=hour0;//设置报时检测KEY
sec0=second%10;
sec1=(second%60-sec0)/10;
min0=((second%3600-sec1*10-sec0)/60)%10;
min1=((second%3600-sec1*10-sec0)/60-min0)/10;
hour0=(second%36000-min1*600-min0*60-sec1*10-sec0)/3600;
hour1=second/36000;
}
voidscan()
{
}
参考资料:
我写的,在实验板上调试成功,有问题加我,一路学习学习…………
/*小时调整分种调整*/
#include<>#include<>
unsignedchardatadis_digit;unsignedcharkey_s,key_v;
unsignedcharcodedis_code[11]={0xc0,0xf9,0xa4,0xb0,//0,1,2,30x99,0x92,0x82,0xf8,0x80,0x90,0xff};//4,5,6,7,8,9,offunsignedchardatadis_buf[8];unsignedchardatadis_index;unsignedcharhour,min,sec;unsignedcharsec100;
sbitK1=P1^0;sbitK2=P1^1;
bitscan_key();voidproc_key();voidinc_sec();voidinc_min();voidinc_hour();voiddisplay();voiddelayms(unsignedcharms);
voidmain(void){P0=0xff;P2=0xff;TMOD=0x11;//定时器0,1工作模式1,16位定时方式TH1=0xdc;TL1=0;
TH0=0xFC;TL0=0x17;hour=12;min=00;sec=00;
sec100=0;dis_buf[0]=dis_code[hour/10];//时十位dis_buf[1]=dis_code[hour%10];//时个位dis_buf[3]=dis_code[min/10];//分十位dis_buf[4]=dis_code[min%10];//分个位dis_buf[6]=dis_code[sec/10];//秒十位dis_buf[7]=dis_code[sec%10];//秒个位dis_buf[2]=0xbf;//显示"-"dis_buf[5]=0xbf;//显示"-"dis_digit=0xfe;dis_index=0;TCON=0x01;IE=0x8a;//使能timer0,1中断TR0=1;TR1=1;
key_v=0x03;
while
(1){if(scan_key()){delayms(10);if(scan_key()){key_v=key_s;proc_key();}}}}
bitscan_key(){key_s=0x00;key_s|=K2;key_s<<=1;key_s|=K1;return(key_s^key_v);}
voidproc_key(){EA=0;if((key_v&0x01)==0)//K1{inc_hour();}elseif((key_v&0x02)==0)//K2{min++;if(min>59){min=0;}dis_buf[3]=dis_code[min/10];//分十位dis_buf[4]=dis_code[min%10];//分个位}
EA=1;}
voidtimer0()interrupt1//定时器0中断服务程序,用于数码管的动态扫描//dis_index---显示索引,用于标识当前显示的数码管和缓冲区的偏移量//dis_digit---位选通值,传送到P2口用于选通当前数码管的数值,如等于0xfe时,//选通口数码管//dis_buf---显于缓冲区基地址{TH0=0xFC;TL0=0x17;P2=0xff;//先关闭所有数码管P0=dis_buf[dis_index];//显示代码传送到P0口P2=dis_digit;//
dis_digit=_crol_(dis_digit,1);//位选通值左移,下次中断时选通下一名数码管dis_index++;//dis_index&=0x07;//8个数码管全部扫描完一遍之后,再回到第一个开始下一次扫描}
voidtimer1()interrupt3{TH1=0xdc;sec100++;if(sec100>=100){sec100=0;inc_sec();}}
voidinc_sec(){sec++;if(sec>59){sec=0;inc_min();}dis_buf[6]=dis_code[sec/10];//秒十位dis_buf[7]=dis_code[sec%10];//秒个位}
voidinc_min(){min++;if(min>59){min=0;inc_hour();}dis_buf[3]=dis_code[min/10];//分十位dis_buf[4]=dis_code[min%10];//分个位}
voidinc_hour(){hour++;if(hour>23){hour=0;}if(hour>9)dis_buf[0]=dis_code[hour/10];//时十位elsedis_buf[0]=0xff;//当小时的十位为0时不显示dis_buf[1]=dis_code[hour%10];//时个位
}
voiddelayms(unsignedcharms)//延时子程序{unsignedchari;while(ms--){for(i=0;i<120;i++);}}
//P0:
LED数码管显示内容通过P1口从单片机传送到数码管//-:
数码管位选控制端口//-:
分别连接开关K0,K1,K2,K3通过不同的组合实现外部控制程序状态//:
蜂鸣器,倒计时完毕产生鸣响//-:
发光二极管,显示当前时钟状态//完整的源程序如下:
//附程序源代码及注释#include<>#include<>#define uintunsignedint#define ucharunsignedchar/*定义P2口各管脚*/sbitK0=P2^2;//按键定义sbitK1=P2^1;//按键定义sbitK2=P2^0;//按键定义sbitK3=P2^3;//按键定义sbitD0=P1^5;//位选定义sbitD1=P1^4;//位选定义sbitD2=P1^3;//位选定义sbitD3=P1^2;//位选定义/*定义P1口各管脚*/sbitbeep=P1^0; //蜂鸣器sbitL0=P1^1; //状态指示定义sbitL1=P1^6; //状态指示定义sbitL2=P1^7; //状态指示定义
uchardataBUFFER[4]={0,0,0,0}; //显示缓冲区(依次从低位到高位,共四位数码管)uchardataCLOCK[4]={0,0,0,0}; //存放时钟时间(依次是百分秒,秒,分,时)uchardataSECOND[3]={0,0,0}; //存放秒表时间(依次时百分秒,秒,分)uchardataSEVER[4]={0,0,0,0}; //存放倒计时时间(依次是百分秒,秒,分,时)/*定义程序运行状态*/uchardataSTATE=0;/*STATE=0;时钟运行*//*STATE=1;时钟分调整*//*STATE=2;未定义状态,可添加*//*STATE=3;时钟时调整*//*STATE=4;倒计时分调整*//*STATE=5;倒计时时调整*//*STATE=6;秒表*//*STATE=7;倒计时运行*//*定义辅助计时全局变量*/ucharm=60;/*共阳数码管显示"0-9"和"-"*/ucharcodeTABLE[]={0x10,0xba,0x48,0x44,0x86,0x24,0x20,0x56,0x00,0x04,0xef};/*自定义子函数*/voiddisplay(); //显示函数voiddelay(); //显示延时函数voidintsvr(); //调整时间时加1子函数voiddelay10ms(); //延时函数/*主函数体*/voidmain(void){ EA=1;ET0=1; //开总中断源,开T0中断 TMOD=0x61; //T1方式2计数,T0方式1计时 TH0=-9460/256;TL0=-9460%256; //初始化计数器初值 TH1=0xff;TL1=0xff; T2CON=0;TH2=-9452/256;TL2=-9452%256; K0=1;K1=1;K2=1; //初始化控制状态位 STATE=P2&0x07; for(;;) { switch(STATE) { case1:
//时钟分调整程序 { TR0=0;ET0=0;EX0=0;TR2=0;//关闭定时器,时钟停止运行,同时关闭外中断IT0 L1=0;L2=0;L0=1; intsvr(); //调用加1函数 BUFFER[0]=CLOCK[2]%10; //数码管显示分钟个位 BUFFER[1]=CLOCK[2]/10; //数码管显示分钟十位 BUFFER[2]=10; //显示"-" BUFFER[3]=10; //显示"-" }break; case3:
//时钟时调整程序 { TR0=0;ET0=0;EX0=0;TR2=0;//关闭定时器,时钟停止运行 L1=0;L2=0;L0=1; intsvr(); //调用加1函数 BUFFER[0]=CLOCK[2]%10; //数码管显示分钟个位 BUFFER[1]=CLOCK[2]/10; //数码管显示分钟十位 BUFFER[2]=CLOCK[3]%10; //数码管显示时钟个位 BUFFER[3]=CLOCK[3]/10; //数码管显示时钟十位 }break; case4:
//倒计时分钟调整程序 { TR0=1;ET0=1;EX0=0;TR2=0;//保持T0正常运行,即时钟正常运行,同时关闭外中断IT0 L2=0;L1=0; intsvr(); //调用加1函数 BUFFER[0]=SEVER[2]%10; //数码管显示分钟个位 BUFFER[1]=SEVER[2]/10; //数码管显示分钟十位 BUFFER[2]=10; //显示"-" BUFFER[3]=10; //显示"-" SECOND[1]=0; //秒表初始化为0 SECOND[2]=0; }break; case5:
//倒计时时钟调整程序 { TR0=1;ET0=1;EX0=0;TR2=0;//保持T0正常运行,即时钟正常运行,同时关闭外中断IT0 L2=0;L1=0; intsvr(); //调用加1子函数 BUFFER[0]=SEVER[2]%10; //数码管显示分钟个位 BUFFER[1]=SEVER[2]/10; //数码管显示分钟十位 BUFFER[2]=SEVER[3]%10; //数码管显示时钟个位 BUFFER[3]=SEVER[3]/10; //数码管显示时钟十位 SECOND[1]=0; //秒表初始化为0 SECOND[2]=0; }break; case6:
{ TR0=1;ET0=1;EX0=1;ET2=1;//保持T0正常运行,即时钟正常运行,同时开外中断IT0 BUFFER[0]=SECOND[1]%10;//数码管显示秒表秒个位 BUFFER[1]=SECOND[1]/10;//数码管显示秒表秒十位 BUFFER[2]=SECOND[2]%10;//数码管显示秒表分个位 BUFFER[3]=SECOND[2]/10;//数码管显示秒表分十位 }break; case7:
{ TR0=1;ET0=1;EX0=0;ET2=1; //倒计时运行,同时时钟也正常运行,关闭外中断T0 if((SEVER[2]==0)&&(SEVER[3]==0)) //当预置时间(分,时)变为0时,计时完毕 { beep=!
beep; //蜂鸣器响 BUFFER[0]=10; //显示"-" BUFFER[1]=10; BUFFER[2]=10; BUFFER[3]=10; TR2=0; //关闭T2 } else { TR2=1; //开启T2 } SECOND[1]=0; //秒表时间初始化 SECOND[2]=0; }break; default:
{ ET0=1;TR0=1;EX0=0; //开启T0,时钟运行,关闭外中断 L1=1;L2=1;//L3=1; BUFFER[0]=CLOCK[2]%10; //数码管显示分钟个位 BUFFER[1]=CLOCK[2]/10; //数码管显示分钟十位 BUFFER[2]=CLOCK[3]%10; //数码管显示时钟个位 BUFFER[3]=CLOCK[3]/10; //数码管显示时钟十位 } } K0=1;K1=1;K2=1; //重新预置状态位 display(); //调用显示函数 STATE=P2&0x07; //通过P2口提取当前状态 }}/*T0中断服务*/voidtime0(void) interrupt1using1 //T0中断函数{ T
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 单片机 时钟 程序
![提示](https://static.bdocx.com/images/bang_tan.gif)