模拟电路图如图所示:
启动仿真后数码管显示初始时间:假设12-34-56
按下一拖三的开关P10,可以选择调节时,还是分还是秒。按一下调时,按两下调分钟,按三下调秒。按4下回到时。调整时的时候只有时的两位数显示,其他不显示,同理分和秒也是一样的。
如果按一下的情况下再按P11,则对应钟表数加一。
按下 P12后退出调整。数码管显示全部时间。并秒闪烁加一,跟真实的时间一样增加。
接线要和图片中一样。
AT89C51控制8位八段数码管显示时钟。
- 写回答
- 好问题 0 提建议
- 追加酬金
- 关注问题
- 邀请回答
-
7条回答 默认 最新
关注 引自免费微信小程序:皆我百晓生
为了实现您的需求,我们首先需要明确几个关键点:
- 时钟初始化:在程序开始时,设定一个初始时间(例如12小时34分56秒)。
- 按键控制逻辑:P10键用于切换调整模式(时、分、秒),P11键用于递增当前被调整的时间单位,P12键用于确认调整并使秒开始闪烁计数。
- 数码管显示:根据当前时间和调整模式,动态显示相应的数字,并处理秒的闪烁效果。
- 硬件连接:确保硬件连接与Proteus中的设计相匹配,这里主要关注P10、P11、P12以及数码管的控制。
硬件连接确认
- AT89C51的P0口通过上拉电阻连接到数码管的段选线(a~g, dp)。
- P2口的部分引脚(如P2.0至P2.7)可能用于控制数码管的位选线,具体取决于您实际的数码管连接方式。
- P10、P11、P12分别用于调整模式选择、时间增加和退出调整模式。
软件实现步骤
1. 初始化设置
#include<reg51.h> unsigned char DispCode[17] = {0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f, //0-9,A,b,C,d,E,F 0x77,0x7c,0x39,0x5e,0x79,0x71,0x00}; //G,H,I,J,K,L,.,-, unsigned char Time[3] = {12, 34, 56}; // 初始时间为12:34:56 char AdjustMode = 0; // 0-时,1-分,2-秒,用于记录当前调整的模式 bit FlashFlag = 0; // 用于控制秒的闪烁 void Delay(unsigned int i); void DisplayTime(); void IncTime(char mode); void main() { // 初始化 P0 = 0xff; // 确保段选线默认为高电平 P2 = 0x01; // 假设先点亮第一个数码管 while(1) { // 检查调整模式按键P10 if(P10 == 0) // 按下P10 { Delay(10); // 去抖动 if(P10 == 0) { AdjustMode = (AdjustMode + 1) % 3; // 循环切换调整模式 Delay(200); // 模式切换后等待一段时间 } } // 检查时间增加按键P11 if(P11 == 0) { Delay(10); // 去抖动 if(P11 == 0) { IncTime(AdjustMode); // 根据当前模式递增时间 } } // 检查退出调整模式按键P12 if(P12 == 0) { Delay(10); // 去抖动 if(P12 == 0) { FlashFlag = 1; // 开启秒闪烁,模拟真实时间计数 } } DisplayTime(); // 显示当前时间 } }
2. 显示时间函数
void DisplayTime() { static unsigned char digit = 0; // 记录当前显示的数码管位 static unsigned char secDisplay = Time[2]; // 用于处理秒的闪烁 // 根据FlashFlag控制秒的显示是否闪烁 if(FlashFlag && digit == 2) // 秒位且允许闪烁 { if(_crol_(0x80, digit)) // 使用闪烁标志控制显示 P0 = DispCode[secDisplay]; else P0 = 0xff; // 关闭该位显示 } else { P0 = DispCode[Time[digit]]; // 正常显示 } P2 = 0x01 << digit; // 位选,点亮对应的数码管 digit = (digit + 1) % 4; // 循环显示所有位 // 控制数码管刷新频率 Delay(5); } void IncTime(char mode) { Time[mode]++; if(mode == 0 && Time[mode] > 23) Time[mode] = 0; // 时钟调整 if(mode == 1 && Time[mode] > 59) Time[mode] = 0; // 分钟调整 if(mode == 2 && Time[mode] > 59) Time[mode] = 0; // 秒钟调整 }
3. 延时函数
void Delay(unsigned int i) { while(i--) { _nop_(); _nop_(); _nop_(); _nop_(); _nop_(); _nop_(); _nop_(); _nop_(); } }
注意事项
- 以上代码是一个基础框架,具体细节(如去抖动、数码管硬件接口等)需根据实际硬件电路进行调整。
- 确保硬件连接与代码中对端口的操作相匹配。
- 数码管的段选线控制和位选线控制应根据实际连接方式进行调整。
- 实际应用中可能还需要考虑低功耗设计、时间准确性等问题。
解决 无用评论 打赏 举报 编辑记录
悬赏问题
- ¥15 使用ESP8266连接阿里云出现问题
- ¥15 BP神经网络控制倒立摆
- ¥20 要这个数学建模编程的代码 并且能完整允许出来结果 完整的过程和数据的结果
- ¥15 html5+css和javascript有人可以帮吗?图片要怎么插入代码里面啊
- ¥30 Unity接入微信SDK 无法开启摄像头
- ¥20 有偿 写代码 要用特定的软件anaconda 里的jvpyter 用python3写
- ¥20 cad图纸,chx-3六轴码垛机器人
- ¥15 移动摄像头专网需要解vlan
- ¥20 access多表提取相同字段数据并合并
- ¥20 基于MSP430f5529的MPU6050驱动,求出欧拉角