程序實在論壇下的 不過發現只會用 改了IO口就用不了了 有沒有大佬能幫幫我怎么改 最好能寫下備注 讓我學習下怎么修改 附件放上。。。
/*************************************************本程序特點**********************************************************/
/* 1.連按與非連按:定義靜態變量使得連按標志僅在本程序內有效。工作原理:初次進入鍵盤
掃描函數,將連按標志置一,即初次按下;當有鍵按下的時候,會進入掃描函數,在掃描函數內
將標志位掛起,即按鍵已按下;當程序執行完此次掃描,下次進入的時候,首先判斷連按標志位
與鍵盤是否按下,如果按下了,但連按標志位是掛起的,那不進入此函數。接下來判斷鍵盤是否
處于釋放狀態,如果鍵盤是釋放的,則將標志位放下。否則,仍將標志位掛起。
2.端口的初始化,端口首先需要兩種端口,一種是推完輸出,另一種是上拉輸入(沒有信號時電平
為高),首先將輸出置低,如果有鍵按下,會得到相應的列的位置,近而分別置低相應的行,從
而得到按下的按鍵所在的行。
3.本程序略顯麻煩,但經過驗證,完全可用。在寫此程序時,網上有另一種方法,即不斷改變端口
的模式,判斷列時如此程序,接下來將兩種端口的模式換過來,將相應的列置低作為輸出,判斷
相應行的位置,由是得到位置坐標,通過公式換算即可,如對程序實時性要求較高,可嘗試此方
法。
*/
/*************************************************心得體會**************************************************************/
/* 1.使用if語句時一定要注意語句間的聯系,如同本程序,鍵盤掃描需要依次將各個行線置低,并不
是分別將行線置低。
2.熟悉輸入輸出方式,對不必要的端口置位復位進行取消,省略,以簡化程序。
3.switch 語句在使用時,一定要注意break的使用,所以在寫程序時,尤其像此類程序,可以套用
復制粘貼的,首先確保最初的程序一定要沒有基本錯誤。
4.有空的時候將變量標準化,利用define使代碼簡化易讀易改
*/
單片機源程序如下:
- #include "key4x4.h"
- #include "delay.h"
- //從高(H)1---低(L)4接的
- //按鍵初始化函數
- //PA15和PC5 設置成輸入
- void KEY_Init(void)
- {
-
- GPIO_InitTypeDef GPIO_InitStructure;
- RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE);//使能PORTA時鐘
- GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0|GPIO_Pin_1|GPIO_Pin_2|GPIO_Pin_3;//PA 0 1 2 3 H
- GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; //設置成推挽輸出
- GPIO_Init(GPIOA, &GPIO_InitStructure);//初始化GPIOA
-
- GPIO_InitStructure.GPIO_Pin = GPIO_Pin_4|GPIO_Pin_5|GPIO_Pin_6|GPIO_Pin_7;//PA 4 5 6 7 L
- GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU; //設置成上拉輸入
- GPIO_Init(GPIOA, &GPIO_InitStructure);//初始化GPIOA
-
- }
- //按鍵處理函數
- void BIXU(void)
- {
- RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOD, ENABLE);
- }
-
- int key_scan(void)
- {
- static u8 key_up=1;
- int key_num=0;
- u8 temp=0; //判斷列的數據緩存區
- u8 temp1=0; //判斷行的數據緩存區
- GPIO_ResetBits(GPIOA,GPIO_Pin_0|GPIO_Pin_1|GPIO_Pin_2|GPIO_Pin_3); //拉低行線
- delay_us(10);
- temp=GPIO_ReadInputData(GPIOA)&0xff; //讀出A的數據寄存器的值 ***0xff表示選擇低8(0~7)位 寫的話用或。讀就要用與 獲取高8位則將&0xff改成&0xff00
- delay_us(1);
- if (key_up&&(temp != 0xf0)) //判斷鍵是否按下與是否連按 ***0xf0表示獲得4~7位
- {
- delay_ms(10); //消抖
- key_up=0; //當有鍵按下時,將連按標志位掛起 屏蔽這一段為連按 太快把延時加長
- temp = GPIO_ReadInputData(GPIOA)&0xff; //消抖后重新得到A的值
- if(temp != 0xf0)
- {
- switch(temp) //進入鍵盤按下的相應行線
- {
- case 0xe0:
- {
-
- GPIO_SetBits(GPIOA,GPIO_Pin_1|GPIO_Pin_2|GPIO_Pin_3|GPIO_Pin_0); //依次從第一行拉低到第四行,讀出A的數據,從而判斷
- GPIO_ResetBits(GPIOA,GPIO_Pin_0); //是哪一行的鍵盤按下,從而給出相應的鍵值
- delay_us(10);
- temp1=GPIO_ReadInputData(GPIOA)&0xff;
- if (temp1==0xee)
- key_num=13;
- else
- {
- GPIO_SetBits(GPIOA,GPIO_Pin_1|GPIO_Pin_2|GPIO_Pin_3|GPIO_Pin_0);
- GPIO_ResetBits(GPIOA,GPIO_Pin_1);
- delay_us(1);
- temp1=GPIO_ReadInputData(GPIOA)&0xff;
-
- if (temp1==0xed)
- key_num=9;
- else
- {
- GPIO_SetBits(GPIOA,GPIO_Pin_1|GPIO_Pin_2|GPIO_Pin_3|GPIO_Pin_0);
- GPIO_ResetBits(GPIOA,GPIO_Pin_2);
- delay_us(1);
- temp1=GPIO_ReadInputData(GPIOA)&0xff;
-
- if (temp1==0xeb)
- key_num=5;
- else
- key_num=1;
- }
- }
- }
- break;
- case 0xd0:
- {
- GPIO_SetBits(GPIOA,GPIO_Pin_1|GPIO_Pin_2|GPIO_Pin_3|GPIO_Pin_0);
- GPIO_ResetBits(GPIOA,GPIO_Pin_0);
- delay_us(1);
- temp1=GPIO_ReadInputData(GPIOA)&0xff;
- if (temp1==0xde)
- key_num=14;
- else
- {
- GPIO_SetBits(GPIOA,GPIO_Pin_1|GPIO_Pin_2|GPIO_Pin_3|GPIO_Pin_0);
- GPIO_ResetBits(GPIOA,GPIO_Pin_1);
- delay_us(1);
- temp1=GPIO_ReadInputData(GPIOA)&0xff;
-
- if (temp1==0xdd)
- key_num=10;
- else
- {
- GPIO_SetBits(GPIOA,GPIO_Pin_1|GPIO_Pin_2|GPIO_Pin_3|GPIO_Pin_0);
- GPIO_ResetBits(GPIOA,GPIO_Pin_2);
- delay_us(1);
- temp1=GPIO_ReadInputData(GPIOA)&0xff;
-
- if (temp1==0xdb)
- key_num=6;
- else
- key_num=2;
- }
- }
- }
- break;
- case 0xb0:
- {
- GPIO_SetBits(GPIOA,GPIO_Pin_1|GPIO_Pin_2|GPIO_Pin_3|GPIO_Pin_0);
- GPIO_ResetBits(GPIOA,GPIO_Pin_0);
- delay_us(1);
- temp1=GPIO_ReadInputData(GPIOA)&0xff;
- if (temp1==0xbe)
- key_num=15;
- else
- {
- GPIO_SetBits(GPIOA,GPIO_Pin_1|GPIO_Pin_2|GPIO_Pin_3|GPIO_Pin_0);
- GPIO_ResetBits(GPIOA,GPIO_Pin_1);
- delay_us(1);
- temp1=GPIO_ReadInputData(GPIOA)&0xff;
-
- if (temp1==0xbd)
- key_num=11;
- else
- {
- GPIO_SetBits(GPIOA,GPIO_Pin_1|GPIO_Pin_2|GPIO_Pin_3|GPIO_Pin_0);
- GPIO_ResetBits(GPIOA,GPIO_Pin_2);
- delay_us(1);
- temp1=GPIO_ReadInputData(GPIOA)&0xff;
-
- if (temp1==0xbb)
- key_num=7;
- else
- key_num=3;
- }
- }
- }
- break;
- case 0x70:
- {
- GPIO_SetBits(GPIOA,GPIO_Pin_1|GPIO_Pin_2|GPIO_Pin_3|GPIO_Pin_0);
- GPIO_ResetBits(GPIOA,GPIO_Pin_0);
- delay_us(1);
- temp1=(GPIO_ReadInputData(GPIOA)&0xff);
- if (temp1==0x7e)
- key_num=16;
- else
- {
- GPIO_SetBits(GPIOA,GPIO_Pin_1|GPIO_Pin_2|GPIO_Pin_3|GPIO_Pin_0);
- GPIO_ResetBits(GPIOA,GPIO_Pin_1);
- delay_us(1);
- temp1=GPIO_ReadInputData(GPIOA)&0xff;
-
- if (temp1==0x7d)
- key_num=12;
- else
- {
- GPIO_SetBits(GPIOA,GPIO_Pin_1|GPIO_Pin_2|GPIO_Pin_3|GPIO_Pin_0);
- GPIO_ResetBits(GPIOA,GPIO_Pin_2);
- delay_us(1);
- temp1=GPIO_ReadInputData(GPIOA)&0xff;
-
- if (temp1==0x7b)
- key_num=8;
- else
- key_num=4;
- }
- }
- }
- break;
- default :return 0;
- }
- }
- }
- else if(temp == 0xf0)
- { //當沒有鍵按下后,將連按標志復位
- key_up=1;
- }
- return key_num;
- }
復制代碼
全部資料51hei下載地址:
完整.zip
(2.48 KB, 下載次數: 8)
2019-12-12 09:03 上傳
點擊文件名下載附件
矩陣按鍵
|