由于中断方式去抖时需要采用定时器,且HAL下中断5-9为同一个中断处理函数,没有现成的获取当前中断源接口(也许是没有找到),需要读取寄存器获取当前中断源。所以采用使用比较广泛的轮询方式实现。
基于方便移植等,做了多个封装及注释;
源码如下:
基于STM32F429,正点原子基础上移植
keypad.h
#ifndef _KEYPAD_H
#define _KEYPAD_H
#ifdef __cplusplus
extern "C" {
#endif
#include "sys.h"
#define KEY_ROW_NUM 3
#define KEY_COL_NUM 3
typedef struct _STRUCT_GPIO_
{
GPIO_TypeDef* GPIOx;
uint16_t GPIO_Pin;
}GpioStruct, *pGpioStruct;
typedef struct _STRUCT_KEYPAD_
{
GpioStruct rowNum[KEY_ROW_NUM];
GpioStruct colNum[KEY_COL_NUM];
}KeypadGpioStruct, *pKeypadGpioStruct;
void KEY_Init(void);//IO³õʼ»¯
int key_scan(void); //°´¼üɨÃ躯Êý
#ifdef __cplusplus
}
#endif
#endif
keypad.c
//#include "exti.h"
#include "delay.h"
#include "led.h"
#include "keypad.h"
//ÐÐÁмüÖµ²ÉÓöþάÊý×鷽ʽ£¬¸ù¾ÝÐèÒªÐ޸ĶÔÓ¦¼üÖµ£»
u32 keyVal[KEY_COL_NUM][KEY_ROW_NUM] =
{
//col0
1, //row0
2, //row1
3, //row2
//col1
4, //row0
5, //row1
6, //row2
//col2
7, //row0
8, //row1
9, //row2
};
//ÐÐÁжÔÓ¦Ó²¼þIO£¬²ÉÓýṹÌ帳ֵ·½Ê½£¬·½±ãÒÆÖ²£»
KeypadGpioStruct keypadio =
{
{{GPIOC, GPIO_PIN_1}, {GPIOH, GPIO_PIN_2}, {GPIOH, GPIO_PIN_3}}, //rowNum[KEY_ROW_NUM]
{{GPIOC, GPIO_PIN_4}, {GPIOC, GPIO_PIN_5}, {GPIOC, GPIO_PIN_6}} //colNum[KEY_COL_NUM]
};
//°´¼ü³õʼ»¯º¯Êý
//PA15ºÍPC5 ÉèÖóÉÊäÈë
void KEY_Init(void)
{
GPIO_InitTypeDef GPIO_Initure;
__HAL_RCC_GPIOC_CLK_ENABLE(); //¿ªÆôGPIOBʱÖÓ
__HAL_RCC_GPIOH_CLK_ENABLE(); //¿ªÆôGPIOBʱÖÓ
GPIO_Initure.Pin=GPIO_PIN_1; //PC1
GPIO_Initure.Mode=GPIO_MODE_OUTPUT_PP; //ÍÆÍìÊä³ö
GPIO_Initure.Pull=GPIO_PULLUP; //ÉÏÀ
GPIO_Initure.Speed=GPIO_SPEED_HIGH; //¸ßËÙ
HAL_GPIO_Init(GPIOC,&GPIO_Initure);
GPIO_Initure.Pin=GPIO_PIN_2|GPIO_PIN_3; //PH2£¬PH3
HAL_GPIO_Init(GPIOH,&GPIO_Initure);
HAL_GPIO_WritePin(GPIOC, GPIO_PIN_1, GPIO_PIN_SET); //PH7ÖÃ1
HAL_GPIO_WritePin(GPIOH, GPIO_PIN_2|GPIO_PIN_3, GPIO_PIN_SET); //PH7ÖÃ1
GPIO_Initure.Pin=GPIO_PIN_4|GPIO_PIN_5|GPIO_PIN_6; //PC4.PC5£¬PC6
GPIO_Initure.Mode=GPIO_MODE_INPUT; //ÊäÈë
GPIO_Initure.Pull=GPIO_PULLDOWN; //ÏÂÀ Ó²¼þµç·ÓÐÉÏÀ
HAL_GPIO_Init(GPIOC,&GPIO_Initure);
}
//°´¼ü´¦Àíº¯Êý
int key_scan(void)
{
static u8 key_up=1;
u8 keyUpFlag = 0;
u32 key_num=0;
u8 valValid = 0;
u8 icol, irow;
GPIO_PinState val_col[KEY_COL_NUM] = {0}; //ÓÃÓÚ´æ´¢ÁжÔÓ¦IOÖµ£¨0 or 1£©
//ÅäÖÃÐÐÊä³öΪ¸ß
for(irow = 0; irow < KEY_ROW_NUM; irow++)
{
HAL_GPIO_WritePin(keypadio.rowNum[irow].GPIOx, keypadio.rowNum[irow].GPIO_Pin, GPIO_PIN_SET); //PH7ÖÃ1
}
// HAL_GPIO_WritePin(GPIOC, GPIO_PIN_1, GPIO_PIN_SET); //PH7ÖÃ1
// HAL_GPIO_WritePin(GPIOH, GPIO_PIN_2|GPIO_PIN_3, GPIO_PIN_SET); //PH7ÖÃ1
delay_us(10);
//ÒÀ´Î¶ÁÈ¡ÁжÔÓ¦IOÖµ
for(icol = 0; icol < KEY_COL_NUM; icol++)
{
val_col[icol] = HAL_GPIO_ReadPin(keypadio.colNum[icol].GPIOx, keypadio.colNum[icol].GPIO_Pin);
if(key_up && val_col[icol]) //Èç¹ûÈ·¶¨Îªµ±Ç°ÁУ¬Ôò²éÕÒÄÄÒ»ÐÐ COL0
{
delay_ms(10); //keyVal
for(irow = 0; irow < KEY_ROW_NUM; irow++)
{
//ÒÀ´ÎÖÃλÐÐIOΪµÍ£¬Èç¹ûÐжÁȡΪµÍ£¬Ôò±íʾΪµ±Ç°ÐÐ
HAL_GPIO_WritePin(keypadio.rowNum[irow].GPIOx, keypadio.rowNum[irow].GPIO_Pin, GPIO_PIN_RESET); //ÖÃ0
delay_us(10);
if(!HAL_GPIO_ReadPin(keypadio.colNum[icol].GPIOx, keypadio.colNum[icol].GPIO_Pin)) //Èç¹ûµ±Ç°¶Áµ½Îª0£¬Ôò±íʾÊÇ´ËÖµ£»
{
key_up = 0;
key_num = keyVal[icol][irow]; //¸ù¾ÝÐÐÁÐÖµ£¬»ñÈ¡¶ÔÓ¦¼üÖµ
valValid = 1; //¼¦Àß
break;
}
}
if(valValid)
break;
}
}
//Èç¹ûÈ«²¿ÎªµÍ£¬Ôò±íʾ°´¼ü̧Æð£»·Àֹ̧ÆðÇ°ÖØ¸´·¢ËͼüÖµ
for(icol = 0; icol < KEY_COL_NUM; icol++)
{
keyUpFlag |= val_col[icol];
}
if(!keyUpFlag) //ûÓмüÖµ£¬Ôò±íʾ̧Æð
key_up = 1;
return key_num;
}
/*************************************************˵Ã÷**********************************************************/
/*
1¡¢¾ØÕó¼üÅÌ£¨µ¥¸ö¼üÖµ£©£ºÁÐ×÷ΪÊäÈ루ÏÂÀ£©£¬ÐÐ×öÊä³ö£»
ÐÐÊ×ÏÈÊä³öΪ¸ß£¬ÂÖѯ¶ÁÿһÁжÔÓ¦µÄIO£¬Èç¹ûΪ¸ß£¬Ôò±íʾ´ËÁÐÓа´¼ü°´Ï£¬·ñÔò²éѯÏÂÒ»ÁУ»
È·Èϵ±Ç°ÁÐÓа´¼ü°´ÏÂʱ£¬ÐÐÒÀ´ÎÊä³öΪµÍ£¬µ±»ñȡΪµÍʱ£¬±íʾµ±Ç°Ðа´Ï£¬·ñÔò¼ÌÐøÏÂÒ»ÐУ»
µ±Ç°ÐÐÁоùÈ·ÈϺ󣬼´¿ÉÊä³ö¶ÔÓ¦¼üÖµ£»
2¡¢ÎªÁË·½ÃæÐÞ¸ÄÒÆÖ²£¬ÐÐÁÐÊýÁ¿¾ù²ÉÓú궨Ò巽ʽ£»ÐÐÁжÔÓ¦IO²ÉÓýṹÌ帳ֵ·½Ê½£»¶ÔÓ¦¼üÖµ²ÉÓöþάÊý×鷽ʽ£»
*/
注释为乱码,不知道怎么整,可以下载资源(不知道这里怎么上传),文件源码,搜索“STM32矩阵键盘HAL库实现,轮询方式,方便移植”(不知道怎么设置免费下载,哈哈)