1.前言
嘉立创做了一块编程小车的蓝牙按键遥控器,按键是4*4矩阵的,通过蓝牙发送按键编码值给蓝牙小车(外围设备)。
原理图如下:
板子回来后,因为懒得写按键矩阵扫描程序,想想还是交给人工智能帮我写吧。
1.开始提一个大概的需求
浏览器打开通义千问,国产免费的对话人工智能,同时选择代码模式
提问:使用C语言写一个矩阵按键的扫描程序,要求记录按下和松开事件。
模型回答的代码:
#include <stdio.h>
#include <stdbool.h>
#define ROWS 4
#define COLS 4
// 模拟按键状态数组
bool keyMatrix[ROWS][COLS] = {
{false, false, false, false},
{false, false, false, false},
{false, false, false, false},
{false, false, false, false}
};
// 上一次按键状态数组
bool lastKeyMatrix[ROWS][COLS];
void initKeyboard() {
// 初始化上一次按键状态数组
for (int i = 0; i < ROWS; i++) {
for (int j = 0; j < COLS; j++) {
lastKeyMatrix[i][j] = keyMatrix[i][j];
}
}
}
void scanKeyboard() {
// 这里应该是从硬件读取按键状态的代码
// 这里我们用随机数模拟按键状态变化
for (int i = 0; i < ROWS; i++) {
for (int j = 0; j < COLS; j++) {
keyMatrix[i][j] = rand() % 2;
}
}
// 检测按键按下和松开事件
for (int i = 0; i < ROWS; i++) {
for (int j = 0; j < COLS; j++) {
if (keyMatrix[i][j] && !lastKeyMatrix[i][j]) {
printf("Key (%d,%d) pressed\n", i, j);
} else if (!keyMatrix[i][j] && lastKeyMatrix[i][j]) {
printf("Key (%d,%d) released\n", i, j);
}
lastKeyMatrix[i][j] = keyMatrix[i][j];
}
}
}
int main() {
srand(time(NULL));
initKeyboard();
while (1) {
scanKeyboard();
usleep(100000); // 延迟100ms
}
return 0;
}
他已经帮我写了一些逻辑,写自动举例是4*4的按键矩阵,但是一看好像是一段和平台无关的代码,于是我又补充问题。
2.补充具体平台代码
提问:使用stm32单片机来编写这段代码
回答:
好的,下面是一个使用STM32单片机编写的矩阵按键扫描程序示例。假设你有一个4x4的矩阵键盘,并且使用的是STM32的GPIO接口来读取按键状态。我们将使用HAL库来进行GPIO操作。
硬件连接
- 行(ROW):PA0, PA1, PA2, PA3
- 列(COL):PB0, PB1, PB2, PB3
代码实现
#include "main.h"
#include "stm32f4xx_hal.h"
#define ROWS 4
#define COLS 4
// 定义行和列的GPIO引脚
GPIO_TypeDef* rowPorts[ROWS] = {GPIOA, GPIOA, GPIOA, GPIOA};
uint16_t rowPins[ROWS] = {GPIO_PIN_0, GPIO_PIN_1, GPIO_PIN_2, GPIO_PIN_3};
GPIO_TypeDef* colPorts[COLS] = {GPIOB, GPIOB, GPIOB, GPIOB};
uint16_t colPins[COLS] = {GPIO_PIN_0, GPIO_PIN_1, GPIO_PIN_2, GPIO_PIN_3};
bool keyMatrix[ROWS][COLS];
bool lastKeyMatrix[ROWS][COLS];
void SystemClock_Config(void);
static void MX_GPIO_Init(void);
int main(void)
{
HAL_Init();
SystemClock_Config();
MX_GPIO_Init();
// 初始化按键状态数组
for (int i = 0; i < ROWS; i++) {
for (int j = 0; j < COLS; j++) {
lastKeyMatrix[i][j] = false;
}
}
while (1) {
scanKeyboard();
HAL_Delay(100); // 延迟100ms
}
}
void scanKeyboard() {
for (int r = 0; r < ROWS; r++) {
// 设置当前行为低电平
HAL_GPIO_WritePin(rowPorts[r], rowPins[r], GPIO_PIN_RESET);
for (int c = 0; c < COLS; c++) {
// 读取列的状态
keyMatrix[r][c] = HAL_GPIO_ReadPin(colPorts[c], colPins[c]) == GPIO_PIN_SET;
// 检测按键按下和松开事件
if (keyMatrix[r][c] && !lastKeyMatrix[r][c]) {
printf("Key (%d,%d) pressed\n", r, c);
} else if (!keyMatrix[r][c] && lastKeyMatrix[r][c]) {
printf("Key (%d,%d) released\n", r, c);
}
lastKeyMatrix[r][c] = keyMatrix[r][c];
}
// 将当前行恢复为高电平
HAL_GPIO_WritePin(rowPorts[r], rowPins[r], GPIO_PIN_SET);
}
}
static void MX_GPIO_Init(void)
{
GPIO_InitTypeDef GPIO_InitStruct = {0};
__HAL_RCC_GPIOA_CLK_ENABLE();
__HAL_RCC_GPIOB_CLK_ENABLE();
// 配置行引脚为输出模式
for (int i = 0; i < ROWS; i++) {
GPIO_InitStruct.Pin = rowPins[i];
GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
GPIO_InitStruct.Pull = GPIO_NOPULL;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
HAL_GPIO_Init(rowPorts[i], &GPIO_InitStruct);
HAL_GPIO_WritePin(rowPorts[i], rowPins[i], GPIO_PIN_SET); // 初始化为高电平
}
// 配置列引脚为输入模式
for (int i = 0; i < COLS; i++) {
GPIO_InitStruct.Pin = colPins[i];
GPIO_InitStruct.Mode = GPIO_MODE_INPUT;
GPIO_InitStruct.Pull = GPIO_PULLDOWN;
HAL_GPIO_Init(colPorts[i], &GPIO_InitStruct);
}
}
void S