|
本帖最后由 KeepYn 于 2021-7-6 21:58 編輯
51單片機獨立按鍵數(shù)碼管
基于普中51單片機開發(fā)板,運用定時器/計數(shù)器0。按鍵控制數(shù)碼管,實現(xiàn)60秒計時,數(shù)值加減清零。
前言
本程序涉及中斷,定時器的配置,數(shù)碼管動態(tài)掃描,獨立按鍵。程序基于模塊化編寫。詳細(xì)的注解,適合小白服用。
原文件下載按鍵控制數(shù)碼管實現(xiàn)顯示數(shù)值加減]:[按鍵控制數(shù)碼管實現(xiàn)顯示數(shù)值加減](https://download.csdn.net/download/qq_54311788/20048437)
嗶哩嗶哩演示視頻[按鍵+數(shù)碼管](https://www.bilibili.com/video/BV1Cv411J7Ch/)
一、獨立按鍵
獨立按鍵比較簡單,它們各自與獨立的輸入線相連接
4 條輸入線接到單片機的 I/O 口上,當(dāng)按鍵 K1 按下時,+5V 通過電阻 R1 然后再通過按鍵 K1 最終進(jìn)入 GND 形成一條通路,那么這條線路的全部電壓都加到了 R1 這個電阻上,KeyIn1 這個引腳就是個低電平。當(dāng)松開按鍵后,線路斷開,就不會有電流通過,那么 KeyIn1和+5V 就應(yīng)該是等電位,是一個高電平。我們就可以通過 KeyIn1 這個 IO 口的高低電平來判斷是否有按鍵按下。

在按鍵被按下的短暫一瞬間,由于硬件上的抖動,往往會產(chǎn)生幾毫秒的抖動,在這時候若采集信號,勢必導(dǎo)致誤操作,甚至系統(tǒng)崩潰;同樣,在釋放按鍵的那一刻,硬件上會相應(yīng)的產(chǎn)生抖動,會產(chǎn)生同樣的后果。因此,在模擬或者數(shù)字電路中,我們要避免在最不穩(wěn)定的時候采集信號,進(jìn)行操作。因此需要對獨立按鍵進(jìn)行一個消抖處理。
### 其他相關(guān)
有關(guān)數(shù)碼管,可以去看我的另一篇博文[51單片機數(shù)碼管顯示60秒倒計時(C語言)]51單片機數(shù)碼管顯示60秒倒計時(C語言程序) - 51單片機 (51hei.com)
下面咱們直接上代碼,我分為主函數(shù)部分硬件部分和軟件部分代碼
二、代碼
1.MAIN
#include "hardware.h"
#include "software.h"
void main()
{
timing(); //初始化定時函數(shù)
while(1)
{
tube();//數(shù)碼管服務(wù)函數(shù)(不斷對數(shù)碼管進(jìn)行掃描)
KEY();//獨立按鍵服務(wù)函數(shù)(不斷對獨立按鍵進(jìn)行掃描)
}
}
2.硬件部分代碼
//按鍵、數(shù)碼管
#include "hardware.h"
#include "software.h" //調(diào)用此函數(shù)的變量(因此包含此文件)
//共陰數(shù)碼管段碼
uchar code block[16] = {0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,
0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71}; //定義無符號字符型類型數(shù)組來儲存段碼
void tube() //數(shù)碼管掃描函數(shù)
{
uchar i; //定義i變量
for(i=2;i<4;i++)
{
switch(i)
{
case(0): //位選,第一個數(shù)碼管
LSA=1;
LSB=1;
LSC=1;
P0 = block[num/1000%10]; //千位數(shù)拆分
break;
case(1): //位選,第一個數(shù)碼管
LSA=0;
LSB=1;
LSC=1;
P0 = block[num/100%10]; //百位數(shù)拆分
break;
case(2):
LSA=1;
LSB=0;
LSC=1;
P0 = block[num/10%10]; //十位數(shù)拆分
break;
case(3):
LSA=0;
LSB=0;
LSC=1;
P0 = block[num/1%10]; //個位數(shù)拆分
break;
}
delayms(5); //延時一會(視覺殘留)
P0=0x00; //消影
}
}
//獨立按鍵
void KEY()
{
if(K1 == 0) //判斷按鍵是否按下
delayms(5); //消抖
if(K1 == 0) //確認(rèn)按鍵按下,執(zhí)行
{
num++;
if(num == 60)
num = 0;
while(!K1); //檢測按鍵是否松開
}
if(K2 == 0) //判斷按鍵是否按下
delayms(5); //消抖
if(K2 == 0) //確認(rèn)按鍵按下,執(zhí)行
{
num--;
if(num == 0)
num = 60;
while(!K2); //檢測按鍵是否松開
}
if(K3 == 0) //判斷按鍵是否按下
delayms(5); //消抖
if(K3 == 0) //確認(rèn)按鍵按下,執(zhí)行
{
num = 0;
while(!K3); //檢測按鍵是否松開
}
if(K4 == 0) //判斷按鍵是否按下
delayms(5); //消抖
if(K4 == 0) //確認(rèn)按鍵按下,執(zhí)行
{
while(!K4); //檢測按鍵是否松開
TR0=~TR0;
}
}
3.軟件部分代碼
#include "software.h"
uchar numm; //定義數(shù)據(jù)類型為無符號字符型類型
uchar num; //定義數(shù)據(jù)類型為無符號字符型類型
void delayms(uint xms) //簡單延時
{
uint a , b;
for(a=xms; a>0; a--)
for(b=110; b>0; b--);
}
void timing() //初始化定時器函數(shù)
{
TMOD = 0X01;
TH0 = (65536-45872)/256; //裝初值,11.0592M晶振,定時50ms,計數(shù)個數(shù) N = 45872(在計數(shù)時需要預(yù)先填裝初始計數(shù)個數(shù))
TL0 = (65536-45872)%256;
EA = 1;
ET0 = 1;
}
void Timer0_Rountine(void) interrupt 1 //中斷號 定時器/計數(shù)器0中斷 1為定時器/計數(shù)器0的中斷號(重要)
{
TH0 = (65536-45872)/256; //方式1需要重裝初值
TL0 = (65536-45872)%256;
numm++; //mun變量自加1
if(numm == 20) //判斷定時時間是否等于1s 為真之后 LED燈的電平狀態(tài)轉(zhuǎn)換
{
numm = 0; //清零,好判斷下次計時
LED =~ LED;//電平狀態(tài)取反
num++;
if(num == 60)
num = 0;
}
}
4.相關(guān)H文件程序代碼
#ifndef __HARDWARE_H__
#define __HARDWARE_H__
#include <reg51.h> //51單片機頭文件
//數(shù)碼管 138譯碼器
sbit LSA=P2^2;
sbit LSB=P2^3;
sbit LSC=P2^4;
//LED燈
sbit LED=P2^0;
//獨立按鍵
sbit K1 =P3^1; //定義按鍵1
sbit K2 =P3^0;
sbit K3 =P3^2;
sbit K4 =P3^3;
typedef unsigned int uint; // typedef(類型定義) 用來給無符號整型類型數(shù)據(jù) unsigned int 定義新名字 uint
typedef unsigned char uchar; //用來給無符號字符型類型數(shù)據(jù) unsigned char 定義新名字 uchar
extern uint; //聲明給外部函數(shù)使用
extern uchar; //聲明給外部函數(shù)使用
extern void tube(void); //數(shù)碼管掃描函數(shù)
extern void KEY();
#endif
#ifndef __SOFTWARE_H__
#define __SOFTWARE_H__
#include <hardware.h> //包含此頭文件,以便在此C文件中調(diào)用
extern void delayms(uint xms); //簡單延時
extern void timing(); //初始化定時器函數(shù)
extern uchar num; //聲明給外部函數(shù)使用
#endif
|
-
-
按鍵+數(shù)碼管.rar
2021-7-6 21:55 上傳
點擊文件名下載附件
下載積分: 黑幣 -5
51.9 KB, 下載次數(shù): 28, 下載積分: 黑幣 -5
評分
-
查看全部評分
|