1.首先在Cubemx里使能矩阵键盘管脚
PC6--PC9为行
PB12--PB15为列
2.
将PC6--PC9设位输出模式高电平
将PB12--PB15设为输入模式上拉
3.
绘制仿真
5.
在写程序前前先弄清楚IDR和ODR这两个东西
1.IDR是查看引脚电平状态用的寄存器
2.ODR是引脚电平输出的寄存器
IDR在高16位保留,始终读为0。在低16位为只读并只能以字(16位)的形式读出。读出的值为对应I/O口的状态。(简单的说就是只能读不能写)
比如要读取某个端口状态
GPIOX->=0xxxx
ODR在高16位保留,始终读为0。在低16位可读可写并只能以字(16位)的形式操作,写1对应的管脚为高电平写0对应的管脚为低电平。
比如要使PC9为低电平PC8,7,6为高电平
GPIOC->ODR=0x1c0 //0001 1100 0000
6.
程序
uint8_t k = 0;
uint8_t key_scan()
{
GPIOC->ODR=0x1c0; //0001 1100 0000 PC9 = 0; DOR 低16写1为高
GPIOB->ODR=0xF000; //把列全部设位高
uint8_t i = 0;
if(GPIOB->IDR!=0xF000) //IDR高16保留始终为0 低16位只读 当任何一列被按下(为0)进入判断
{
HAL_Delay(5);
if(GPIOB->IDR==0x7000){k = 0;}
if(GPIOB->IDR==0xb000){k = 1;}
if(GPIOB->IDR==0xd000){k = 2;}
if(GPIOB->IDR==0xe000){k = 3;}
}
GPIOC->ODR=0x2c0; //0010 1100 0000 PC8 = 0;
GPIOB->ODR=0xF000;
if(GPIOB->IDR!=0xF000)
{
HAL_Delay(5);
if(GPIOB->IDR==0x7000){k = 4;}
if(GPIOB->IDR==0xb000){k = 5;}
if(GPIOB->IDR==0xd000){k = 6;}
if(GPIOB->IDR==0xe000){k = 7;}
}
GPIOC->ODR=0x340; //0011 0100 0000 PC7 = 0;
GPIOB->ODR=0xF000;
if(GPIOB->IDR!=0xF000)
{
HAL_Delay(5);
if(GPIOB->IDR==0x7000){k = 8;}
if(GPIOB->IDR==0xb000){k = 9;}
if(GPIOB->IDR==0xd000){k = 10;}
if(GPIOB->IDR==0xe000){k = 11;}
}
GPIOC->ODR=0x380; //0011 1000 0000 PC6 = 0;
GPIOB->ODR=0xF000;
if(GPIOB->IDR!=0xF000)
{
HAL_Delay(5);
if(GPIOB->IDR==0x7000){k = 12;}
if(GPIOB->IDR==0xb000){k = 13;}
if(GPIOB->IDR==0xd000){k = 14;}
if(GPIOB->IDR==0xe000){k = 15;}
}
return k;
}
void getkey()
{
k = key_scan();
}
在判断第一行时
把行ROW0设为低电平ROW1--ROW3为高电平
把列全部设位高电平
再读取列的状态如果不是原来的状态了则表明某个列被按下了
按下时进行判断读取列的状态就能得出我们的键值了
判断第二行时只需要把第ROW1为低电平ROW0,ROW2,ROW3为高电平
扫描列不变
以此类推。。。。。。
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_TIM3_Init();
/* USER CODE BEGIN 2 */
// HAL_TIM_IC_Start_IT(&htim3,TIM_CHANNEL_3);
LCD1602_init();
uint8_t keybuff[10];
/* USER CODE END 2 */
/* Infinite loop */
/* USER CODE BEGIN WHILE */
while (1)
{
getkey(); //记得添加这个
sprintf(keybuff,"kunm= %d\r\n",k);
LCD_showstr(1,0,keybuff);
LCD_showstr(2,5,"Test");
/* USER CODE END WHILE */
/* USER CODE BEGIN 3 */
}
/* USER CODE END 3 */
}
仿真测试成功
还是看不懂??等等别划走啊!!
让我们把代码改的明了一些
//
// Created by Administrator on 2023/8/1.
//
#include "key4x4.h"
uint8_t key4x4 = 0;
uint8_t key4x4scan()
{
HAL_GPIO_WritePin(ROW0_GPIO_Port,ROW0_Pin,GPIO_PIN_RESET);
HAL_GPIO_WritePin(ROW1_GPIO_Port,ROW1_Pin,GPIO_PIN_SET);
HAL_GPIO_WritePin(ROW2_GPIO_Port,ROW2_Pin,GPIO_PIN_SET);
HAL_GPIO_WritePin(ROW3_GPIO_Port,ROW3_Pin,GPIO_PIN_SET);
if(HAL_GPIO_ReadPin(COL0_GPIO_Port,COL0_Pin)||HAL_GPIO_ReadPin(COL1_GPIO_Port,COL1_Pin)||
HAL_GPIO_ReadPin(COL2_GPIO_Port,COL2_Pin)||HAL_GPIO_ReadPin(COL3_GPIO_Port,COL3_Pin)
==GPIO_PIN_RESET)
{
HAL_Delay(10);
if(HAL_GPIO_ReadPin(COL0_GPIO_Port,COL0_Pin)==GPIO_PIN_RESET){key4x4 = 0;}
if(HAL_GPIO_ReadPin(COL1_GPIO_Port,COL1_Pin)==GPIO_PIN_RESET){key4x4 = 1;}
if(HAL_GPIO_ReadPin(COL2_GPIO_Port,COL2_Pin)==GPIO_PIN_RESET){key4x4 = 2;}
if(HAL_GPIO_ReadPin(COL3_GPIO_Port,COL3_Pin)==GPIO_PIN_RESET){key4x4 = 3;}
}
HAL_GPIO_WritePin(ROW0_GPIO_Port,ROW0_Pin,GPIO_PIN_SET);
HAL_GPIO_WritePin(ROW1_GPIO_Port,ROW1_Pin,GPIO_PIN_RESET);
HAL_GPIO_WritePin(ROW2_GPIO_Port,ROW2_Pin,GPIO_PIN_SET);
HAL_GPIO_WritePin(ROW3_GPIO_Port,ROW3_Pin,GPIO_PIN_SET);
if(HAL_GPIO_ReadPin(COL0_GPIO_Port,COL0_Pin)||HAL_GPIO_ReadPin(COL1_GPIO_Port,COL1_Pin)||
HAL_GPIO_ReadPin(COL2_GPIO_Port,COL2_Pin)||HAL_GPIO_ReadPin(COL3_GPIO_Port,COL3_Pin)
==GPIO_PIN_RESET)
{
HAL_Delay(10);
if(HAL_GPIO_ReadPin(COL0_GPIO_Port,COL0_Pin)==GPIO_PIN_RESET){key4x4 = 4;}
if(HAL_GPIO_ReadPin(COL1_GPIO_Port,COL1_Pin)==GPIO_PIN_RESET){key4x4 = 5;}
if(HAL_GPIO_ReadPin(COL2_GPIO_Port,COL2_Pin)==GPIO_PIN_RESET){key4x4 = 6;}
if(HAL_GPIO_ReadPin(COL3_GPIO_Port,COL3_Pin)==GPIO_PIN_RESET){key4x4 = 7;}
}
HAL_GPIO_WritePin(ROW0_GPIO_Port,ROW0_Pin,GPIO_PIN_SET);
HAL_GPIO_WritePin(ROW1_GPIO_Port,ROW1_Pin,GPIO_PIN_SET);
HAL_GPIO_WritePin(ROW2_GPIO_Port,ROW2_Pin,GPIO_PIN_RESET);
HAL_GPIO_WritePin(ROW3_GPIO_Port,ROW3_Pin,GPIO_PIN_SET);
if(HAL_GPIO_ReadPin(COL0_GPIO_Port,COL0_Pin)||HAL_GPIO_ReadPin(COL1_GPIO_Port,COL1_Pin)||
HAL_GPIO_ReadPin(COL2_GPIO_Port,COL2_Pin)||HAL_GPIO_ReadPin(COL3_GPIO_Port,COL3_Pin)
==GPIO_PIN_RESET)
{
HAL_Delay(10);
if(HAL_GPIO_ReadPin(COL0_GPIO_Port,COL0_Pin)==GPIO_PIN_RESET){key4x4 = 8;}
if(HAL_GPIO_ReadPin(COL1_GPIO_Port,COL1_Pin)==GPIO_PIN_RESET){key4x4 = 9;}
if(HAL_GPIO_ReadPin(COL2_GPIO_Port,COL2_Pin)==GPIO_PIN_RESET){key4x4 = 10;}
if(HAL_GPIO_ReadPin(COL3_GPIO_Port,COL3_Pin)==GPIO_PIN_RESET){key4x4 = 11;}
}
HAL_GPIO_WritePin(ROW0_GPIO_Port,ROW0_Pin,GPIO_PIN_SET);
HAL_GPIO_WritePin(ROW1_GPIO_Port,ROW1_Pin,GPIO_PIN_SET);
HAL_GPIO_WritePin(ROW2_GPIO_Port,ROW2_Pin,GPIO_PIN_SET);
HAL_GPIO_WritePin(ROW3_GPIO_Port,ROW3_Pin,GPIO_PIN_RESET);
if(HAL_GPIO_ReadPin(COL0_GPIO_Port,COL0_Pin)||HAL_GPIO_ReadPin(COL1_GPIO_Port,COL1_Pin)||
HAL_GPIO_ReadPin(COL2_GPIO_Port,COL2_Pin)||HAL_GPIO_ReadPin(COL3_GPIO_Port,COL3_Pin)
==GPIO_PIN_RESET)
{
HAL_Delay(10);
if(HAL_GPIO_ReadPin(COL0_GPIO_Port,COL0_Pin)==GPIO_PIN_RESET){key4x4 = 12;}
if(HAL_GPIO_ReadPin(COL1_GPIO_Port,COL1_Pin)==GPIO_PIN_RESET){key4x4 = 13;}
if(HAL_GPIO_ReadPin(COL2_GPIO_Port,COL2_Pin)==GPIO_PIN_RESET){key4x4 = 14;}
if(HAL_GPIO_ReadPin(COL3_GPIO_Port,COL3_Pin)==GPIO_PIN_RESET){key4x4 = 15;}
}
return key4x4;
}
void GetKeyValue()
{
key4x4 = key4x4scan();
}