4*4薄膜按键
薄膜按键和矩阵按键类似,同样是4*4的按键矩阵,由于商家并不提供任何资料导致很苦恼,就感觉有点离谱
虽然键盘挺简单的,但是连个例程和原理图都没有属实有点离谱
后来找来找去只找到这么一张图
根据这张图,进行开发
经过我的一番探索,了解了此键盘的具体情况,并为八条线设置引脚
矩阵按键扫描采用行高电平,列检测的方法进行键盘扫描
硬件连线
由于这个插排线的缘故,只能把这个插排的塑料外壳拆掉才能分两排插到stm32上
stm32cubemx
矩阵扫描行对应引脚输出 output
列对应引脚 input
注意 input 引脚要下拉输入,防止干扰
生成代码
keil5
新建文件夹 keyboard
文件夹中新建 keyboard.c 和 keyboard.h 文件
将其路径添加到keil5中
keyboard.h
#ifndef __KEYBOARD_H
#define __KEYBOARD_H
#include "bsp_system.h"
#include "gpio.h"
#include "stm32f1xx_hal.h"
void Key_Scan(void);
void Display_Change(void);
#endif /* __KEYBOARD_H */
keyboard.c
#include "keyboard.h"
unsigned char temp = 'A';
void Key_Scan()
{
//拉高第1行电平,判断第一行的状态
HAL_GPIO_WritePin(GPIOB,GPIO_PIN_13,GPIO_PIN_SET);
if( HAL_GPIO_ReadPin(GPIOB,GPIO_PIN_12) == GPIO_PIN_SET )
{
temp = '1';
}
if( HAL_GPIO_ReadPin(GPIOB,GPIO_PIN_14) == GPIO_PIN_SET )
{
temp = '2';
}
if( HAL_GPIO_ReadPin(GPIOC,GPIO_PIN_6) == GPIO_PIN_SET )
{
temp = '3';
}
if( HAL_GPIO_ReadPin(GPIOB,GPIO_PIN_8) == GPIO_PIN_SET )
{
temp = 'A';
}
//拉低第1行,拉高第1行
HAL_GPIO_WritePin(GPIOB,GPIO_PIN_13,GPIO_PIN_RESET);
HAL_GPIO_WritePin(GPIOB,GPIO_PIN_15,GPIO_PIN_SET);
if( HAL_GPIO_ReadPin(GPIOB,GPIO_PIN_12) == GPIO_PIN_SET )
{
temp = '4';
}
if( HAL_GPIO_ReadPin(GPIOB,GPIO_PIN_14) == GPIO_PIN_SET )
{
temp = '5';
}
if( HAL_GPIO_ReadPin(GPIOC,GPIO_PIN_6) == GPIO_PIN_SET )
{
temp = '6';
}
if( HAL_GPIO_ReadPin(GPIOB,GPIO_PIN_8) == GPIO_PIN_SET )
{
temp = 'B';
}
//拉低第2行,拉高第3行
HAL_GPIO_WritePin(GPIOB,GPIO_PIN_15,GPIO_PIN_RESET);
HAL_GPIO_WritePin(GPIOC,GPIO_PIN_7,GPIO_PIN_SET);
if( HAL_GPIO_ReadPin(GPIOB,GPIO_PIN_12) == GPIO_PIN_SET )
{
temp = '7';
}
if( HAL_GPIO_ReadPin(GPIOB,GPIO_PIN_14) == GPIO_PIN_SET )
{
temp = '8';
}
if( HAL_GPIO_ReadPin(GPIOC,GPIO_PIN_6) == GPIO_PIN_SET )
{
temp = '9';
}
if( HAL_GPIO_ReadPin(GPIOB,GPIO_PIN_8) == GPIO_PIN_SET )
{
temp = 'C';
}
//拉低第3行,拉高第4行
HAL_GPIO_WritePin(GPIOC,GPIO_PIN_7,GPIO_PIN_RESET);
HAL_GPIO_WritePin(GPIOB,GPIO_PIN_9,GPIO_PIN_SET);
if( HAL_GPIO_ReadPin(GPIOB,GPIO_PIN_12) == GPIO_PIN_SET )
{
temp = '*';
}
if( HAL_GPIO_ReadPin(GPIOB,GPIO_PIN_14) == GPIO_PIN_SET )
{
temp = '0';
}
if( HAL_GPIO_ReadPin(GPIOC,GPIO_PIN_6) == GPIO_PIN_SET )
{
temp = '#';
}
if( HAL_GPIO_ReadPin(GPIOB,GPIO_PIN_8) == GPIO_PIN_SET )
{
temp = 'D';
}
HAL_GPIO_WritePin(GPIOB,GPIO_PIN_9,GPIO_PIN_RESET);
}
void Display_Change()
{
//OLED一共可以显示21位数据,最小形式1
switch(temp)
{
case 'A':
OLED_ShowStr(0,0,(unsigned char*)"FirstPage ",1);
OLED_ShowStr(0,2,(unsigned char*)"A for FirstPage ",1);
OLED_ShowStr(0,3,(unsigned char*)"B for Read/WriteRFID ",1);
OLED_ShowStr(0,4,(unsigned char*)"C for RFID is Truth ",1);
OLED_ShowStr(0,5,(unsigned char*)"D for Clear OLCED ",1);
OLED_ShowStr(0,6,(unsigned char*)" ",1);
OLED_ShowStr(0,7,(unsigned char*)" ",1);
OLED_ShowStr(0,8,(unsigned char*)" ",1);
break;
case 'B':
OLED_ShowStr(0,0,(unsigned char*)"Read/Write Page ",1);
OLED_ShowStr(0,1,(unsigned char*)" ",1);
OLED_ShowStr(0,2,(unsigned char*)" ",1);
OLED_ShowStr(0,3,(unsigned char*)" ",1);
OLED_ShowStr(0,4,(unsigned char*)" ",1);
OLED_ShowStr(0,5,(unsigned char*)" ",1);
OLED_ShowStr(0,6,(unsigned char*)" ",1);
OLED_ShowStr(0,7,(unsigned char*)" ",1);
break;
case 'C':
OLED_ShowStr(0,0,(unsigned char*)"RFID is Truth Page ",1);
OLED_ShowStr(0,1,(unsigned char*)" ",1);
OLED_ShowStr(0,2,(unsigned char*)" ",1);
OLED_ShowStr(0,3,(unsigned char*)" ",1);
OLED_ShowStr(0,4,(unsigned char*)" ",1);
OLED_ShowStr(0,5,(unsigned char*)" ",1);
OLED_ShowStr(0,6,(unsigned char*)" ",1);
OLED_ShowStr(0,7,(unsigned char*)" ",1);
break;
case 'D':
OLED_CLS();
break;
}
}
这里我把lcd切换显示函数也放在了里面
矩阵扫描的精髓在于
控制一行按键高电平,判断列
然后在拉低,控制下一行按键高电平,判断列
也就是滚动扫描
OLED屏幕可以支持21位的字母显示(字号为1的情况)
将keyboard.h包含到bsp_system.h文件中
这里不再进行展示
main.c
/* USER CODE END Header */
/* Includes ------------------------------------------------------------------*/
#include "main.h"
#include "i2c.h"
#include "usart.h"
#include "gpio.h"
/* Private includes ----------------------------------------------------------*/
/* USER CODE BEGIN Includes */
#include "bsp_system.h"
/* USER CODE END Includes */
/* Private typedef -----------------------------------------------------------*/
/* USER CODE BEGIN PTD */
/* USER CODE END PTD */
/* Private define ------------------------------------------------------------*/
/* USER CODE BEGIN PD */
/* USER CODE END PD */
/* Private macro -------------------------------------------------------------*/
/* USER CODE BEGIN PM */
/* USER CODE END PM */
/* Private variables ---------------------------------------------------------*/
/* USER CODE BEGIN PV */
/* USER CODE END PV */
/* Private function prototypes -----------------------------------------------*/
void SystemClock_Config(void);
/* USER CODE BEGIN PFP */
/* USER CODE END PFP */
/* Private user code ---------------------------------------------------------*/
/* USER CODE BEGIN 0 */
uint8_t send_date[64] = {0};
extern unsigned char temp;
/* USER CODE END 0 */
/**
* @brief The application entry point.
* @retval int
*/
int main(void)
{
/* USER CODE BEGIN 1 */
/* USER CODE END 1 */
/* MCU Configuration--------------------------------------------------------*/
/* Reset of all peripherals, Initializes the Flash interface and the Systick. */
HAL_Init();
/* USER CODE BEGIN Init */
/* USER CODE END Init */
/* Configure the system clock */
SystemClock_Config();
/* USER CODE BEGIN SysInit */
/* USER CODE END SysInit */
/* Initialize all configured peripherals */
MX_GPIO_Init();
MX_USART1_UART_Init();
MX_I2C1_Init();
/* USER CODE BEGIN 2 */
/* USER CODE END 2 */
/* Infinite loop */
/* USER CODE BEGIN WHILE */
OLED_Init();
OLED_CLS();
//OLED_ShowStr(0,0,(unsigned char*)"Hello world",2);
OLED_ON();
while (1)
{
Key_Scan();
//串口调试
sprintf((char *)send_date,"test date+%c ",temp);
//HAL_UART_Transmit(&huart1, send_date, sizeof(send_date), 100);
//HAL_Delay(500);
//OLED_ShowStr(0,0,(unsigned char*)send_date,2);
Display_Change();
//OLED_CLS();
/* USER CODE END WHILE */
/* USER CODE BEGIN 3 */
}
/* USER CODE END 3 */
}
效果图
就放一张吧,反正就是按键ABCD切换LED的显示
明天是RFID标签
也是重点
后期代码会放到 github 开源
点个赞吧