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

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