学了51,模仿了小时候电子手表的基本功能,可以在时钟和秒表两个功能间切换,用的是郭天祥的板子。采用四个独立按键,通过对四个键按下的次数不同,实现不同的功能,程序详注。(第一次尝试很多地方未免复杂冗余,希望大神指点)
/*使用1602作为电子表的显示屏,单片机上电后,首先通过按键设定当前时间,
完成初始化,同时该电子表还具有秒表功能,按下秒表键后,进入秒表界面。秒
表界面有开始,取次,停止,复位,返回时间,可以记录三次取时,每个按钮按
下都对应蜂鸣器短响一声进入秒表界面,时间继续运行,在时间界面,秒表处于
复位状态。*/
单片机源程序如下:
- /*......................................................................................*/
- #include<reg52.h>
- sbit lcden=P3^4; //使能端
- sbit lcdrs=P3^5; //RS
- sbit dula=P2^6; //定义锁存器的锁存端
- sbit wela=P2^7;
- sbit s1=P3^0; //定义按键----功能键
- sbit s2=P3^1; //定义按键-----增加键
- sbit s3=P3^2; //定义按键------计次键
- sbit s4=P3^3; //定义按键------钟与秒表的切换键
- sbit rd=P3^7; //初始化函数中使它接地从而使第四列矩阵键盘成为独立键盘
- sbit beep=P2^3; //定义蜂鸣器
- char count,count1,s1num,s2num,s3num,s4num,stop, miao,shi, //stop保证在秒表工作模式下,定时器0的数值不会被送去lcd显示。 count,count1是用到定时器里面, *num是用来计按键次数,miao*,shi*,fen*
- fen,miao1,shi1,fen1,miao3,fen3,shi3,miao4,fen4,shi4,miao5, //是用来保持lcd上的显示的,结合下面应该可以看懂。
- fen5,shi5,miao6,fen6,shi6,miao7,fen7,shi7,miao8,fen8,shi8,
- miao9,fen9,shi9; //char表示的数据范围-127~128
- void delay(int z) //延时子函数
- {
- int x,y;
- for(x=z;x>0;x--)
- for(y=110;y>0;y--);
- }
- void xiang() //蜂鸣器发声函数
- {
- beep=0;
- delay(20);
- beep=1;
- }
- void write_com(char com) //写命令子函数
- {
- lcdrs=0;
- P0=com;
- delay(5);
- lcden=1;
- delay(5);
- lcden=0;
- }
- void write_date(char date) //写数据子函数
- {
- lcdrs=1;
- P0=date;
- delay(5);
- lcden=1;
- delay(5);
- lcden=0;
- }
- void write_sfm(unsigned char add,unsigned char date) //写时分秒函数
- {
- unsigned char shi,ge;
- shi=date/10; //分解一个2位数的十位和个位
- ge=date%10;
- write_com(0x80+0x40+add); //设置显示位置
- write_date(0x30+shi); //送去液晶显示十位
- write_date(0x30+ge); //送去液晶显示个位
- }
- void init() //初始化函数
- {
- rd=0; //软件将矩阵按键第四列一端置低用来分离出独立按键
- dula=0;
- wela=0; //关闭锁存器,防止数码管分流,影响1602的显示
- lcden=0;
- fen=0; //初始化钟变量值
- miao=0;
- shi=0;
- count=0;
- count1=0;
- s1num=0;
- s2num=0;
- s3num=0;
- s4num=0;
- write_com(0x38); //设置16*2显示,5*7点阵,8位数据口
- write_com(0x0c); //开显示,不开光标 00001100
- write_com(0x06); //写字符后地址指针自动加一,不移动 00000110
- write_com(0x01); //清除屏幕上原有的乱码
- write_com(0x80+0x04); //从第一行的第五个字符位开始显示
- write_com(0x80+0x40+6); //在第二行第第七个字符处写入 “ :”
- write_date(':');
- delay(5);
- write_com(0x80+0x40+9); //在第二行第第十个字符处写入 “ :”
- write_date(':');
- delay(5);
- write_sfm(10,miao);
- write_sfm(7,fen);
- write_sfm(4,shi);
- TMOD=0X11; //设置定时器0的工作模式1;
- TH0=(65536-50000)/256; //装初值
- TL0=(65536-50000)%256;
- EA=1; //打开总中断
- ET0=1; //开定时器0中断
- TR0=1; //启动定时器0
- }
- void init_stopwatch() //初始化秒表
- {
- write_com(0x01);
- miao1=0;
- fen1=0;
- shi1=0;
- write_com(0x80+0x40+6); //在第二行第第七个字符处写入 “ :”
- write_date(':');
- delay(5);
- write_com(0x80+0x40+9); //在第二行第第十个字符处写入 “ :”
- write_date(':');
- delay(5);
- write_sfm(10,miao1);
- write_sfm(7,fen1);
- write_sfm(4,shi1); //TMOD=0x10;错误处:采用两个定时器时,一次设置工作模式就行
- TH1=(65536-50000)/256;
- TL1=(65536-50000)%256;
- EA=1;
- ET1=1;
- TR1=0;
- }
- void keyscan() //键盘扫描函数
- {
- if(s1==0) //判断s1是否被按下
- {
- delay(5);
- if(s1==0) //确实被按下
- {
- while(!s1); //按键抬起,
- xiang(); //蜂鸣器响
- s1num++; //功能键被按下次数
- if(s1num==1) //第一次被按下时
- {
- }
- if(s1num==2) //第二次被按下时
- {
- TR0=0; //关闭定时器
- write_com(0x80+0x40+10); //指针定到秒的地址
- write_com(0x0f); //指针开始闪烁
- }
- if(s1num==3) //第三次被按下时
- {
- write_com(0x80+0x40+7); //指针定位到分的地址
- }
- if(s1num==4) //第四次被按下时
- {
- write_com(0x80+0x40+4); //指针定位到时的地址
- }
- if(s1num==5) //第五次被按下时
- {
- s1num=0; //清零
- write_com(0x0c); //关闭光标
- TR0=1; //打开定时器
- }
- }
- }
- if(s1num==1)
- {
- if(s4==0) //切换到定时器模式
- {
- delay(5);
- if(s4==0);
- s4num++;
- while(!s4);
- xiang(); //s4确实被按下
- if(s4num==1)
- {
- stop=1;
- init_stopwatch();
- }
- if(s4num==2)
- {
- TR1=0;
- stop=0;
- s4num=0;
- write_sfm(10,(miao3+miao4));
- write_sfm(7,(fen3+fen4));
- write_sfm(4,(shi3+shi4));
-
- }
- }
- }
- if(s1num==1)
- {
- if(s2==0)
- {
- delay(5);
- if(s2==0)
- {
- while(!s2);
- xiang();
- s2num++;
- if(s2num==1)
- {
- TR1=1;
- }
- if(s2num==2)
- {
- s2num=0;
- TR1=0;
- }
- }
- }
- }
- if(s2num==1&&s4num==1)
- { if(s3==0)
- {
- delay(5);
- if(s3==0)
- {
- s3num++;
- while(!s3);
- xiang();
- if(s3num==1)
- {
- shi6=shi5;
- fen6=fen5;
- miao6=miao5;
- }
- if(s3num==2)
- {
- shi7=shi5;
- fen7=fen5;
- miao7=miao5;
- }
- if(s3num==3)
- {
- shi8=shi5;
- fen8=fen5;
- miao8=miao5;
- }
- if(s3num==4)
- {
- miao1=0;
- fen1=0;
- shi1=0;
- write_sfm(10,miao1);
- write_sfm(7,fen1);
- write_sfm(4,shi1);
- TR1=0;
- }
- if(s3num==5)
- {
- write_sfm(10,miao6);
- write_sfm(7,fen6);
- write_sfm(4,shi6);
- }
- if(s3num==6)
- {
- write_sfm(10,miao7);
- write_sfm(7,fen7);
- write_sfm(4,shi7);
- }
- if(s3num==7)
- {
- write_sfm(10,miao8);
- write_sfm(7,fen8);
- write_sfm(4,shi8);
- }
- if(s3num==8)
- {
- s3num=0;
- init_stopwatch();
- }
- }
- }
- }
- if(s1num!=0) //若是s1被按过
- {
- if(s2==0) //s2被按下
- {
- delay(5);
- if(s2==0) //s2确实被按下
- {
- while(!s2); //如果s2抬起
- xiang(); //蜂鸣器响
- if(s1num==2) //此时若是s1被按了一次
- {
- miao++; //秒加一
- miao4=miao;
- if(miao==60) //如果秒等于60
- miao=0;
- miao4=miao; //清零
- write_com(0x80+0x40+10);
- write_sfm(10,miao);
- }
- if(s1num==3)
- {
- fen++;
- fen4=fen;
- if(fen==60)
- fen=0;
- fen4=fen;
- write_com(0x80+0x40+7);
- write_sfm(7,fen);
- }
- if(s1num==4)
- {
- shi++;
- shi4=shi;
- if(shi==24)
- shi=0;
- shi4=shi;
- write_com(0x80+0x40+4);
- write_sfm(4,shi);
- }
- }
- }
-
- }
- }
- void main()
- {
- init(); //初始化1602
- while(1)
- {
- keyscan(); //一直扫描键盘
- }
- }
- void timer0() interrupt 1 //定时器0用于钟表
- {
- TH0=(65536-50000)/256; //装初值
- TL0=(65536-50000)%256;
- count++; //计数,保证每20次中断一次,时长为一秒
- if(count==20)
- {
- count=0;
- miao++;
- miao3=miao;
- if(miao==60) //将更新的秒时分的值更新到1602
- {
- miao=0;
- miao3=miao;
- fen++;
- fen3=fen;
- if(fen==60)
- {
- fen=0;
- fen3=fen;
- shi++;
- shi3=shi;
- if(shi==24)
- {
- shi=0;
- shi3=shi;
- }
- if(stop==0) //在秒表模式,钟表的时间不显示,但是任然计时
- write_sfm(4,shi);
- }
- if(stop==0)
- write_sfm(7,fen);
- }
- if(stop==0)
- write_sfm(10,miao);
- }
- }
- void timer1() interrupt 3 //定时器1用于秒表计时
- {
- TH1=(65536-50000)/256;
- TL1=(65536-50000)%256;
- count1++;
- if(count1==20)
- {
- count1=0;
- miao1++;
- miao5=miao1;
- if(miao1==60)
- {
- miao1=0;
- miao5=miao1;
- fen1++;
- fen5=fen1;
- if(fen1==60)
- {
- fen1=0;
- fen5=fen1;
- shi1++;
- shi5=shi1;
- if(shi1==24)
- {
- shi1=0;
- shi5=shi1;
- }
- write_sfm(4,shi1);
- }
- write_sfm(7,fen1);
- }
- write_sfm(10,miao1);
- }
- }
复制代码
|