按键重新LED数码管倒数C语言,单片机之Protues模拟仿真-按键控制LED小灯和数码管99倒计时…

前言今天抽时间用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”符号的蓝色方块,可以进入查找原件的对话框中。如下图所示。

00cb669cc0a7df793f14cc2377d04484.png

通过输入关键字依次查找到如下原件

ae8080339958b3ccf1e19e5d545e8055.png

这个电路设计是比较简单的一种,程序设计也是要根据电路设计来进行编写的,如果有朋友可以尝试的话可以设计出更好的电路出来,也可以根据实际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进行处理,非常感谢!

上一篇 2021年4月16日
下一篇 2021年4月16日

相关推荐