单片机c 语言编程时钟及闹钟程序.docx
《单片机c 语言编程时钟及闹钟程序.docx》由会员分享,可在线阅读,更多相关《单片机c 语言编程时钟及闹钟程序.docx(13页珍藏版)》请在冰点文库上搜索。
单片机c语言编程时钟及闹钟程序
一·功能
1、计时功能,数码管显示数值从00:
00:
00--23:
59:
59循环替换,且周期时间与实际时间吻合。
2、定时闹钟功能,按下“定时”键后,可以设定所需要的任意时间,定时完成后,当到达设定时间后,蜂鸣器发声。
3、调整时间功能,根据此项功能可将时钟调至正确的时间。
4、查看定时功能,当设定完成后可以查看上次定时的时间,且能在此基础上进行重新定时。
二·按键说明
设定键:
按一次开始设定时间,并将设定过程显示在数码管上。
若未按此键,则其他按键无效。
设定过程中,再按一次此键,定时结束,数码管显示返回时钟。
当第一次按下设定键时,显示值为00:
00:
00,在此基础上调节定时时间。
第一次设定完成后,以后再按设定键,显示初值则为上次定时的时间。
确定键:
在定时过程中按下此键,则保留当前设定的时间为定时时间。
若定时过程未按此键,定时无效。
向上键:
按下此键,使得当前设定值在现有数值上加一,当加至满位时,当前值变为零。
向下键:
按下此键,使得当前设定值在现有数值上减一,当减至零时,当前值变为满位减一。
向左键:
按下此键,使得设定值移向左边一位,若已经在最左边,则移至最右边。
向右键:
按下此键,使得设定值移向右边一位,若已经在最右边,则移至最左边。
三·具体操作演示
(一)·定时及查看定时演示
1.仿真开始。
如图:
2、按键如图:
3、按下设定键,开始设定时间,如图:
4、如图所示,当前设定时位。
按向上键,使数值加一。
5、按下向右键,设定位移至分位。
6、按下向下键,使数字减一。
7、按确定键,确定当前设定的时间。
再按设定键,退出定时,开始时钟显示。
8、设定完成后按设定键,显示前次设定值,可在此基础上重新设定,也可直接再按设定键推出。
9、当时钟运行到设定时间时,蜂鸣器发声。
(二)·调整时间演示
1、计时开始。
2、按照定时的方法开始设定时间,使其显示20:
10:
09。
3、调整到正确时间后,按下确定键不放,同时再按一下设定键,将目前设定值送入时钟,使其开始从设定值计时。
放开确定键,再点设定键退出设定,则显示目前时钟指示值。
四·程序原文
#include
unsignedcharsec,min,hou,_sec=30,_min=00,_hou=00;//定义时间参数变量
intcount=0;
unsignedcharcodeSEG_TAB_A[20]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90,
0x40,0x79,0x24,0x30,0x19,0x12,0x02,0x78,0x00,0x10};//0-9码码值及0.-9.码值
sbitDAT=P2^7;//数据线连接的是P2.7
sbitPL=P2^6;//锁存线连接的是P2.6
sbitCLK=P2^5;//移位时钟连接的是P2.5
sbitBP=P2^4;//数据线连接的是蜂鸣器
sbitMA=P2^0;
sbitMB=P2^1;
sbitMC=P2^2;
unsignedcharKeyVal;//当前按键状态组合
unsignedcharpLED,i=0;
unsignedcharDispBuf[6];
charxx[3];//保存定时时间
unsignedcharn=0;
bitAB=0;
externunsignedcharKeyVal;
unsignedcharCurKey,LastKey;
unsignedcharKeyPressed;
voidInitT0(void)//计时器
{
//pLED=0;
TMOD=0x01;
TH0=0xF1;//1/240s
TL0=0x00;
TR0=1;
ET0=1;
EA=1;
}
voidclock(void)interrupt1using1//时钟计时
{
TL0=0x00;
TH0=0xf1;//1/240s
P0=0xff;
//P2=(P2&0xf8)|pLED;这样的错误在于如此赋值,改变了原来高位的值。
所以改为低位单独赋值,成功
MC=pLED/4;
MB=(pLED%4)/2;
MA=(pLED%4)%2;
P0=DispBuf[pLED];
if(++pLED==6)pLED=0;
count++;
if(count==240)//秒分时的递加
{count=0;
sec++;
if(sec==60)
{min++;
sec=0;
if(min==60)
{hou++;
min=0;
if(hou==24)
{hou=0;
}
}
}
}
if((count&0x19)==0)//每20次中断即1/12秒读一次按键状态
{
CLK=0;
PL=0;//锁存命令,发负脉冲
PL=1;
KeyVal=0;//初值数据为0,无按键
for(i=0;i<8;i++)//8次移位循环完成
{
KeyVal<<=1;//KeyVal左移位1位
if(!
DAT)KeyVal|=0x01;//有键压下,KeyVal末位置1
CLK=1;//发移位正脉冲
CLK=0;
}
KeyVal&=0x3F;//只用了6个键,所以最高两位屏蔽掉
P1=~KeyVal;
//**********************按键功能的编程*******************
LastKey=CurKey;
CurKey=KeyVal;
KeyPressed=CurKey^LastKey;
if(KeyPressed==0)return;//检测键的变化
if(CurKey==0)return;//键释放忽略
if(KeyVal==0x10)//一次5号键,定时,再按一次,定时结束
{AB=~AB;
xx[0]=_hou;
xx[1]=_min;
xx[2]=_sec;
}
if(AB==1)
{
switch(KeyVal)
{case0x00:
break;
case0x01:
KeyVal=0;
xx[n]=xx[n]+1;//+1
if(n==0)
{if(xx[n]==24)xx[n]=0;}
else
{if(xx[n]==60)xx[n]=0;}
break;
case0x02:
KeyVal=0;
n--;//左移
if(n<0)n=2;
break;
case0x04:
KeyVal=0;
n++;//右移
if(n>2)n=0;
break;
case0x08:
KeyVal=0;
xx[n]=xx[n]-1;//-1
if(n==0)
{if(xx[n]<0)xx[n]=23;}
else
{if(xx[n]<0)xx[n]=59;}
break;
case0x20:
KeyVal=0;
_hou=xx[0];//保存设定的时间
_min=xx[1];
_sec=xx[2];
BP=1;
break;
case0x30:
KeyVal=0;
hou=xx[0];//调整时钟的显示时间
min=xx[1];
sec=xx[2];
break;
default:
break;
}
}}
if((hou==_hou)&&(min==_min)&&(sec==_sec))//到达定时时间,蜂鸣器运作
{BP=0;
}
}
voidDisplayTim()//显示函数,更新显示缓冲区。
SEG-TAB-A是码表
{if(AB==1)//定时键(5)按一下,显示正设定位的小数点
{switch(n+1)
{case1:
DispBuf[0]=SEG_TAB_A[xx[0]/10+10];//显示时调节
DispBuf[1]=SEG_TAB_A[xx[0]%10+10];
DispBuf[2]=SEG_TAB_A[xx[1]/10];
DispBuf[3]=SEG_TAB_A[xx[1]%10];
DispBuf[4]=SEG_TAB_A[xx[2]/10];
DispBuf[5]=SEG_TAB_A[xx[2]%10];
break;
case2:
DispBuf[0]=SEG_TAB_A[xx[0]/10];//显示分调节
DispBuf[1]=SEG_TAB_A[xx[0]%10];
DispBuf[2]=SEG_TAB_A[xx[1]/10+10];
DispBuf[3]=SEG_TAB_A[xx[1]%10+10];
DispBuf[4]=SEG_TAB_A[xx[2]/10];
DispBuf[5]=SEG_TAB_A[xx[2]%10];
break;
case3:
DispBuf[0]=SEG_TAB_A[xx[0]/10];//显示秒调节
DispBuf[1]=SEG_TAB_A[xx[0]%10];
DispBuf[2]=SEG_TAB_A[xx[1]/10];
DispBuf[3]=SEG_TAB_A[xx[1]%10];
DispBuf[4]=SEG_TAB_A[xx[2]/10+10];
DispBuf[5]=SEG_TAB_A[xx[2]%10+10];
break;
}
}
else
{//显示正常计时
DispBuf[0]=SEG_TAB_A[hou/10];
DispBuf[1]=SEG_TAB_A[hou%10];
DispBuf[2]=SEG_TAB_A[min/10];
DispBuf[3]=SEG_TAB_A[min%10];
DispBuf[4]=SEG_TAB_A[sec/10];
DispBuf[5]=SEG_TAB_A[sec%10];
}
}
voidmain(void)//主函数
{
InitT0();
while
(1)
{
DisplayTim();
}
}
五·电路图(Proteus软件)
单片机部分
数码管显示部分
按键部分