基于数码管的简单时钟系统
来源:互联网 发布:方舟画质优化 编辑:程序博客网 时间:2024/05/18 01:13
- 主要实现:能够在数码管上显示时,分,秒;
设置闹钟(蜂鸣器);
利用51单片机的定时器功能进行计时。
说明:在程序的编写过程中无法实现减一的操作,没按一次减一的键总是不止一次地减一。这个问题尚未解决,详情见附录的程序部分。希望各路大神看到了能指点一二,在此不胜感激。 - 系统仿真图:
- 程序如下:
#include<reg51.h> //头文件#define uchar unsigned char //宏定义 之后用uchar代替unsigned char 这里指无符号字符#define uint unsigned int //宏定义 同上 无符号整数sbit beep=P0^0;uchar dat[]={0,0,10,0,0,10,2,1}; //定义初始化显示时间数组uchar dat1[]={0,0,10,0,0,10,0,0}; //定义初始化闹钟设定值数组,本程序中闹钟只设定到分uchar dis_bit[]={0x80,0x40,0x20,0x10,0x08,0x04,0x02,0x01}; //数码管位选uchar code SEG7[11]={0xC0,/*0*/0xF9,/*1*/0xA4,/*2*/0xB0,/*3*/0x99,/*4*/0x92,/*5*/0x82,/*6*/0xF8,/*7*/ 0x80,/*8*/0x90,/*9*/0xBF,/*-*/}; //共阴极数码管字段码uchar key_code[]= { /*列检测时按键按下时key的可能值,通过对这些值的判断也就可以知道具体按键的位置*/ 0x7e,0x7d,0x7b,0x77, /*当列中的最高位P2.7为0时,这一列四个按键按下时(即对应行值变为0)的key的值,对应的键值为0,1,2,3*/ 0xbe,0xbd,0xbb,0xb7, /*当列中的P2.6为0时,这一列四个按键按下时(即对应行值变为0)的key的值,对应的键值为4,5,6,7*/ 0xde,0xdd,0xdb,0xd7, /*当列中的P2.5为0时,这一列四个按键按下时(即对应行值变为0)的key的值,对应的键值为8,9,A,B*/ 0xee,0xed,0xeb,0xe7 /*当列中的P2.4为0时,这一列四个按键按下时(即对应行值变为0)的key的值,对应的键值为C,D,E,F*/ };uchar code ksp[4]={0x7f,0xbf,0xdf,0xef}; //确定列的前提下(分别给每列置零)进行行检测uint tcount,t_beep;uchar flag=0; //闹钟切换标志位,uchar flag_beep=0; //蜂鸣器响标志位,=1表示蜂鸣器响 /*flag=0,设定闹钟;flag=1,显示正常时间*/struct time{uint second;uint minute;uint hour;}time1; //定义名为time的结构体,变量名time1uchar n,i,k;void delay(n) //延时函数 {while(n--) { for(i=110;i>0;i--); } } void display(void) //数字显示{ if(flag==0) //显示正常时间 { for(k=0;k<8;k++) { P3=dis_bit[k]; P2=SEG7[dat[k]]; //p2接数码管a-g,p3接数码管1-8,控制动态扫描输出 delay(5); P3=0X00; } } if(flag==1) //显示闹钟设定时间 { for(k=0;k<8;k++) { P3=dis_bit[k]; P2=SEG7[dat1[k]]; //p2接数码管a-g,p3接数码管1-8,控制动态扫描输出 delay(5); P3=0X00; //消影 } }}uchar keypad_scan(){ uchar key,temp=0; P1=0xf0; if(P1!=0xf0) { delay(10); if(P1!=0xf0) { do{ for(i=0;i<4;i++) //检测四列,按键必定在这四列之中 { P1=ksp[i]; //重新给P2口赋值,此时列已经确定了 if(P1!=ksp[i]) //某一行值变为0,P2口的值发生改变 { delay(10); //消抖,按键抖动 key=P1; if(key!=ksp[i]) //再次确认四行中有某行变为0 { while(temp!=ksp[i]) {P1=ksp[i];temp=P1;display();} return(key); //此时的key值既包含了行值信息又包含了列值信息。 } } } }while(1); } }}uchar gotkey(){ uchar temp; temp=keypad_scan(); for(i=0;i<16;i++) { if(temp==key_code[i]) //查表确定键盘号 return(i); }} void keyscan(void) //时间调整函数{ uchar keynum; keynum=gotkey(); EA=0; //中断开关。=0关中断 if(keynum==0) //开始设定闹钟时间 { flag=1; TR0=0; } if(keynum==1) //暂停功能触发,停止计时,便于调整时间 { flag=0; TR0=0;ET0=0; //ET0为定时器T0的中断控制位。=0禁止中断;TR0运行控制位,位于TCON内部,=1定时器可能工作 } if(keynum==2) { if(flag==0) //时钟调整每次加1 { dat[6]++; if((dat[7]==2)&&(dat[6]>3)) { dat[7]=0; dat[6]=0; } if(dat[6]>9) { dat[6]=0; dat[7]++; if(dat[7]>2) { dat[7]=0; } } } if(flag==1) //闹钟时钟定时 { dat1[6]++; if((dat1[7]==2)&&(dat1[6]>3)) { dat1[7]=0; dat1[6]=0; } if(dat1[6]>9) { dat1[6]=0; dat1[7]++; if(dat1[7]>2) { dat1[7]=0; } } } } if(keynum==3) { if(flag==0) //分钟调整每次加一 { dat[3]++; if(dat[3]>=9) { dat[4]++; dat[3]=0; if(dat[4]>5) { dat[4]=0; } } } if(flag==1) //闹钟分钟定时 { dat1[3]++; if(dat1[3]>9) { dat1[4]++; dat1[3]=0; if(dat1[4]>5) { dat1[4]=0; } } } } if(keynum==4) //暂停结束,显示正常时间;正常情况按下时无影响 { flag=0; TR0=1;ET0=1; } if(keynum==5) { dat1[0]=0; dat1[1]=0; dat1[3]=0; dat1[4]=0; dat1[6]=0; dat1[7]=0; }/* if(keynum==6) { if(flag==0) //时钟减一 { if(dat[6]!=0) { dat[6]=dat[6]-1; } else { if((dat[6]==0)&&(dat[7]!=0)) { dat[7]=dat[7]-1; dat[6]=9; } else { dat[6]=3; dat[7]=2; } } } if(flag==1) //闹钟时钟减一 { if(dat1[6]!=0) dat1[6]=dat1[6]-1; else { if((dat1[6]==0)&&(dat1[7]!=0)) { dat1[7]=dat[7]-1; dat1[6]=9; } else { dat1[6]=3; dat1[7]=2; } } } } if(keynum==7) { if(flag==0) //分钟减一 { if(dat[3]!=0) dat[3]=dat[3]-1; else { if((dat[3]==0)&&(dat[4]!=0)) { dat[4]=dat[4]-1; dat[3]=9; } else { dat[3]=9; dat[4]=5; } } } if(flag==1) //闹钟分钟减一 { if(dat1[3]!=0) dat1[3]=dat1[3]-1; else { if((dat1[3]==0)&&(dat1[4]!=0)) { dat1[4]=dat1[4]-1; dat1[3]=9; } else { dat1[3]=9; dat1[4]=5; } } } } */ EA=1; //中断开关,开中断} void init(void) //初始化函数{ TMOD = 0x11; //TMOD特殊功能寄存器。控制两个定时器T1,T0,这里=00010001,T1T0处于工作方式1,定时开关仅由TR0控制 TH0 = 0xDB; //预置数计时,转为十进制56319,到65536结束。计时约10ms TL0 =0xFF; ET0=1; TR0=1; tcount=0; EA = 1; beep=1; t_beep=0; flag=0; flag_beep=0;}void main(){ init(); delay(10); while(1) //只要条件为真就一直循环。 { display(); keyscan(); if((dat[7]==dat1[7])&&(dat[6]==dat1[6])&&(dat[4]==dat1[4])&&(dat[3]==dat1[3])&&(dat[1]==dat1[1])&&(dat[0]==dat1[0])) /*以上条件同时成立*/ { flag_beep=1; //当正常时间到达设定时间时,将蜂鸣器响标志置为1 } if(flag_beep) { if(t_beep%2==0) { beep=0;delay(5);} beep=1; } } }void timer_0() interrupt 1 { ET0=0; //T0禁止中断 TR0=0; TH0 = 0xDB; TL0 = 0xFF; TR0=1; tcount++; if(tcount==100) //定时器是否满1秒 { time1.second++; t_beep++; if(t_beep==60) //蜂鸣器持续响60s { flag_beep=0; t_beep=0; } tcount=0; dat[0]=(time1.second)%10; dat[1]=(time1.second)/10; //显示秒 if(time1.second>59) { dat[0]=0; dat[1]=0; time1.second=0; time1.minute++; dat[3]=(time1.minute)%10; dat[4]=(time1.minute)/10; //显示分 if(time1.minute>59) { dat[3]=0; dat[4]=0; time1.minute=0; time1.hour++; dat[6]=time1.hour%10; //显示小时 dat[7]=time1.hour/10; if(time1.hour>23) { dat[6]=0; dat[7]=0; time1.hour=0; } } } } ET0=1;}
本设计相关工程文件和仿真文件见:基于数码管的简单时钟系统
1 0
- 基于数码管的简单时钟系统
- 利用数码管显示的时钟
- 数码管的简单介绍
- 基于ISD1760的语音时钟播报系统
- 基于S3C2440的系统时钟配置
- 单片机数码管时钟显示
- [51]数码管作时钟
- 数码管显示时钟
- DS1302时钟数码管显示
- 数码管显示时钟
- 从零开始基于S5PV210的嵌入式时钟系统的分析
- 利用单片机的数码管模拟时钟的显示时间
- 用单片机定时器和数码管实现的电子时钟
- CPLD 八段数码管时钟显示的VHDL实现
- 带修改暂停启动的动态数码管时钟
- 基于OpenCV的数码管数字识别
- 时钟一:51单片机用替换的方法在数码管上显示时钟
- 时钟数码管GL5642AH调试心得
- 关于iOS提交审核的IDFA
- 扣丁学堂——显示网络图片到手机中
- 安卓DisplayMetrics获取屏幕分辨率
- HDFS HA与QJM(Quorum Journal Manager)介绍及官网内容整理
- 终于发布了一个app游戏
- 基于数码管的简单时钟系统
- ubuntu 14.04中打开echo、daytime等标准服务详细实例图解
- Android ListView头部随着上下拖动缩放
- 评测:最有效的PDF在线无损转换免费工具Smallpdf
- 秩1矩阵
- Oracle学习笔记:图形管理工具 EM 的使用
- 3dmax雪景插件(SnowFlow) For Max2012/2014
- 使用Git命令实现代码上传与同步
- 【实际项目】微信相关api调用例子【以分享为例】