日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

stm32以中断方式扫描矩阵键盘

發布時間:2023/12/10 编程问答 37 豆豆
生活随笔 收集整理的這篇文章主要介紹了 stm32以中断方式扫描矩阵键盘 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

stm32矩陣鍵盤

  • 矩陣鍵盤
  • cubemx配置
  • 編程思路
  • 代碼編寫

矩陣鍵盤

普通的按鍵,都是一個IO口控制一個按鍵,但是當按鍵數量變多時,單片機可能沒有那么多的IO口來供給按鍵使用,這時候就需要用到矩陣鍵盤,比如45的矩陣鍵盤,用到了4+5共9根IO口線,可以控制45=20個按鍵。相應的,程序也要復雜些。

cubemx配置

X0到X3這4個IO口配置為低電平輸出,無上拉,無下拉,即推挽方式,速度為中
Y0到Y4這5個IO口配置為EXTI外部中斷模式,上拉,下降沿觸發。

編程思路

1 X0~3配置為輸出低電平
2 Y0~4配置為下降沿中斷,但是芯片內部配置了上拉,所以無按鍵觸發時不會進中斷。
3 當有按鍵按下,比如X2Y4按下時,X2路的低電平會進入到Y4路,觸發下降沿中斷。
4 在Y4中斷內,將Y4配置為低電平輸出,而X0~3配置為上拉輸入,記錄下Y值為4
5 逐一檢測X0~3的電平,哪一路為低,即對應的為X鍵值,本例X值為2
6 綜合x=2, y=4, 即可知道是哪一個按鍵按下了。

代碼編寫

定義一個結構體,有按鍵觸發時,active置1,x,y分別記錄行列值,num是最后的鍵值。

typedef struct KEYBOARD_TYPEDEF {u8 active;u8 x;u8 y;u8 num; }KEYBOARD_Typedef;KEYBOARD_Typedef keyboard;

以Y4為例,列出一路中斷如下:

void EXTI15_10_IRQHandler(void) {/* USER CODE BEGIN EXTI15_10_IRQn 0 */if(__HAL_GPIO_EXTI_GET_FLAG(KEY_Y4_Pin)){delay_us(10);if(KEY_Y4_READ() != 0){HAL_GPIO_EXTI_IRQHandler(KEY_Y4_Pin);return;}delay_us(10);if(KEY_Y4_READ() != 0){HAL_GPIO_EXTI_IRQHandler(KEY_Y4_Pin);return;}delay_us(10);if(KEY_Y4_READ() != 0){HAL_GPIO_EXTI_IRQHandler(KEY_Y4_Pin);return;}keyboard.active = 1;keyboard.y = 4;}keyboard_scan();/* USER CODE END EXTI15_10_IRQn 0 */HAL_GPIO_EXTI_IRQHandler(KEY_Y4_Pin);/* USER CODE BEGIN EXTI15_10_IRQn 1 *//* USER CODE END EXTI15_10_IRQn 1 */ }

增加了幾次延時,作為鍵盤消抖的判斷
確認不是誤觸發后,active置1,并相應的y值。
最后調用鍵盤掃描函數,來確認X的鍵值。
.
.

引腳功能模式切換

//切換GPIO引腳的方向 //port 端口號 //pin號 //dir 方向,0為輸入,1為輸出, 2為EXTI void pin_io_switch(GPIO_TypeDef *port, u32 pin, u8 mode) {switch(mode){ case GPIO_IN://輸入GPIO_InitStruct.Pin = pin;GPIO_InitStruct.Mode = GPIO_MODE_INPUT;GPIO_InitStruct.Pull = GPIO_PULLUP;HAL_GPIO_Init(port, &GPIO_InitStruct);break;case GPIO_OUT://輸出GPIO_InitStruct.Pin = pin;GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;GPIO_InitStruct.Pull = GPIO_NOPULL;GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_MEDIUM;HAL_GPIO_Init(port, &GPIO_InitStruct);break;case GPIO_EXTI:GPIO_InitStruct.Pin = pin;GPIO_InitStruct.Mode = GPIO_MODE_IT_FALLING;GPIO_InitStruct.Pull = GPIO_PULLUP;HAL_GPIO_Init(port, &GPIO_InitStruct);break;} }

.
.
本函數用來確認X軸的鍵值。

void keyboard_scan(void) {u16 i,j;u8 x0, x1, x2, x3;u8 temp, current;if(keyboard.active == 0)return;//關中斷HAL_NVIC_DisableIRQ(EXTI3_IRQn); HAL_NVIC_DisableIRQ(EXTI4_IRQn);HAL_NVIC_DisableIRQ(EXTI9_5_IRQn);HAL_NVIC_DisableIRQ(EXTI15_10_IRQn);//X0~3切換為輸入狀態pin_io_switch(KEY_X0_PORT, KEY_X0_Pin, GPIO_IN); //X0 PC13pin_io_switch(KEY_X1_PORT, KEY_X1_Pin, GPIO_IN); //X1 PC14pin_io_switch(KEY_X2_PORT, KEY_X2_Pin, GPIO_IN); //X2 PC15pin_io_switch(KEY_X3_PORT, KEY_X3_Pin, GPIO_IN); //X3 PB7//只將相應的一路Y口切換為輸出狀態,Y的數值,在中斷函數中設置過switch(keyboard.y){case 0:pin_io_switch(KEY_Y0_PORT, KEY_Y0_Pin, GPIO_OUT);KEY_Y0_SET(0); //Y0 PB6break;case 1:pin_io_switch(KEY_Y1_PORT, KEY_Y1_Pin, GPIO_OUT);KEY_Y1_SET(0); //Y0 PB5break;case 2:pin_io_switch(KEY_Y2_PORT, KEY_Y2_Pin, GPIO_OUT);KEY_Y2_SET(0); //Y0 PB4break;case 3:pin_io_switch(KEY_Y3_PORT, KEY_Y3_Pin, GPIO_OUT);KEY_Y3_SET(0); //Y0 PB3break;case 4:pin_io_switch(KEY_Y4_PORT, KEY_Y4_Pin, GPIO_OUT);KEY_Y4_SET(0); //Y0 PA15break;}//讀取X軸的狀態x0 = KEY_X0_READ(); //X0 PC13x1 = KEY_X1_READ(); //X1 PC14x2 = KEY_X2_READ(); //X2 PC15x3 = KEY_X3_READ(); //X3 PB7if(x0 == 0)keyboard.x = 3; //X方向從左開始為x3, x2, x1, x0else if(x1 == 0)keyboard.x = 2; //與電路圖上相反,下一版電路要把方向改過來,改為x0,x1,x2,x3else if(x2 == 0)keyboard.x = 1;else keyboard.x = 0;keyboard.num = keyboard.y*4 + keyboard.x; //計算鍵值,0~19//將Y口配置為EXTI,上拉pin_io_switch(KEY_Y0_PORT, KEY_Y0_Pin, GPIO_EXTI);pin_io_switch(KEY_Y1_PORT, KEY_Y1_Pin, GPIO_EXTI);pin_io_switch(KEY_Y2_PORT, KEY_Y2_Pin, GPIO_EXTI);pin_io_switch(KEY_Y3_PORT, KEY_Y3_Pin, GPIO_EXTI);pin_io_switch(KEY_Y4_PORT, KEY_Y4_Pin, GPIO_EXTI);//將X口配置為輸出,低電平pin_io_switch(KEY_X0_PORT, KEY_X0_Pin, GPIO_OUT);pin_io_switch(KEY_X1_PORT, KEY_X1_Pin, GPIO_OUT);pin_io_switch(KEY_X2_PORT, KEY_X2_Pin, GPIO_OUT);pin_io_switch(KEY_X3_PORT, KEY_X3_Pin, GPIO_OUT);KEY_X0_SET(0);KEY_X1_SET(0);KEY_X2_SET(0);KEY_X3_SET(0);HAL_NVIC_EnableIRQ(EXTI3_IRQn);HAL_NVIC_EnableIRQ(EXTI4_IRQn);HAL_NVIC_EnableIRQ(EXTI9_5_IRQn);HAL_NVIC_EnableIRQ(EXTI15_10_IRQn); }

最后在主程序中檢查keyboard.active,若不為0,則表示有按鍵按下,此時需要做相應處理,并且將keyboard中的各成員清零。

總結

以上是生活随笔為你收集整理的stm32以中断方式扫描矩阵键盘的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。