前言今天抽时间用protues软件仿真了一个按键控制LED小灯和数码管99倒计时的单片机小程序,就拿来和大家分享一下吧。
本次展示的仿真是通过51单片机的C语言进行程序的编写,相信学习单片机的小伙伴对51单片机和C语言的基础知识应该是有的,在此我就不详细介绍单片机的基础知识。希望大家能够理解。
原理
通过P0.0到P0.3四个按键控制LED小灯的亮灭和数码管的99倒计时。现象功能为:程序运行后按下K1按键第一次八个LED小灯同时亮起,按下K1按键第二次八个LED小灯中奇数小灯亮偶数小灯灭,按下K1按键第三次八个LED小灯中偶数数小灯亮奇数小灯灭,当按下K1按键第四次时八个LED小灯全灭。
当按下K2按键时数码管开始倒计时(还可以根据控制LED小灯一样控制数码管暂停和清零,本次实验就不展示了,下次有时间再给大家补充一下)
电路图
我们通过protues进行电路仿真,首先打开protues软件并进行创建项目,然后进行设计电路。在设计电路图前我们需要先把电路中所需要用到的原件进行找到。寻找原件我们可以在左边工具栏中选择第二个,然后点击“P”符 的蓝色方块,可以进入查找原件的对话框中。如下图所示。
通过输入关键字依次查找到如下原件
这个电路设计是比较简单的一种,程序设计也是要根据电路设计来进行编写的,如果有朋友可以尝试的话可以设计出更好的电路出来,也可以根据实际51单片机的开发板来设计电路,当然你设计的电路不同,程序也就有点不同了,但具体思路还是大致相同的。
代码设计#include
#include
//函数定义
void jishu(); //数码管计数
void initeConfig(); //初始化配置
void changeLED(); //LED小灯改变
void startDaojishu(); //数码管倒计时开始计数
//按键IO定义
sbit K0=P0^0;
sbit K1=P0^1;
sbit K2=P0^2;
sbit K3=P0^3;
//数码管显示控制io引脚定义
sbit ADDR0=P3^0;
sbit ADDR1=P3^1;
sbit ADDR2=P3^2;
sbit ADDR3=P3^3;
sbit ADDR4=P3^4;
sbit ADDR5=P3^5;
unsigned char KeySta[4] = {1,1,1,1}; //4个按键状态定义
unsigned char backup[4] = {1,1,1,1}; //4个按键状态缓冲区定义
unsigned char flags=0; //数码管一秒计时状态标志
unsigned int cnt1=0; //一秒计时变量
unsigned char i=0; //for循环控制变量
unsigned char start=0; //开始倒计时按键按下标志
unsigned char cnt = 0; //LED小灯状态控制变量
unsigned long sec=100; //99倒计时数值变量
unsigned char code LedChar[]={ //数码管0到F显示的十六进制值的初始化
0xC0,0xF9,0xA4,0xB0,0x99,0x92,0x82,0xF8,
0x80,0x90,0x88,0x83,0xC6,0xA1,0x86,0x8E
};
unsigned char LedBuff[6]={ //六个数码管的缓存数组
0xFF,0xFF,0xFF,0xFF,0xFF,0xFF
};
void main(void){
initeConfig(); //环境初始化
while (1){
if(start==1){ //当start=1时开始倒计时
startDaojishu();
}
for(i=0;i<4;i++){ //循环判断四个按键是否被按下
if(KeySta[i] != backup[i]){
if(backup[i] == 0){
if(i==1){ //如果K1按键按下时改变LED小灯的状态
changeLED();
}
else if(i==2){ //如果K1按键按下时
start=1; //开始倒计时按键按下标志赋值为1 表示开始倒计时
}
}
backup[i] = KeySta[i];
}
}
}
}
void initeConfig(){
K1=1;
EA = 1;
TMOD = 0x01;
TH0=0xFC;
TL0=0x67;
ET0 = 1;
TR0 = 1;
}
void changeLED(){
cnt++;
if(cnt==1){ //k1按键按下第一次小灯全亮
P2=0x00;
}
else if(cnt==2){ //k1按键按下第二次奇数小灯全亮
P2=0xAA;
}
else if(cnt==3){ //k1按键按下第三次偶数小灯全亮
P2=~P2;
}
else if(cnt==4){ //k1按键按下第四次小灯全灭
P2=0xFF;
cnt=0;
}
}
void jishu(){
cnt1++;
if(cnt1>=1000){ //时钟中断时间为1ms 所以当在第一千次中断时为一秒,数码管倒计时减1
cnt1=0;
flags=1;
}
P1=0xFF;
//这是通过人眼的视觉暂停效应进行同时显示多个数码管,但实际上时每1ms只显示一个数码管的
if(i==0){
ADDR5=1; ADDR4=0; ADDR3=0;ADDR2=0; ADDR1=0; ADDR0=0; i++; P1=LedBuff[0]; //给第六个数码管io引脚实时赋值
}
else if(i==1){
ADDR5=0; ADDR4=1; ADDR3=0;ADDR2=0; ADDR1=0; ADDR0=0; i=0; P1=LedBuff[1]; //给第五个数码管io引脚实时赋值
}
}
void startDaojishu(){
if(flags==1){ //当计时1s到了时,数码管倒计时减1
flags=0;
sec–;
//减1后分别给每个数码管的显示值赋值,比如sec=98时,数码管个位sec%10=8,十位sec/10%10=9
//然后在让数码管缓存的0 元素和1 元素分别存储数码管显示位是8和9的十六进制值,让他们在jishu函数中进行赋值到io引脚上从而让数码管显示相应的数字
LedBuff[0]=LedChar[sec%10];
LedBuff[1]=LedChar[sec/10%10];
if(sec==0)
sec=99;
}
}
//T0计时器中断函数,中断时间到了就判断四个按键的状态,并进行按键消抖操作。
void InterruptTimer0() interrupt 1{
static unsigned char keybuf[] = {0xFF,0xFF,0xFF,0xFF};
char i=0;
TH0=0xFC;
TL0=0x67;
keybuf[0] = (keybuf[0] << 1) | K0;
keybuf[1] = (keybuf[1] << 1) | K1;
keybuf[2] = (keybuf[2] << 1) | K2;
keybuf[3] = (keybuf[3] << 1) | K3;
for(i=0;i<4;i++){
if(keybuf[i] == 0x00){
KeySta[i] = 0;
}
else if(keybuf[i] != 0x00){
KeySta[i] = 1;
}
}
if(start==1){
jishu();
}
}
By:star147
Time:2020/3/23
文章知识点与官方知识档案匹配,可进一步学习相关知识C技能树首页概览113095 人正在系统学习中 相关资源:倒计时软件.exe_倒计时电脑软件-管理软件工具类资源-CSDN文库
声明:本站部分文章及图片源自用户投稿,如本站任何资料有侵权请您尽早请联系jinwei@zod.com.cn进行处理,非常感谢!