#define uchar unsigned char
sbit buzzer=P2^7; //定义蜂鸣器控制端口 /**************函数声明*************/ void display(uchar *p); uchar keyscan(); uchar search(); void alarm(); void ftion0(); void ftion1(); void cum();
//扫描键盘有无键按下 //按键识别
//闹钟判断启动
//时钟修改 //闹钟修改 //加1修改
/***************全局变量定义****************/
uchar clockbuf[3]={0,0,0};//存放时钟时分秒的十进制数 uchar bellbuf[3]={0,0,0};//存放闹钟时分秒的十进制数 uchar msec1; uchar msec2;
//10ms中断次数 //1s循环次数
uchar timdata,rtimdata; //时钟和闹钟修改位置标志 uchar count; uchar *dis_p;
//闹钟启动后10s计时单元
//显示缓冲区指针
_
bit armbit;//闹钟标志,为0闹钟未设定,为1已设定 bit rtimbit;//闹钟是否启动标志,为1已启动
bit rhourbit;//闹钟小时修改标志,为1正在修改闹钟小时 bit rminbit;//闹钟分修改标志,为1正在修改闹钟分 bit hourbit;//时钟小时修改标志,为1正在修改时钟小时 bit minbit;//时钟分修改标志,为1正在修改时钟分 bit secbit;//时钟秒修改标志,为1正在修改时钟秒 /****************主函数****************/ void main() {
uchar a;
armbit=0; //清零闹钟标志位
msec1=0; //设置10ms中断次数初值 msec2=0; //设置1s中断次数初值 timdata=0; //时钟内容修改位置记忆单元清零 rtimdata=0;//闹钟内容修改位置记忆单元清零 count=0; //闹钟启动后保持10s计时单元清零 TMOD=0x02; //定时器T0为工作方式2 TL0=0x06; //定时初始值为250us TH0=0x06;
EA=1; //中断总允许位开启 ET0=1; //定时器1开中断
_
数 数
TR0=1; //启动定时器T0
dis_p=clockbuf;//将时钟值所在地址送入显示指针 P1=0x00;buzzer=0; while(1) {
a=keyscan(); //调用键盘扫描子程序 if(a==0x07) { } else {
display(dis_p);//调用显示子函数作为延时去抖动 a=keyscan();
if(a!=0x07) //没有抖动,表示有键按下 {
a=search(); //调用查键值子函数 switch(a){
case 0x00:ftion0();break;//是时钟参数修改功能键,调用时钟设置子函display(dis_p);//无键输入调用显示程序
if(armbit==1)alarm();//判断闹钟设定否,若设定则调用闹钟启动函数
case 0x01:ftion1();break;//是闹钟参数修改功能键,调用闹钟设置子函
_
}}}}
case 0x02:cum();break;//是加1功能键,调用加1修改功能子函数 default:break;}
/***************6位LED显示函数***************/ void display(uchar *p)
{ uchar buffer[6]={0,0,0,0,0,0};
uchar k,i,j,m,temp;
uchar led[]={0x3f,0x06,0x5b,0x4f,0x66, 0x6d,0x7d,0x07,0x7f,0x6f}; buffer[0]=p[0]/10; buffer[1]=p[0]%10; buffer[2]=p[1]/10; buffer[3]=p[1]%10; buffer[4]=p[2]/10; buffer[5]=p[2]%10; for(k=0;k<2;k++) {temp=0x01;
for(i=0;i<6;i++) {
j=buffer[i]; P0=~temp;
P1=led[j]; //P1送断码
_
}}}
temp<<=1;
for(m=0;m<100;m++);//每一位显示延时 P1=0x00;
//关显示
/**************键盘扫描函数************/ uchar keyscan() { }
/**************查键值函数*************/ uchar search() {
uchar a,b,c,d,e; //P2=0xfe; c=0xfe; a=0;
//首列扫描字送变量c //首列号送a
uchar c; P0=0xf0; c=P2;
c=c&0x07;//按键行输入为P2.0-P2.2,屏蔽无关位 return(c);
while(1) {
_
}
}
P0=c; //列扫描字送P0口
d=P2; //读入P2口的行状态
if((d&0x01)==0){b=0;break;}//第0行有键按下,第0行行首号送b else if((d&0x02)==0){b=4;break;}//第1行有键按下,第1行行首号送b
else if((d&0x04)==0){b=8;break;}//第2行有键按下,第2行行首号送b
//扫描列号加1
a++;
c<<=1; //修改列扫描字,扫描下一列
e=a+b; //将行首号与列号相加,求键号
do{display(dis_p);}
while((d=keyscan())!=0x07);//等待释放按键 return(e);
/***********闹钟判断启动函数*************/ void alarm() {
if((clockbuf[0]==bellbuf[0])&&(clockbuf[1]==bellbuf[1]))
{buzzer=1;rtimbit=1;}//设置闹钟计时标志,时钟将进行10s计时标志
//判断闹钟保持10s时间到否
if(count==10)
{
count=0; //清除闹钟保持10s计时 buzzer=0; //清除闹钟
_
armbit=0; //清闹钟标志,否则闹钟设置将继续有效 rtimbit=0; }}
/*************时钟设置函数*************/ void ftion0() {
if(rhourbit==1||rtimbit==1||rtimdata==1)
{secbit=0;minbit=0;hourbit=0;timdata=0;}
else { }}
TR0=0;
//关定时器
dis_p=clockbuf;//将时钟缓冲区首地址送显示指针 timdata++; //将时钟修改记录值加1 switch(timdata){
case 0x01:secbit=1;break;//记录值为1,则将时钟秒修改标志置1
case 0x02:secbit=0;minbit=1;break;//记录值为2,则将时钟分修改标志置1 case 0x03:minbit=0;hourbit=1;break;//记录值3,则将时钟时修改标志置1 case 0x04:timdata=0;hourbit=0;TR0=1;break;//按4次则清时钟单元修改位置
//记录,定时器重新开启
default:break;}
/***************闹钟设置函数**************/
_
void ftion1() {
if(secbit==1||minbit==1||hourbit==1||timdata==1) {rhourbit=0;rtimbit=0;rtimdata=0;} else { }}
dis_p=bellbuf; //设置闹钟显示标志 rtimdata++;
//将闹钟修改记录值加1
switch(rtimdata){
case 0x01:rminbit=1;break;//记录值为1,将闹钟分修改标志置1 case 0x02:rminbit=0;rhourbit=1;break;
//记录值为2,将时钟分修改标志置1
case 0x03:rtimdata=0;rhourbit=0;//按3次则清闹钟单元修改位置记录
armbit=1; //设置闹钟已设置标志位 dis_p=clockbuf;//恢复时钟显示标志 break;
default:break;}
/*************加1修改功能函数**************/ void cum()
{ if(secbit==1){ //时钟秒修改标志为1,秒单元内容加1
if(clockbuf[2]==59) clockbuf[2]=0;
_
}
else clockbuf[2]++;}
else if(minbit==1){ //时钟分修改标志为1,分单元内容加1
if(clockbuf[1]==59) clockbuf[1]=0; else clockbuf[1]++;}
else if(hourbit==1){ //时钟小时修改标志为1,小时单元内容加1
if(clockbuf[0]==23) clockbuf[0]=0; else clockbuf[0]++;}
else if(rminbit==1){ //闹钟分修改标志为1,分单元内容加1
if(bellbuf[1]==59) bellbuf[1]=0; else bellbuf[1]++;}
else if(rhourbit==1){ //闹钟小时修改标志为1,小时单元内容加1
if(bellbuf[0]==23) bellbuf[0]=0; else bellbuf[0]++;}
/************定时器中断函数*************/ void clock() interrupt 1 {
EA=0;
//关中断
if(msec1!=40) msec1++; else
{ msec1=0; //到10ms否,不到则msec1加1
if(msec2!=10)msec2++;//到1s否,不到则msec2加1
_
}
else {
if(rtimbit==1)count++;msec2=0;
if(clockbuf[2]!=59)clockbuf[2]++;//到1min否,不到则clockbuf[2]加1 else { }}}
//开中断 clockbuf[2]=0;
if(clockbuf[1]!=59)clockbuf[1]++;//到1h否,不到则clockbuf[1]加1 else { }
clockbuf[1]=0; if(clockbuf[0]!=23)
clockbuf[0]++; //到24h否,不到则clockbuf[0]加1 else clockbuf[0]=0;
EA=1;
第五章 电子时钟仿真结果
电子钟正常显示仿真:
_
启动闹钟:
设置定时数值:(如图设置为10分钟)