摘要
在蓝桥杯物联网的CT127C开发板上测试矩阵键盘模块;复用矩阵键盘的io口和i2c3的io口;在屏幕显示按下的按键.
开发环境
- Keil 5.35.00
- HAL库版本:STM32Cube FW_L0 V1.12.0
- STM32CubeMX:6.2.1
原理简介
stm32的引脚复用
void HAL_I2C_MspDeInit(I2C_HandleTypeDef* i2cHandle)
{
if(i2cHandle->Instance==I2C3)
{
/* USER CODE BEGIN I2C3_MspDeInit 0 */
/* USER CODE END I2C3_MspDeInit 0 */
/* Peripheral clock disable */
__HAL_RCC_I2C3_CLK_DISABLE();
/**I2C3 GPIO Configuration
PA8 ------> I2C3_SCL
PB4 ------> I2C3_SDA
*/
HAL_GPIO_DeInit(GPIOA, GPIO_PIN_8);
HAL_GPIO_DeInit(GPIOB, GPIO_PIN_4);
/* USER CODE BEGIN I2C3_MspDeInit 1 */
/* USER CODE END I2C3_MspDeInit 1 */
}
}
例如HAL_I2C_MspDeInit
函数就是用于复用引脚功能的.
实现
核心代码
main.c
uint8_t g_keypad_pressed = '0'; // keypad pressed key
void keypadInit(void);// reinit keypad
uint8_t keypadScan(void); // scan keypad
void displayInit(void); //reinit display
// init display
displayInit();
// init keypad
keypadInit();
while(1){
// 扫描矩阵键盘
if(keypadScan() != 0){
// init display
displayInit();
// init keypad
keypadInit();
}
}
/*
重新初始化矩阵键盘的引脚
re init keypad gpio
reuse gpio
COL(PB1,PB0,PA8)OUTPUT,
ROW(PB6,PB7)INPUT
*/
void keypadInit(void){
HAL_I2C_MspDeInit(&hi2c3);
GPIO_InitTypeDef GPIO_InitStruct = {0};
// PB6,PB7->INPUT
GPIO_InitStruct.Pin = GPIO_PIN_6|GPIO_PIN_7;
GPIO_InitStruct.Mode = GPIO_MODE_INPUT;
GPIO_InitStruct.Pull = GPIO_PULLUP;
HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);
// PB1,PB0,PA8->OUTPUT
HAL_GPIO_WritePin(GPIOA, GPIO_PIN_8, GPIO_PIN_RESET);
GPIO_InitStruct.Pin = GPIO_PIN_8;
GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
GPIO_InitStruct.Pull = GPIO_PULLUP;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
HAL_GPIO_WritePin(GPIOB, GPIO_PIN_0, GPIO_PIN_RESET);
HAL_GPIO_WritePin(GPIOB, GPIO_PIN_1, GPIO_PIN_RESET);
GPIO_InitStruct.Pin = GPIO_PIN_0|GPIO_PIN_1;
GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
GPIO_InitStruct.Pull = GPIO_PULLUP;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);
}
/*
扫描矩阵键盘
scan keypad
COL(PB1,PB0,PA8)OUTPUT,
ROW(PB6,PB7)INPUT
*/
uint8_t keypadScan(void){
#define COL3_GPIO_Port GPIOA
#define COL3_Pin GPIO_PIN_8
#define COL2_Pin GPIO_PIN_0
#define COL2_GPIO_Port GPIOB
#define COL1_Pin GPIO_PIN_1
#define COL1_GPIO_Port GPIOB
#define ROW1_Pin GPIO_PIN_6
#define ROW1_GPIO_Port GPIOB
#define ROW2_Pin GPIO_PIN_7
#define ROW2_GPIO_Port GPIOB
uint16_t ROW[2]={ROW1_Pin,ROW2_Pin};
uint16_t COL[3]={COL1_Pin,COL2_Pin,COL3_Pin};
uint8_t s_keypad_name[3][2]={{'1','4'},{'2','5'},{'3','6'}};
// g_keypad_pressed
uint8_t s_col_index = 0;
uint8_t s_row_index = 0;
uint8_t s_keypad_pressed = 0;
// set col gpio status
HAL_GPIO_WritePin(COL1_GPIO_Port,COL1_Pin,GPIO_PIN_SET);
HAL_GPIO_WritePin(COL2_GPIO_Port,COL2_Pin,GPIO_PIN_SET);
HAL_GPIO_WritePin(COL3_GPIO_Port,COL3_Pin,GPIO_PIN_SET);
for(s_col_index = 0 ; s_col_index < 3 ; s_col_index ++){
if(s_col_index != 2) {HAL_GPIO_WritePin(GPIOB,COL[s_col_index],GPIO_PIN_RESET); }
else {HAL_GPIO_WritePin(COL3_GPIO_Port,COL[2],GPIO_PIN_RESET); }
for(s_row_index = 0; s_row_index < 2 ; s_row_index ++){
if(HAL_GPIO_ReadPin(GPIOB,ROW[s_row_index]) != GPIO_PIN_SET){
HAL_Delay(10);
if(HAL_GPIO_ReadPin(GPIOB,ROW[s_row_index]) != GPIO_PIN_SET){
g_keypad_pressed = s_keypad_name[s_col_index][s_row_index];
s_keypad_pressed = s_keypad_name[s_col_index][s_row_index];
while(HAL_GPIO_ReadPin(GPIOB,ROW[s_row_index]) == GPIO_PIN_SET);
// blink
HAL_GPIO_TogglePin(GPIOC,GPIO_PIN_15);
return s_keypad_pressed;
} // end if
} // end if
} // end for row
} // end for col
return s_keypad_pressed;
}// end function
/*
重新初始化显示屏的引脚
re init display gpio
reuse gpio
*/
void displayInit(void){
HAL_I2C_MspInit(&hi2c3);
HAL_GPIO_WritePin(GPIOB, GPIO_PIN_5, GPIO_PIN_RESET);
MX_I2C3_Init();
sprintf((char*)g_oled_buf,"key:%c",g_keypad_pressed);
OLED_ShowString(24,2,g_oled_buf,16);
}
效果
六个按键和屏幕全都正常工作 |
---|