资源描述
电子综合课程设计多功能数字电子时钟
3
资料内容仅供参考,如有不当或者侵权,请联系本人改正或者删除。
题目 多功能数字电子时钟
班级 **************
学号 ************
姓名 ******
指导 **********
时间 12月18日
景德镇陶瓷学院
电工电子技术课程设计任务书
姓名 **** 班级 08电子二班 指导老师 *****
设计课题: 多功能数字电子时钟
设计任务与要求
查找一个感兴趣的电工电子技术应用电路, 要求电子元件超过30~50个或以上, 根据应用电路的功能, 确定封面上的题目, 然后完成以下任务:
1、 分析电路由几个部分组成, 并用方框图对它进行整体描述;
2、 对电路的每个部分分别进行单独说明, 画出对应的单元电路, 分析电路原理、 元件参数、 所起的作用、 以及与其它部分电路的关系等等;
3、 用简单的电路图绘图软件绘出整体电路图, 在电路图中加上自己的班级名称、 学号、 姓名等信息;
4、 对整体电路原理进行完整功能描述;
5、 列出标准的元件清单;
设计步骤
1、 查阅相关资料, 开始撰写设计说明书;
2、 先给出总体方案并对工作原理进行大致的说明;
3、 依次对各部分分别给出单元电路, 并进行相应的原理、 参数分析计算、 功能以及与其它部分电路的关系等等说明;
4、 列出标准的元件清单;
5、 总体电路的绘制及总体电路原理相关说明;
6、 列出设计中所涉及的所有参考文献资料。
参考文献
[1]郭天祥, 《新概念51单片机C语言教程——入门、 提高、 开发、 拓展全攻略》; 北京: 电子工业出版社;
[2]宋戈、 黄鹤松、 员玉良、 蒋海峰, 《51单片机应用开发范例大全》; 北京: 人民邮电出版社;
[3]阎石, 《数字电子技术基础( 第四版) 》; 北京: 高等教育出版社; 1998
[4]邹显圣, 《基于AT89C51单片机数字时钟的研究》, 机电产品开发与创新; ,(5)
[5]刘伏文、 王春华, 《MCS-51单片机存储器结构详解》; 电子制作; ,(10).
[6]卢旭锦, 《基于Keil C的AT24C02串行E~2PROM的编程》; 现代电子技术; ,(8)
目录
1、 总体方案与原理说明. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .1
2、 单元电路1——单片机最小系统. . . . . . . . . . . . . . . . . . . . . . . . . . .3
3、 单元电路2——指示灯与数码管显示电路 . . . . . . . . . . . . . . . . . . . . . .5
4、 单元电路3——键盘检测电路. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .7
5、 单元电路4——AT24C02存储电路. . . . . . . . . . . . . . . . . . . . . . . . . . .9
6、 总体电路原理相关说明. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .11
7、 总体电路原理图. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .13
8、 PCB印制电路板图 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .14
9、 元件清单 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .15
10、 参考文献. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .16
11、 设计心得体会. . . . . . . . . . . . . . . . . . . .. . . . . . . . . . . . . . . . . . . . . . . . . . . .17
12、 附件: C源程序. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .18
AT89S51单片机最小系统
控制按键
发光二极管指示灯
数码管显示
AT24C02存储器
蜂鸣器
图1: 作品总体框图
1、 总体方案与原理说明
这是一个具有时间、 日期、 秒表、 闹铃以及断电储存数据功能的多功能数字电子时钟。它主要由以下几部分组成: 单片机最小系统; 指示灯及数码管显示电路; 按键电路; 以及AT24C02存储电路。整机的逻辑框图如右图所示:
本时钟的主控芯片是一台AT89S51单片机, AT89S51是一个低功耗, 高性能CMOS 8位单片机, 片内含4k Bytes ISP(In-system programmable)的可重复擦写1000次的Flash只读程序存储器, 器件采用ATMEL公司的高密度、 非易失性存储技术制造, 兼容标准MCS-51指令系统及80C51引脚结构, 芯片内集成了通用8位中央处理器和ISP Flash存储单元, 功能强大的微型计算机的AT89S51可为许多嵌入式控制应用系统提供高性价比的解决方案。
AT89S51具有如下特点: 40个引脚, 4k Bytes Flash片内程序存储器, 128 bytes的随机存取数据存储器( RAM) , 32个外部双向输入/输出( I/O) 口, 5个中断优先级2层中断嵌套中断, 2个16位可编程定时计数器,2个全双工串行通信口, 看门狗( WDT) 电路, 片内时钟振荡器。另外, AT89S51设计和配置了振荡频率可为0Hz并可经过软件设置省电模式。空闲模式下, CPU暂停工作, 而RAM定时计数器, 串行口, 外中断系统可继续工作, 掉电模式冻结振荡器而保存RAM的数据, 停止芯片其它功能直至外中断激活或硬件复位。同时该芯片还具有PDIP、 TQFP和PLCC等三种封装形式, 以适应不同产品的需求。
整个电路由一台单片机和一些外围电路组成。它的计时采用单片机内部的定时器, 其晶振频率为11.0592MHz。其主要功能都是经过C语言编程来实现的。其显示部分用四位数码管来显示, 能同时显示小时和分钟。它主要有以下几个功能: ( 1) 时间显示及调整: 在正常状态下显示当前时间, 并随时能够经过控制按键进行调整。( 2) 日期显示及调整: 在日期显示状态下能够显示当前日期, 进入日期调整状态后还能够调整日期。( 3) 秒表功能: 进入秒表状态后能够进行秒表计时, 它能计时的长度为100分钟, 当时间在0~10分钟内计时精度为0.1秒, 四位数码管中第一位显示分钟, 中间两位显示秒钟, 最后一位显示0.1秒表; 当时间在10~100分钟内计时精度为1秒, 四位数码管前两位显示分钟, 后两位显示秒钟。( 4) 闹铃功能: 在进入闹铃调整状态后能够设定闹铃时间, 当时间到达设定好的时间时蜂鸣器就会发出”嘀嘀”的报警声。( 5) 整点报时功能: 当时间到达整点时蜂鸣器会发出”嘀”的一声报警, 以提示到达整点。( 6) 断电存储数据的功能: 当时钟在运行时, 它会实时将当前时间存入一个AT24C02存储器中, 在每次启动时它会首先从该存储器中读取数据, 这样将保证时钟在断电后数据不会丢失, 再次接通电源后将接着上次的时间运行。
以下我将对各部分的原理进行详细的阐述。
图2: 单片机最小系统
2、 单元电路1——单片机最小系统
单片机最小系统由一个单片机加上一个复位电路和振荡电路组成。图中右下角还有一个蜂鸣器电路, 它用于闹铃的报警:
( 1) 复位电路
单片机复位电路原理是在单片机的复位引脚RST上外接电阻和电容, 实现上电复位。当复位电平持续两个机器周期以上时复位有效。复位电平的持续时间必须大于单片机的两个机器周期。具体数值能够由RC电路计算出时间常数。复位电路由按键复位和上电复位两部分组成。( 1) 上电复位: 8051系列单片及为高电平复位, 一般在复位引脚RST上连接一个电容到VCC, 再连接一个电阻到GND, 由此形成一个RC充放电回路保证单片机在上电时RST脚上有足够时间的高电平进行复位, 随后回归到低电平进入正常工作状态, 这个电阻和电容的典型值为10K和10uF。( 2) 按键复位: 按键复位就是在复位电容上并联一个开关, 当开关按下时电容被放电、 RST也被拉到高电平, 而且由于电容的充电, 会保持一段时间的高电平来使单片机复位。
( 2) 振荡电路
单片机系统里都有晶振, 在单片机系统里晶振作用非常大, 全称叫晶体振荡器, 它结合单片机内部电路产生单片机所需的时钟频率, 单片机晶振提供的时钟频率越高, 那么单片机运行速度就越快, 单片接的一切指令的执行都是建立在单片机晶振提供的时钟频率。在一般工作条件下, 普通的晶振频率绝对精度可达百万分之五十。高级的精度更高。有些晶振还能够由外加电压在一定范围内调整频率, 称为压控振荡器( VCO) 。晶振用一种能把电能和机械能相互转化的晶体在共振的状态下工作, 以提供稳定, 精确的单频振荡。
单片机晶振的作用是为系统提供基本的时钟信号。一般一个系统共用一个晶振, 便于各部分保持同步。有些通讯系统的基频和射频使用不同的晶振, 而经过电子调整频率的方法保持同步。晶振一般与锁相环电路配合使用, 以提供系统所需的时钟频率。如果不同子系统需要不同频率的时钟信号, 能够用与同一个晶振相连的不同锁相环来提供。AT89S51使用11.0592MHz的晶体振荡器作为振荡源, 由于单片机内部带有振荡电路, 因另外部只要连接一个晶振和两个电容即可, 电容容量一般在15pF至50pF之间。
图3: 指示灯与数码管显示电路
3、 单元电路2——指示灯及数码管显示电路
图4: 数码管内部原理图
1、 数码管显示原理
数码管有一位、 双位、 四位等几种。而不论将几位数码管连在一起, 数码管和显示原理都是一样的, 都是靠点亮内部的发光二极管来发光。数码管的内部电路结构如上图所示: 从( a) 可看出, 一位数码管的引脚数是10个, 显示一个8字需要7个小段, 另外还有一个小数点, 因此其内部一共有8个小的发光二极管, 最后还有一个公共端, 生产商为了封装统一, 单位数码管都封装10个引脚。而它们的公共端又分为共阳极和共阴极。上页图的( b) 和( c) 分别为共阳极和共阴极数码管的原理图。
本电子钟上的数码管采用的是4位共阳极数码管。所谓”共阳”就是指其内部的8个发光二极管的阳极全部接在一起, 而它们的阴极是独立的, 一般在设计电路时一般把阳极接VCC, 当我们给数码管的任一个阴极加低电平时, 对应的那个发光二极管就点亮了。
当使用多位一体数码管时, 它们内部的公共端是独立的, 而负责显示什么数字的段线全部都是连在一起的, 独立的公共端能够控制多位数码管中哪一位点亮。一般我们把公共端叫做”位选线”, 连在一起的段线叫做”段选线”。
2、 显示部分C源程序的编写:
由于在本电子钟中4位数码管的段选线是直接接在单片机的P0口的, 因此我们首先应该计算出显示各个数字所对应的P0口输出的二进制编码。例如如果要显示一个”0”, 对照上面的( a) 图, 我们需要点亮数码管中的a、 b、 c、 d、 e、 f, 而g和dp不点亮, 故a、 b、 c、 d、 e、 f、 g、 dp对应的二进制编码就为: 00000011。再对照数码管段选线与单片机连接的顺序就可得要赋给单片机P0口的值应为10100000, 转换为十六进制就是a0。同理能够得到其它数字对应的十六进制编码:
uchar code table[10]={0xa0,0xbe,0x62,0x2a,0x3c,0x29,0x21,0xba,0x20,0x28};
uchar code table_dot[10]={0x80,0x9e,0x42,0x0a,0x1c,0x09,0x01,0x9a,0x00,0x08}; //带小数点的数字段码表
3、 指示灯功能说明:
其中秒表、 日期、 闹铃、 小时调整、 分钟调整为状态指示灯, 当时钟处于其中的某种状态时, 对应的指示灯会亮。秒针指示为秒针指示灯, 它会每隔0.5秒闪烁一次, 用来指示当前正处于计时状态( 包括时间显示和秒表状态) 。
显示部分的具体C源程序见附录。
单元电路3——键盘检测电路
图5: 键盘与单片机连接电路
理想波形
实际波形
稳定闭合
按下抖动
释放抖动
图6: 按键被按下时电压的变化
上图是5个按键与单片机的连接图, 其中一端是直接接地的, 当某一个按键被按下时, 与之对应的I/O口就会被置为低电平, 由于一上电时计算机的所有I/O口都是高电平, 当单片机检测到某一个I/O口为低电平时就知道是哪个按键被按下了。
可是如果直接检测引脚是否为低电平的话是会有问题的。请看图6。从图中能够看出, 理想波形与实际波形之间是有区别的, 实际波形在按下和释放的瞬间都会有抖动现象, 抖动时间的长短和按钮的机械特性有关, 一般为5~10ms。一般我们手动一般我们手动按下键然后释放, 这个动作中稳定闭合的时间超过20ms。因此单片机在检测键盘是否按下时都要加上去抖动操作, 有专门的去抖动电路, 但一般我们用软件延时的方法就能很容易地解决抖动的问题, 因此没必要增加多余的硬件电路。
在编写程序时, 一般在检测按下是加入去抖延时。按键检测的流程图如下:
因此, 键盘检测部分的C源程序的写法应如下所示:
void keyscan()
{
if(key==0)
{
delay(10);
if(key==0)
{
( 按键后要执行的语句)
while(!key);//等待按键释放
}
}
}
键盘检测部分的具体C源程序见附录。
开始
寄存器及I/O口初始化
检测是否有键按下
延时10ms
检测是否有键按下
检测是否有键释放
执行相应的代码
N
N
N
Y
Y
Y
图7: 按键检测流程图
图8: AT24C02存储电路
4、 单元电路 4——AT24C02存储电路
单片机与AT24C02芯片通信使用I2C总线协议。
1、 I2C总线:
图9: I2C总线模拟时序图
起始与终止信号
字节的传送与应答
I2C总线是由数据线SDA和时钟SCL构成的串行总线, 可发送和接收数据。I2C总线在传送数据过程中共有三种类型信号, 它们分别是: 开始信号、 结束信号和应答信号。
开始信号: SCL为高电平时, SDA由高电平向低电平跳变, 发出数据开始传输信号。
结束信号: SCL为高电平时, SDA由低电平向高电平跳变, 发出数据传输结束信号。
应答信号: 接收数据的I2C在接收到8bit数据后, 向发送数据的I2C发出特定的低电平脉冲, 表示已收到数据。CPU向受控单元发出一个信号后, 等待受控单元发出一个应答信号(0), CPU接收到应答信号后, 根据实际情况作出是否继续传递信号的判断。若未收到应答信号, 由判断为受控单元出现故障。
I2C规程运用主/从双向通讯。器件发送数据到总线上, 则定义为发送器, 器件接收数据则定义为接收器。主器件和从器件都能够工作于接收和发送状态。 总线必须由主器件( 一般为微控制器) 控制, 主器件产生串行时钟( SCL) 控制总线的传输方向, 并产生起始和停止条件。SDA线上的数据状态仅在SCL为低电平的期间才能改变, SCL为高电平的期间, SDA状态的改变被用来表示起始和停止条件。
5、 总体电路原理相关说明
2
1
作品外观:
7
18
17
13
6
4
5
11
16
8
10
AT24C02
15
12
AT89S51
9
3
8.8.8.8.
14
图10: 作品外观图
1: 小时调整指示灯 2: 秒针指示灯 3: 分钟调整指示灯 4: 秒表状态指示灯
5: 日期状态指示灯 6: 闹铃状态指示灯 7: 四位LED数码管 8:AT24C02存储器
9: AT89S51单片机 10: 蜂鸣器 11: 闹铃开关 12: DC5.0V电源插口
13: 复位按钮 14: 11.0593Hz晶振 15: 模式键 16: 调整选择键
17: 调整+键 18: 调整-键
功能说明:
1.功能键说明:
(1) 模式键: 按下该键时钟将在正常状态、 秒表状态、 日期调整状态和闹铃调整状态之间循环切换。如果在秒表状态、 日期调整状态或闹铃调整下进行了操作, 则按下该键将直接返回正常状态。
(2) 调整选择键: 按下该键将在小时调整状态、 分钟调整状态之间切换。
(3) 调整+键: 在正常状态下按住该键不放将显示当前日期。在任何调整状态下按下该键对应的项目将加1。
(4) 调整-键: 在正常状态下按住该键不放将显示当前闹铃。在任何调整状态下按下该键对应的项目将减1。
2.秒表功能:
在正常状态下按一下模式键将进入秒表状态。此时秒表状态指示灯亮起, 按下调整+键秒表开始计时, 再按一下停止计时。按下秒表将清零。在计时的过程中按下调整-键, 秒表显示将静止, 但计时仍在继续, 再按一下恢复显示。在秒表状态下进行了任何操作后按一下模式键将直接返回到正常状态。
当时间在0~10分钟内计时精度为0.1秒, 四位数码管中第一位显示分钟, 中间两位显示秒钟, 最后一位显示0.1秒表; 当时间在10~100分钟内计时精度为1秒, 四位数码管前两位显示分钟, 后两位显示秒钟。
3: 日期功能:
在正常状态下按住调整+键不放将进入日期显示状态, 此时四位LED数码管上显示当前日期。在正常状态下按两下模式键将进入日期调整状态, 此时日期状态指示灯亮起。同时分钟调整指示灯亮起, 按下调整+键或调整-键能够调整日期。按一下调整选择键将切换到月份调整状态, 同时小时调整指示灯亮起, 按下调整+键或调整-键能够调整月份。调整完后按一下能够直接返回到正常状态。
4: 闹铃功能:
在正常状态下按住调整-键不放将进入日期显示状态, 此时四位LED数码管上显示当前闹铃时间。在正常状态下按三下模式键将进入闹铃调整状态, 此时闹铃状态指示灯亮起。同时分钟调整指示灯亮起, 按下调整+键或调整-键能够调整当前闹铃分钟。按一下调整选择键将切换到闹铃小时调整状态, 同时小时调整指示灯亮起, 按下调整+键或调整-键能够调整闹铃小时。调整完后按一下模式键能够直接返回到正常状态。当时间到达闹铃时间时, 蜂鸣器会发出”嘀嘀”声, 按一下调整-键将停止响铃。
5: 整点报时功能:
当时间到达整点时蜂鸣器会发出”嘀”的一声, 以提示到达整点。
6: 存储数据的功能:
当时钟在运行时, 它会实时将当前时间存入一个AT24C02存储器中, 在每次启动时它会首先从该存储器中读取数据, 这样将保证时钟在断电后数据不会丢失, 再次接通电源后将接着上次的时间运行。
6、 总体电路原理图
图11: 总体电路图
7、 PCB印制电路板图
图12: PCB印制电路板图
8、 元件清单
序号
元件名称
元件
数量
参数
1
电解电容
C1
1
10uf
2
瓷片电容
C2,C3
2
20pf
3
发光二极管
DS1, DS2, DS3, DS4, DS5, DS7
6
——
4
三极管
Q1, Q2, Q3, Q4, Q5
5
8550(2N3960)
5
电阻
R1~R5,R7,R8~R14,R16
14
470kΩ
6
电阻
R15
1
16kΩ
7
电阻
R22,R23
2
10kΩ
8
弹性按键
S1~S4
4
——
9
LED数码管
U3
1
4位共阳
10
AT24C02
U1
1
——
11
AT89S51单片机
U2
1
——
12
蜂鸣器
LS1
1
——
13
晶振
Y1
1
11.0592MHz
14
电源插座
J1
1
PWR2.5
9、 参考文献
[1]郭天祥, 《新概念51单片机C语言教程——入门、 提高、 开发、 拓展全攻略》; 北京: 电子工业出版社;
[2]宋戈、 黄鹤松、 员玉良、 蒋海峰, 《51单片机应用开发范例大全》; 北京: 人民邮电出版社;
[3]阎石, 《数字电子技术基础( 第四版) 》; 北京: 高等教育出版社; 1998
[4]邹显圣, 《基于AT89C51单片机数字时钟的研究》, 机电产品开发与创新; ,(5)
[5]刘伏文、 王春华, 《MCS-51单片机存储器结构详解》; 电子制作; ,(10).
[6]卢旭锦, 《基于Keil C的AT24C02串行E~2PROM的编程》; 现代电子技术; ,(8)
设计心得体会
这是我入大学以来的第一次课程设计, 虽然没什么经验, 做出来的东西也似乎不那么尽人意, 但这毕竟是我第一次经过自己的努力, 完整地做出来了一件自己的作品。从中我也学到了很多在课堂上学不到的东西, 对于原来所学的东西也得到了巩固和加深。
经过这两周的电子综合课程设计, 我对经过单片机编程设计一个产品有了一些更深层的认识, 比如产品及程序设计的”模块化”, 以前只是在课堂上接触到了这些概念, 但对它却没有什么深刻的认识, 而经过这次的课程设计, 我深切的感受到了”模块化设计”的必要必以及给整个作品的设计带来的便捷。同时对于C语言的编程能力也有了一定的提升。
进行电子课程设计其中很重要的一点就是原理图和绘制。这其中要用到的专业软件就是Altium Designer (Protel)。由于我前一段时间已经自学过这个软件, 因此在这次课程设计中的原理图绘制部分没遇到过什么太大的问题。而有些不会使用这个软件的同学则会遇到很大的问题, 我又体会到了专业软件寻我们专业的重要性。
总之, 我学这次实习对我们来说是一次很好的锻炼, 对我们学的专业知识也有很大的巩固与提高, 也为我们以后的毕业设计积累了宝贵的经验。同时我也希望学校能多搞一些这样的课程设计
附录: C源程序
#include<reg52.h>
#include"24c02.h"
#define uchar unsigned char
#define uint unsigned int
sbit key1=P3^7;
sbit key2=P3^6;
sbit key3=P3^5;
sbit key4=P3^4;
sbit led=P1^7; //定义秒针的指示灯
sbit beep=P2^3; //定义蜂鸣器
sbit led1=P1^0; //定义左边数字调整指示灯
sbit led2=P1^1; //定义右边数字调整指示灯
sbit led3=P1^2; //定义秒表状态指示灯
sbit led4=P1^3; //定义日期调整状态指示灯
sbit led5=P1^4; //定义闹铃调整状态指示灯
uchar code table[10]={0xa0,0xbe,0x62,0x2a,0x3c,0x29,0x21,0xba,0x20,0x28};
uchar code table_dot[10]={0x80,0x9e,0x42,0x0a,0x1c,0x09,0x01,0x9a,0x00,0x08};
uchar mode,adjust,hour,min,sec,num0,num1,month,day,bell_hour,bell_min;
/*mode为指示电子钟模式的变量, mode=0为正常状态, 1为秒表状态, 2为日期调整状态, 3为闹铃调整状态。adjust为调整选择变量, adjust=0时不调整任何变量, =1时为小时/月份调整状态, =2时为分钟/日期调整状态。hour、 min、 sec分别为时钟的小时、 分钟、 秒钟。num0、 num1为记录定时器溢出次数的变量。month、 day、 bell_hour、 bell_min分别为月份、 日期、 闹铃小时、 闹铃分钟。*/
bit frezze=0,date_display,bell_display,flag;
/*frezze为表示秒表显示是否静止的变量( frezze=1时秒表显示静止) 。date_display、 bell_display为指示日期、 闹铃显示状态的变量。*/
uint min1,sec1,a,b; //min1、 sec1为秒表状态时的分、 秒*10。a, b为秒表示数静止时保存秒表分和秒和临时变量*/
/**************************************************/
/********************延时函数********************/
/*************************************************/
void delay(m)
{
uint i,j;
for(i=m;i>0;i--)
for(j=110;j>0;j--);
}
void di()
{
beep=0;
delay(12);
beep=1;
}
/**************************************************/
/**********时间显示时的显示子函数**************/
/**************************************************/
void display(uchar hour_1,uchar min_1)
{
uchar a,b,c,d;
a=hour_1/10; //分离小时和分钟的个位和十位
b=hour_1%10;
c=min_1/10;
d=min_1%10;
if(a==0) //如果小时的十位为零则只显示个位
{
P2=0xdf;
P0=0xff;
P0=table_dot[b];
delay(1);
}
else
{
P2=0xbf;
P0=0xff;
P0=table[a];
delay(1);
P2=0xdf;
P0=0xff;
P0=table_dot[b];
}
delay(1);
P2=0xef;
P0=0xff;
P0=table[c];
delay(1);
P2=0x7f;
P0=0xff;
P0=table[d];
delay(1);
P0=0xff;
}
/************************************************/
/*************秒表状态时的显示子函数*************/
void display_stopwatch(uchar min1,uint sec1) //该函数为0~10分钟内的显示子函数, 其中第一位显示分钟, 第二、 三位显示秒钟、 最后一位显示0.1秒
{
uchar a,b,c;
a=(sec1%1000)/100;
b=(sec1%100)/10;
c=sec1%10;
P2=0xbf;
P0=0xff;
P0=table_dot[min1];
delay(5);
P2=0xdf;
P0=0xff;
P0=table[a];
delay(5);
P2=0xef;
P0=0xff;
P0=table_dot[b];
delay(5);
P2=0x7f;
P0=0xff;
P0=table[c];
delay(5);
P0=0xff;
}
/**************************************************/
/*****************秒表显示子函数2******************/
void display_stopwatch2(uchar min1,uint sec1)
{ //该函数为10~99分钟内的显示子函数
uchar a,b,c,d; //其中前两位为分钟, 后两位为秒钟
a=min1/10;
b=min1%10;
c=sec1/100;
d=(sec1/10)%10;
P2=0xbf;
P0=0xff;
P0=table[a];
delay(1);
P2=0xdf;
P0=0xff;
P0=table_dot[b];
delay(1);
P2=0xef;
P0=0xff;
P0=table[c];
delay(1);
P2=0x7f;
P0=0xff;
P0=table[d];
delay(1);
P0=0xff;
}
/**************************************************/
/****************日期状态时的显示子函数************/
void display_date(uchar month,uchar day)
{
uchar a,b,c,d;
a=month/10;
b=month%10;
c=day/10;
d=day%10;
if(a==0) //如果月份的十位为零则只显示个位
{
P2=0xdf;
P0=0xff;
P0=table_dot[b];
delay(1);
P0=0xff;
}
else
{
P2=0xbf;
P0=0xff;
P0=table[a];
delay(1);
P2=0xdf;
P0=0xff;
P0=table_dot[b];
delay(1);
P0=0xff;
}
if(c==0)
{
P2=0x7f;
P0=0xff;
P0=table[d];
delay(1);
P0=0xff;
P0=0xff;
}
else
{
P2=0xef;
P0=0xff;
P0=table[c];
delay(1);
P2=0x7f;
P0=0xff;
P0=table[d];
delay(1);
P0=0xff;
P0=0xff;
}
}
/******************************************/
/****************键盘检测函数**************/
/******************************************/
void keyscan()
{
if(key1==0) //按下第一个键时钟将在正常状态、 秒表状态、 日期调整状态和
{ //闹铃调整状态之间循环切换
di(); //每按一下按键蜂鸣器”嘀”一下
delay(10);
if(key1==0)
{
mode++;
if(mode==4) mode=0; //mode取值范围为0~3, 故mode加到4时应清零
if(flag==1) mode=0; //如果在秒表状态、 日期调整状态或闹铃调整下进行了操作, 则flag将会被置1, 如果按下key1时检测到flag为1, 则直接返回到正常模式
if(mode==2||mode==3) adjust=2;
else adjust=0;
flag=0; //每次按下key1键时flag要置0
led=1; //切换模式时应使秒针指示灯熄灭
while(!key1);
}
}
if(key2==0&&mode!=1) //按下第二个按键时在小时/月份调整状态、 分钟/日期调整状态和非调整状态之间循环切换
{
di();
delay(10);
if(key2==0)
{
if(mode==0) //在正常状态下能够在小时/月份、 分钟/日期和非调整状态之间切换
{
if(adjust==0) adjust=3;
}
else //而在其它状态下只能小时/月份、 分钟/日期之间切换
{
if(adjust==1) adjust=3;
}
adjust--;
while(!key2);
}
}
if(key3==0) //在调整状态时按下该键时对应的变量加1
{
if(mode==0&&adjust==0) //在正常状态且非调整状态时按住该键将显示日期, 放开后恢复显示时间
{
date_display=1;
led=1; //按住时应保证秒针指示灯熄灭
}
else
{
flag=1; //按下该键后flag被置1
di();
delay(10);
if(key3==0)
{
switch(mode)
{
case 0: //mode为0时, 调整时间
if(adjust==1)
{
hour++;
if(hour==24) //当小时加到24时应该清零, 下面的同理
hour=0;
展开阅读全文