复制
收藏
提问
全网
stm32f103zet6 4×4矩阵键盘控制8个led灯点亮的代码
1个月前
理解问题stm32f103zet6 4×4矩阵键盘控制8个led灯点亮的代码
已完成理解「stm32f103zet6 4×4矩阵键盘控制8个led灯点亮的代码」
展开阅读网页
使用 STM32F103ZET6 控制 4×4 矩阵键盘和 8 个 LED 灯的代码如下:
#include "stm32f10x.h"
#define ROW1_GPIO_Port GPIOA
#define ROW1_Pin GPIO_PIN_0
#define ROW2_GPIO_Port GPIOA
#define ROW2_Pin GPIO_PIN_1
#define ROW3_GPIO_Port GPIOA
#define ROW3_Pin GPIO_PIN_2
#define ROW4_GPIO_Port GPIOA
#define ROW4_Pin GPIO_PIN_3
#define COL1_GPIO_Port GPIOB
#define COL1_Pin GPIO_PIN_0
#define COL2_GPIO_Port GPIOB
#define COL2_Pin GPIO_PIN_1
#define COL3_GPIO_Port GPIOB
#define COL3_Pin GPIO_PIN_2
#define COL4_GPIO_Port GPIOB
#define COL4_Pin GPIO_PIN_3
#define LED1_GPIO_Port GPIOC
#define LED1_Pin GPIO_PIN_0
#define LED2_GPIO_Port GPIOC
#define LED2_Pin GPIO_PIN_1
#define LED3_GPIO_Port GPIOC
#define LED3_Pin GPIO_PIN_2
#define LED4_GPIO_Port GPIOC
#define LED4_Pin GPIO_PIN_3
#define LED5_GPIO_Port GPIOC
#define LED5_Pin GPIO_PIN_4
#define LED6_GPIO_Port GPIOC
#define LED6_Pin GPIO_PIN_5
#define LED7_GPIO_Port GPIOC
#define LED7_Pin GPIO_PIN_6
#define LED8_GPIO_Port GPIOC
#define LED8_Pin GPIO_PIN_7
void GPIO_Config(void) {
GPIO_InitTypeDef GPIO_InitStructure;
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA | RCC_APB2Periph_GPIOB | RCC_APB2Periph_GPIOC, ENABLE);
GPIO_InitStructure.GPIO_Pin = ROW1_Pin | ROW2_Pin | ROW3_Pin | ROW4_Pin;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(ROW1_GPIO_Port, &GPIO_InitStructure);
GPIO_InitStructure.GPIO_Pin = COL1_Pin | COL2_Pin | COL3_Pin | COL4_Pin;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;
GPIO_Init(COL1_GPIO_Port, &GPIO_InitStructure);
GPIO_InitStructure.GPIO_Pin = LED1_Pin | LED2_Pin | LED3_Pin | LED4_Pin | LED5_Pin | LED6_Pin | LED7_Pin | LED8_Pin;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(LED1_GPIO_Port, &GPIO_InitStructure);
}
uint8_t ReadKey(void) {
uint8_t key = 0xFF;
for (int row = 0; row < 4; row++) {
GPIO_WriteBit(ROW1_GPIO_Port, ROW1_Pin << row, Bit_RESET);
for (int col = 0; col < 4; col++) {
if (GPIO_ReadInputDataBit(COL1_GPIO_Port, COL1_Pin << col) == Bit_RESET) {
key = row * 4 + col;
}
}
GPIO_WriteBit(ROW1_GPIO_Port, ROW1_Pin << row, Bit_SET);
}
return key;
}
void LED_Control(uint8_t key) {
for (int i = 0; i < 8; i++) {
GPIO_WriteBit(LED1_GPIO_Port, LED1_Pin << i, (key > i) ? Bit_SET : Bit_RESET);
}
}
int main(void) {
GPIO_Config();
while (1) {
uint8_t key = ReadKey();
if (key != 0xFF) {
LED_Control(key);
}
}
}
🔧代码说明
- GPIO_Config: 配置 GPIO 引脚,设置行引脚为输出模式,列引脚为输入上拉模式,LED 引脚为输出模式。
- ReadKey: 扫描矩阵键盘,检测按键状态并返回按键编号。
- LED_Control: 根据按键编号控制 LED 灯的点亮数量。
- main: 主循环中不断读取按键状态并控制 LED 灯。
🔌引脚定义
- 行引脚: ROW1_Pin 到 ROW4_Pin
- 列引脚: COL1_Pin 到 COL4_Pin
- LED 引脚: LED1_Pin 到 LED8_Pin
📜参考信息
更专业一些
转笔记
专业
stm32f103zet6 4×4矩阵键盘控制8个led灯点亮的代码不在提醒
在STM32F103ZET6微控制器上实现4×4矩阵键盘控制8个LED灯点亮的代码,需要通过GPIO口进行矩阵键盘的扫描和LED的控制。以下是一个详细的实现方案。
核心结论
通过STM32F103ZET6的GPIO口实现4×4矩阵键盘的扫描,并根据按键状态控制8个LED灯的点亮。代码实现包括矩阵键盘的初始化、扫描逻辑、按键检测和LED控制。
🔌 矩阵键盘的初始化
- GPIO配置:首先,需要配置矩阵键盘的行和列引脚为输入和输出模式。行引脚配置为输出模式,列引脚配置为输入模式。这样可以逐行扫描矩阵键盘,检测按键状态。
- 上拉电阻:为了确保按键未按下时列引脚的电平为高,需要启用内部上拉电阻。
🔍 矩阵键盘的扫描逻辑
- 逐行扫描:通过逐行输出低电平,检测列引脚的电平变化来判断按键是否按下。例如,将第一行输出低电平,其他行输出高电平,然后检测列引脚的电平。如果某一列引脚为低电平,则表示该行该列的按键被按下。
- 按键去抖:由于机械按键存在抖动,需要在检测到按键按下后进行去抖处理,通常通过延时一段时间后再检测按键状态。
🔔 按键检测
- 按键识别:通过扫描矩阵键盘,识别出具体的按键。每个按键对应一个唯一的行列组合,可以根据行列组合确定按键编号。
- 按键状态处理:检测到按键按下后,记录按键状态,并根据按键编号执行相应的LED控制逻辑。
💡 LED控制
- LED初始化:配置LED对应的GPIO口为输出模式,初始状态下所有LED灯熄灭。
- LED点亮逻辑:根据按键编号,控制相应的LED灯点亮。例如,按键1控制第一个LED灯点亮,按键2控制前两个LED灯点亮,依此类推。
🛠️ 代码实现
以下是一个简化的代码框架,展示了如何在STM32F103ZET6上实现4×4矩阵键盘控制8个LED灯点亮的代码:
#include "stm32f10x.h"
#define ROW1_GPIO_Port GPIOA
#define ROW1_Pin GPIO_Pin_0
#define ROW2_GPIO_Port GPIOA
#define ROW2_Pin GPIO_Pin_1
#define ROW3_GPIO_Port GPIOA
#define ROW3_Pin GPIO_Pin_2
#define ROW4_GPIO_Port GPIOA
#define ROW4_Pin GPIO_Pin_3
#define COL1_GPIO_Port GPIOB
#define COL1_Pin GPIO_Pin_0
#define COL2_GPIO_Port GPIOB
#define COL2_Pin GPIO_Pin_1
#define COL3_GPIO_Port GPIOB
#define COL3_Pin GPIO_Pin_2
#define COL4_GPIO_Port GPIOB
#define COL4_Pin GPIO_Pin_3
#define LED1_GPIO_Port GPIOC
#define LED1_Pin GPIO_Pin_0
#define LED2_GPIO_Port GPIOC
#define LED2_Pin GPIO_Pin_1
#define LED3_GPIO_Port GPIOC
#define LED3_Pin GPIO_Pin_2
#define LED4_GPIO_Port GPIOC
#define LED4_Pin GPIO_Pin_3
#define LED5_GPIO_Port GPIOC
#define LED5_Pin GPIO_Pin_4
#define LED6_GPIO_Port GPIOC
#define LED6_Pin GPIO_Pin_5
#define LED7_GPIO_Port GPIOC
#define LED7_Pin GPIO_Pin_6
#define LED8_GPIO_Port GPIOC
#define LED8_Pin GPIO_Pin_7
void GPIO_Config(void) {
GPIO_InitTypeDef GPIO_InitStructure;
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA | RCC_APB2Periph_GPIOB | RCC_APB2Periph_GPIOC, ENABLE);
// 配置行引脚为输出模式
GPIO_InitStructure.GPIO_Pin = ROW1_Pin | ROW2_Pin | ROW3_Pin | ROW4_Pin;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(ROW1_GPIO_Port, &GPIO_InitStructure);
// 配置列引脚为输入模式,启用内部上拉电阻
GPIO_InitStructure.GPIO_Pin = COL1_Pin | COL2_Pin | COL3_Pin | COL4_Pin;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;
GPIO_Init(COL1_GPIO_Port, &GPIO_InitStructure);
// 配置LED引脚为输出模式
GPIO_InitStructure.GPIO_Pin = LED1_Pin | LED2_Pin | LED3_Pin | LED4_Pin | LED5_Pin | LED6_Pin | LED7_Pin | LED8_Pin;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(LED1_GPIO_Port, &GPIO_InitStructure);
}
void Delay(uint32_t count) {
for (; count != 0; count--);
}
uint8_t Scan_Keypad(void) {
uint8_t key = 0;
// 逐行扫描
for (uint8_t row = 0; row < 4; row++) {
// 设置当前行输出低电平
switch (row) {
case 0: GPIO_ResetBits(ROW1_GPIO_Port, ROW1_Pin); break;
case 1: GPIO_ResetBits(ROW2_GPIO_Port, ROW2_Pin); break;
case 2: GPIO_ResetBits(ROW3_GPIO_Port, ROW3_Pin); break;
case 3: GPIO_ResetBits(ROW4_GPIO_Port, ROW4_Pin); break;
}
// 检测列引脚状态
if (GPIO_ReadInputDataBit(COL1_GPIO_Port, COL1_Pin) == Bit_RESET) {
key = row * 4 + 1;
}
if (GPIO_ReadInputDataBit(COL2_GPIO_Port, COL2_Pin) == Bit_RESET) {
key = row * 4 + 2;
}
if (GPIO_ReadInputDataBit(COL3_GPIO_Port, COL3_Pin) == Bit_RESET) {
key = row * 4 + 3;
}
if (GPIO_ReadInputDataBit(COL4_GPIO_Port, COL4_Pin) == Bit_RESET) {
key = row * 4 + 4;
}
// 恢复当前行输出高电平
switch (row) {
case 0: GPIO_SetBits(ROW1_GPIO_Port, ROW1_Pin); break;
case 1: GPIO_SetBits(ROW2_GPIO_Port, ROW2_Pin); break;
case 2: GPIO_SetBits(ROW3_GPIO_Port, ROW3_Pin); break;
case 3: GPIO_SetBits(ROW4_GPIO_Port, ROW4_Pin); break;
}
if (key != 0) {
Delay(0xFFFF); // 去抖延时
break;
}
}
return key;
}
void Control_LED(uint8_t key) {
// 根据按键编号控制LED灯点亮
switch (key) {
case 1: GPIO_SetBits(LED1_GPIO_Port, LED1_Pin); break;
case 2: GPIO_SetBits(LED1_GPIO_Port, LED1_Pin | LED2_Pin); break;
case 3: GPIO_SetBits(LED1_GPIO_Port, LED1_Pin | LED2_Pin | LED3_Pin); break;
case 4: GPIO_SetBits(LED1_GPIO_Port, LED1_Pin | LED2_Pin | LED3_Pin | LED4_Pin); break;
case 5: GPIO_SetBits(LED1_GPIO_Port, LED1_Pin | LED2_Pin | LED3_Pin | LED4_Pin | LED5_Pin); break;
case 6: GPIO_SetBits(LED1_GPIO_Port, LED1_Pin | LED2_Pin | LED3_Pin | LED4_Pin | LED5_Pin | LED6_Pin); break;
case 7: GPIO_SetBits(LED1_GPIO_Port, LED1_Pin | LED2_Pin | LED3_Pin | LED4_Pin | LED5_Pin | LED6_Pin | LED7_Pin); break;
case 8: GPIO_SetBits(LED1_GPIO_Port, LED1_Pin | LED2_Pin | LED3_Pin | LED4_Pin | LED5_Pin | LED6_Pin | LED7_Pin | LED8_Pin); break;
default: GPIO_ResetBits(LED1_GPIO_Port, LED1_Pin | LED2_Pin | LED3_Pin | LED4_Pin | LED5_Pin | LED6_Pin | LED7_Pin | LED8_Pin); break;
}
}
int main(void) {
GPIO_Config();
while (1) {
uint8_t key = Scan_Keypad();
if (key != 0) {
Control_LED(key);
}
}
}
📝 代码说明
- GPIO_Config:配置矩阵键盘和LED的GPIO口。
- Scan_Keypad:逐行扫描矩阵键盘,检测按键状态。
- Control_LED:根据按键编号控制相应的LED灯点亮。
- main:主循环中不断扫描按键并控制LED。
通过以上代码,可以实现STM32F103ZET6微控制器上4×4矩阵键盘控制8个LED灯点亮的功能。