首页 > 其他分享 >stm32笔记[13]-矩阵键盘

stm32笔记[13]-矩阵键盘

时间:2024-01-19 18:46:45浏览次数:24  
标签:键盘 13 HAL keypad PIN index Pin stm32 GPIO

摘要

在蓝桥杯物联网的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);
}

效果

六个按键和屏幕全都正常工作

标签:键盘,13,HAL,keypad,PIN,index,Pin,stm32,GPIO
From: https://www.cnblogs.com/qsbye/p/17975342

相关文章

  • 吴师兄学算法day08 贪心 134. 加油站
    题目:134.加油站理解难点:理解比较难,就是遍历1遍,尽可能找局部满足要求的。如果总油耗满足要求。那局部油耗找的出发点就是对的。遍历的时候,因为答案唯一,要么就满足要求,要么不满足要求。而<0证明之前的都不满足要求,满足要求的一定在后面。这题还是个环,环这里有点没太理解。环......
  • CF1340F Nastya and CBS
    更好的阅读体验CF1340FNastyaandCBS绷不住了,30min写完,虚空调试2h+/lh/lh。如果要准确做的话太困难了,考虑hash。多次区间询问,考虑线段树。一个区间如果内部合法,把内部能匹配的都匹配上,一定是左边一段右括号加上右边一段左括号。节点需要记录左边长度,右边长度和左右分别的......
  • 2-STM32F103+EC800K(移远4G Cat1)远程升级篇(阿里云物联网平台)-STM32F103使用EC800K
    <p><iframename="ifd"src="https://mnifdv.cn/resource/cnblogs/ZLIOTB/EC800K/aliyunota.html"frameborder="0"scrolling="auto"width="100%"height="1500"></iframe></p>  ......
  • C语言学习随笔-13 枚举(enum)
    枚举:枚举是C语言中的一种基本数据类型,用于定义一组具有离散值的常量,它可以让数据更简洁,更易读。          枚举类型通常用于为程序中的一组相关的常量取名字,以便于程序的可读性和维护性1、枚举语法定义格式为:enum枚举名{枚举元素1,枚举元素2,……};   ......
  • P5133题解
    P5133tb148的客人题目传送门题解唯一的一篇题解还是交错题的……很简单的一个二分加差分题。显然是二分答案,考虑检验。如果\(2mid+1\gen\),那么所有人可以自由去到任意位置,一定可行;否则,我们求出每个人可以去到的区间范围,并以此推出要满足这个人的限制,\(1\)号需要在哪个区......
  • dotnet 8项目Docker部署报错 Unhandled exception. Microsoft.Data.SqlClient.SqlExce
    环境:dotnet8+sqlserver2012本地开发调试正常,部署至Docker容器时,运行实例报错。查看日志显示:Unhandledexception.Microsoft.Data.SqlClient.SqlException(0x80131904):Aconnectionwassuccessfullyestablishedwiththeserver,butthenanerroroccurredduringth......
  • 1-STM32F103+EC800K(移远4G Cat1)远程升级篇(阿里云物联网平台)-STM32F103使用EC800K
    <p><iframename="ifd"src="https://mnifdv.cn/resource/cnblogs/ZLIOTB/EC800K/aliyunota.html"frameborder="0"scrolling="auto"width="100%"height="1500"></iframe></p>  ......
  • 文心一言 VS 讯飞星火 VS chatgpt (182)-- 算法导论13.4 6题
    六、用go语言,Skelton和Baron教授担心在RB-DELETE-FIXUP的情况1开始时,结点x.p可能不是黑色的。如果这两位教授是对的,则第5~6行就是错的。证明:x.p在情况1开始时必是黑色的,从而说明这两位教授没有担心的必要。文心一言:首先,我们需要理解RB-DELETE-FIXUP的情况1开始时,节点x.p......
  • STM32CubeMX教程18 DAC - DMA输出自定义波形
    1、准备材料开发板(正点原子stm32f407探索者开发板V2.4)STM32CubeMX软件(Version6.10.0)野火DAP仿真器keilµVision5IDE(MDK-Arm)ST-LINK/V2驱动一台示波器逻辑分析仪nanoDLA2、实验目标使用STM32CubeMX软件配置STM32F407开发板的DACOUT1实现输出0-3.3V周期为12.8ms的正弦......
  • 2-STM32F103+EC800K(移远4G Cat1)远程升级篇(自建物联网平台)-STM32通过EC800K使用htt
    <p><iframename="ifd"src="https://mnifdv.cn/resource/cnblogs/ZLIOTB/EC800K/myota.html"frameborder="0"scrolling="auto"width="100%"height="1500"></iframe></p>  说明前......