51单片机八位数码管时钟电路仿真
程序员文章站
2022-05-27 17:26:03
...
电路图文件以及详细视频介绍请到B站评论区拿取
https://www.bilibili.com/video/BV1Ht4y1975h
仿真电路图
系统设计
1、方案(系统结构框图、器件选型)
器件选型有:AT89C51模块,八位阳极数码管显示模块,两个独立按键模块,还有P1口作为I/O口需要外加上拉电阻的电阻排,由于仿真的单片机模块内有时钟电路以及复位电路,这里省略了。
2、硬件设计与分析
电路原理图如图所示,P0口作为I/O口时需要外加上拉电阻,外接了一个电阻排,P2口接两个锁存器,分别控制数码管的位选和段选,给它的使能端口LE送高电平就开始工作,还要注意数码管采用的是共阴极接法。
这两个锁存器的工作原理是通过单片机控制。
先打开一个锁存器,选择一个位码,然后关闭,再打开另一个锁存器,选择一个要显示的断码, 采用独立按键接口电路控制8位共阴极数码管,采用中断方式K1按下调时,K2按下时调分,数码管初始显示时间为08-30-59.
3、软件设计与分析(流程图、代码)
流程图如下:
下面是代码:
#include <reg51.h>
sbit key1 = P1^0;
bit flag1s = 0;
bit KeySta = 1;
unsigned char hour = 8;
unsigned char minute = 30;
unsigned char second = 59;
unsigned char mode = 0;
void FreshTime();
void TimeInit();
void IntInit();
void InitLedBuff();
void keyscan();
unsigned char code LedChar[] = { //共阴数码管显示字符转换表
0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,
0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71,0x40,0x00};
unsigned char LedBuff[8] = { //数码管显示缓冲区
0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff};
void main()
{
TimeInit();
IntInit();
InitLedBuff();
while(1)//显示内容处理
{
if(flag1s&&!mode) //时间显示模式
{
flag1s = 0;
FreshTime();
}
else if(mode == 1) //校准分钟
{
LedBuff[0] = 17;
LedBuff[1] = 17;
LedBuff[4] = 17;
LedBuff[5] = 17;//不显示
LedBuff[6] = 17;
LedBuff[7] = 17;
LedBuff[2] = minute/10;
LedBuff[3] = minute%10;
}
else if(mode == 2) //校准小时
{
LedBuff[2] = 17;
LedBuff[3] = 17;
LedBuff[4] = 17;
LedBuff[5] = 17;//不显示
LedBuff[6] = 17;
LedBuff[7] = 17;
LedBuff[0] = hour/10;
LedBuff[1] = hour%10;
}
else if(mode == 3) //校准完成重新显示
{
InitLedBuff();
mode = 0;
}
keyscan();
}
}
void InitLedBuff()//初始化时间到显示缓冲区
{
LedBuff[0] = hour/10;
LedBuff[1] = hour%10;
LedBuff[2] = minute/10;
LedBuff[3] = minute%10;
LedBuff[4] = second/10;
LedBuff[5] = second%10;
}
void FreshTime()//刷新时间到显示缓冲区
{
second++;
if(second == 60)//进位
{
second = 0;
minute++;
LedBuff[2] = minute/10;
LedBuff[3] = minute%10;
if(minute == 60)//进位
{
minute = 0;
hour++;
if(hour == 24)
hour = 0;
LedBuff[0] = hour/10;
LedBuff[1] = hour%10;
}
}
LedBuff[4] = second/10;
LedBuff[5] = second%10;
}
void TimeInit()//定时器初始化
{
TMOD = 0X11; //设置定时器为模式1
TL0 = 0xB0;
TH0 = 0x3C; //定时初值 50ms
TL1 = 0x18; //
TH1 = 0xFC; //定时初值 1ms
TR0 = 1; //定时器0开始计时
TR1 = 1; //定时器1开始计时
ET1 = 1; //使能定时器1
ET0 = 1; //使能定时器0
PT0 = 1; //提高计时准确性,提高定时器0中断优先级
EA = 1; //打开总中断
}
void IntInit()//外部中断初始化
{
IT0 = 1; //下降沿触发
EX0 = 1; //使能外部中断0
}
void keyscan() //按键扫描及处理
{
static bit backup = 1;
if (KeySta != backup) //当前值与前次值不相等说明此时按键有动作
{
if (backup == 0) //如果前次值为0,则说明当前是弹起动作
{
if(mode == 1) //校准分钟时,分钟加一
{
minute++;
if(minute==60)
minute = 0;
}
else if(mode == 2) //校准小时,小时加一
{
hour++;
if(hour==24)
hour = 0;
}
}
backup = KeySta; //更新备份为当前值,以备进行下次比较
}
}
void Int0() interrupt 0
{
mode++;
if(mode == 4)
{
mode = 0;
}
}
void Ledfresh() //数码管显示刷新
{
static unsigned char i = 0;
switch(i)
{
case 0 : P2 = ~(0x01<<i);P0 = LedChar[LedBuff[i]];i++;break;
case 1 : P2 = ~(0x01<<i);P0 = LedChar[LedBuff[i]];i++;break;
case 2 : P2 = ~(0x01<<i);P0 = 0x40;i++;break;//时分间隔线
case 3 : P2 = ~(0x01<<i);P0 = LedChar[LedBuff[2]];i++;break;
case 4 : P2 = ~(0x01<<i);P0 = LedChar[LedBuff[3]];i++;break;
case 5 : P2 = ~(0x01<<i);P0 = 0x40;i++;break;//分秒间隔线
case 6 : P2 = ~(0x01<<i);P0 = LedChar[LedBuff[4]];i++;break;
case 7 : P2 = ~(0x01<<i);P0 = LedChar[LedBuff[5]];i=0;break;
}
}
void Time0() interrupt 1 // 50ms
{
static unsigned char n = 0;
TL0 = 0xB0;
TH0 = 0x3C;
n++;
if(n==20)
{
n=0;
flag1s = 1;//1s标志位
}
}
void Time1() interrupt 3 // 1ms
{
static unsigned char keybuff = 0xff;
TL1 = 0x18; //
TH1 = 0xFC; //定时初值 1ms
Ledfresh();
keybuff = (keybuff<<1)|key1;
if (keybuff == 0x00)
{ //连续8次扫描值都为0,即16ms内都只检测到按下状态时,可认为按键已按下
KeySta = 0;
}
else if (keybuff == 0xFF)
{ //连续8次扫描值都为1,即16ms内都只检测到弹起状态时,可认为按键已弹起
KeySta = 1;
}
else
{} //其它情况则说明按键状态尚未稳定,则不对KeySta变量值进行更新
}
//电路图文件以及详细视频介绍请到B站评论区拿取https://www.bilibili.com/video/BV1Ht4y1975h
``
上一篇: 5种爱的语言,可以增进情侣的感情
下一篇: 分享一下谈恋爱的感觉