让人工智能帮我写一个矩阵按键扫描程序

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
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

搏哥聊技术

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值