目錄
一、前提
按鍵的原理圖
二、代碼配置
bsp_key.c文件
疑問
main.c文件
?main.c文件的詳細講解
功能實現
注意事項
一、前提
按鍵這一板塊主要是以記憶為主,我直接給大家講解代碼去實現我要配置的功能。本次我要做的項目是板子上的按鍵有S4~S19,我希望任意一個按鍵可以顯示對應的兩位數,按下兩個不同的按鍵可以一前一后各顯示出兩位數字,也就是生成四位數字,再按下另外一個按鍵實現清零的功能。
按鍵的原理圖
這是板子上按鍵的原理圖,如果要切換獨立按鍵和矩陣鍵盤,那么我們需要將板子上J5部分的小插口的東西插到對應的位置上去,本項目是在KBD上,12是KBD矩陣鍵盤,23是BTN獨立按鍵,如下圖:
那么如何掃描呢?答:先鎖定行,再鎖定列,舉個例子:假如說,我現在想要掃描S4這個按鍵,我們先要鎖定從左往右數第一列連接對應的引腳是P44,S4對應的行是P33
二、代碼配置
我們這里只用到Timer、init、seg、key,led,本文章沒寫的代碼可以去我這個藍橋杯第一個系列觀看,里面有很詳細的代碼簡介
bsp_key.c文件
#include "bsp_key.h"//函數名:按鍵碼值讀取函數
//入口參數:無
//返回值:按鍵的碼值
//函數功能:返回按鍵碼
unsigned char Key_Read(void)
{unsigned int Key_NEW;unsigned char Key_Value;//返回值P44 = 0;P42 = 1;P35 = 1;P34 = 1;//第一列掃描Key_NEW = P3 & 0X0F; //P3 = 0000 1000---P37~P30,高位無效,只看P33~P30P44 = 1;P42 =0;P35 = 1;P34 = 1;//第二列掃描Key_NEW = (Key_NEW << 4) | (P3 & 0X0F); //將原來的數值挪到次4位,本次數值放到最低4位,占用了8位P44 = 1;P42 =1;P35 = 0;P34 = 1;//第三列掃描Key_NEW = (Key_NEW << 4) | (P3 & 0X0F); //將原來的數值挪到次次4位,本次數值放到最低4位,占用了12位P44 = 1;P42 =1;P35 = 1;P34 = 0;//第三列掃描Key_NEW = (Key_NEW << 4) | (P3 & 0X0F); //將原來的數值挪到次次次4位,本次數值放到最低4位,占用了16位switch(~Key_NEW)//Key_Value的數值對應按鍵的編號{case 0X8000:Key_Value = 4;break;case 0X4000:Key_Value = 5;break;case 0X2000:Key_Value = 6;break;case 0X1000:Key_Value = 7;break;case 0X0800:Key_Value = 8;break;case 0X0400:Key_Value = 9;break;case 0X0200:Key_Value = 10;break;case 0X0100:Key_Value = 11;break;case 0X0080:Key_Value = 12;break;case 0X0040:Key_Value = 13;break;case 0X0020:Key_Value = 14;break;case 0X0010:Key_Value = 15;break;case 0X0008:Key_Value = 16;break;case 0X0004:Key_Value = 17;break;case 0X0002:Key_Value = 18;break;case 0X0001:Key_Value = 19;break;default :Key_Value = 0;}return Key_Value;}
疑問
在中switch中,為什么進行Key_New的取反?
答:一般來說,按鍵配置的時候,我們配置的是上拉輸入,在沒按按鍵的時候,對應的是高電平,按下去,是低電平,那么我們通過取反,就是按下去成為高電平1,利用哪個地方是1,進行選擇對應的case
main.c文件
#include "bsp_init.h"
#include "bsp_seg.h"
#include "Timer0.h"
#include "bsp_key.h"
#include "bsp_key.h"
#include "STDIO.H"/* 函數聲明 */
void Key_Proc(void);//按鍵處理
void Seg_Proc(void);//顯示處理/* 全局變量 */unsigned char seg_buf[8];//放置字符串轉換后的段碼到數組
unsigned char seg_string[10];//放置字符串
unsigned char pos = 0;//中斷顯示專用unsigned char Key_Value;//讀取按鍵的數值存儲變量
unsigned char Key_Down,Key_Old;unsigned char num_buffer[2] = {0, 0}; // 存儲2個按鍵編號
unsigned char num_count = 0; // 當前存儲的數字個數unsigned char Seg_Show_Num;//準備顯示出來的數值
void main()
{Cls_Peripheral();Timer0Init(); //1毫秒@12.000MHzEA = 1;while(1){Key_Proc();//按鍵處理Seg_Proc();//顯示處理}}/* Timer0 interrupt routine */
void tm0_isr() interrupt 1
{Seg_Disp( seg_buf, pos );if(++pos ==8) pos = 0;
}
/* Key_Proc */
void Key_Proc(void)//按鍵處理,底層數據變更
{Key_Value = Key_Read();//讀取按鍵按下的編號Key_Down = Key_Value & (Key_Old ^ Key_Value);//^異或(0000^0101)= 0101 0101 & 0101 = //0101 如果按鍵發生了下降沿的變化,輸出結果和本次按鍵數值相同//^異或(0101^0101)= 0000 0101 & 0000 = //0000 如果按鍵發生了下降沿的變化,輸出結果和本次按鍵數值相同Key_Old = Key_Value;if(Key_Down)//如果捕捉到下降沿跳變{if (num_count < 2) // 如果存儲的按鍵個數小于2{num_buffer[num_count++] = Key_Down; // 存儲按鍵編號}else // 如果已經存儲了兩個按鍵編號{// 清零操作num_count = 0; // 清空按鍵個數 }}
}/* Seg_Proc */
void Seg_Proc(void)//顯示處理,顯示信息生成
{if (num_count == 1) // 如果只存儲了一個按鍵編號{// 顯示第一個按鍵編號的兩位數字sprintf(seg_string, " %02d", (unsigned int)num_buffer[0]);}else if (num_count == 2) // 如果存儲了兩個按鍵編號{// 顯示兩個按鍵編號的四位數字sprintf(seg_string, " %02d%02d", (unsigned int)num_buffer[0], (unsigned int)num_buffer[1]);}else // 如果沒有存儲任何按鍵編號{// 顯示全0sprintf(seg_string, " 0000");}Seg_Tran( seg_string,seg_buf);}
?main.c文件的詳細講解
假如說,我現在按下去了S4,那么檢測到了S4處有下降沿,并且將這個數值給一個變量Key_Val,然后這個變量就給到了Seg_Show_Num,此刻還是一個二進制數,無法顯示到數碼管上,然后將這個Seg_Show_Num通過sprintf轉化成字符串,字符串在Seg_Disp函數下,將段碼轉化成能看懂的數字,最后利用定時器中斷每1ms進行刷新數碼管上的東西
-
顯示邏輯調整:? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? 在
Seg_Proc
函數中:-
如果
num_count
為0,顯示全0。 -
如果
num_count == 2
,顯示兩個按鍵編號的四位數字(如0405
)。 -
如果
num_count == 1
,只顯示第一個按鍵編號的兩位數字(如04
)。
-
-
按鍵邏輯調整:
在Key_Proc
函數中:-
如果
num_count == 2
,按下任意按鍵清零。 -
如果
num_count < 2
,存儲按鍵編號。
-
-
數碼管顯示位數調整:
數碼管的動態掃描范圍為8位,顯示內容通過sprintf
格式化為8位數碼管的顯示格式。
功能實現
-
按下第一個按鍵:
-
顯示該按鍵對應的兩位數字(如
04
)。
-
-
按下第二個按鍵:
-
顯示兩個按鍵對應的四位數字(如
0405
)。
-
-
按下任意第三個按鍵:
-
清零顯示內容,顯示
0000
。
-
注意事項
確保按鍵編號S4
到S19
與實際硬件的按鍵編號一致。
如果按鍵編號不是從4
到19
的連續數字,需要根據實際硬件調整按鍵編號的判斷邏輯。
顯示內容前面有4個空格,確保顯示內容在8位數碼管的中間位置。如果需要調整顯示位置,可以修改sprintf
中的空格數量。