想请各位帮忙
用的是 stmSTM32L476 4x4矩阵键盘
参考逐行逐列扫描法,不知为何不工作
下面是我的代码,求帮忙(给各位拜年了)
```c
#include "stm32l476xx.h"
#include "keypad.h"
void Keypad_Init() {
//激活GPIOC 时钟
RCC->AHB2ENR |= RCC_AHB2ENR_GPIOCEN;
//设置输出 PIN 0, PIN1, PIN 2, PIN3,
GPIOC->MODER &= ~(GPIO_MODER_MODE0 | GPIO_MODER_MODE1 | GPIO_MODER_MODE2 | GPIO_MODER_MODE3);
GPIOC->MODER |= (GPIO_MODER_MODE0_0 | GPIO_MODER_MODE1_0 | GPIO_MODER_MODE2_0 | GPIO_MODER_MODE3_0);
//设置输入PIN4,PIN10, PIN11,PIN12
GPIOC->MODER &= ~(GPIO_MODER_MODE4 | GPIO_MODER_MODE10 | GPIO_MODER_MODE11 | GPIO_MODER_MODE12);
//选择 open train 模式
GPIOC->OTYPER |= (GPIO_IDR_ID0 | GPIO_IDR_ID1 | GPIO_IDR_ID2 | GPIO_IDR_ID3);
}
unsigned char keypad_scan() {
unsigned char row, col;
unsigned char key;
unsigned char keymap[4][4] = {
{'1','2','3','A'},
{'4','5','6','B'},
{'7','8','9','C'},
{'*','0','#','D'}
};
/* 这里我做的是 4x4 键盘
输出 1 2 3 A
输出 4 5 6 B
输出 7 8 9 C
输出 * 0 # D
4个输入
*/
// 设置 outputmask 为一个整数
uint32_t outputMask = GPIO_ODR_OD0 | GPIO_ODR_OD1 | GPIO_ODR_OD2 | GPIO_ODR_OD3;
// 设置 intputmask 为一个整数
uint32_t inputMask = GPIO_IDR_ID4 | GPIO_IDR_ID10 | GPIO_IDR_ID11 | GPIO_IDR_ID12;
// output 数组
uint32_t outputArray[4] = { GPIO_ODR_OD0 , GPIO_ODR_OD1 , GPIO_ODR_OD2 , GPIO_ODR_OD3 };
// intput 数组
uint32_t inputArray[4] = { GPIO_IDR_ID4 , GPIO_IDR_ID10 , GPIO_IDR_ID11 , GPIO_IDR_ID12 };
waitms(3); // 延迟
while( (GPIOC->IDR & inputMask) == inputMask) {;} // 等待按键
_output = 0xF; //先让输出都为0
for(row = 0; row < 4; row++) { // 检测横列
GPIOC->ODR &= ~(outputArray[row]); 让单个输出依次为0
waitms(3); // short delay
for(col = 0; col < 4; col++) { // 检测竖排
if((GPIOC->IDR & inputArray[col]) == 0 ){ //如果 输入 and 输出 不为1
key = keymap[row][col]; //在矩阵数组中确认按下的位置
return key;
}
}
}
return 0xFF; //如果没有按键 返回0xFF
}
// 延迟fuction
void waitms(unsigned int ms) {
int i, j;
for(i = 0; i < ms; i++) {
for(j=0; j < 4000; j++);
}
}
```
根据您的描述的问题,关于stm32l476矩阵键盘的实现,您给出的代码,是有什么问题吗,报错了还是咋样,还是说需要继续完善,关于stm32l476的编程,你可以参考编程手册:
STM32L476编程手册【翻译】【中文版】.pdf
https://download.csdn.net/download/feiniao200201/35869675
x*y的矩阵键盘 原理都是基于动态扫描实现的,在行(或列)上输出一个不断右移(或左移)的1,其他全0,同时在列(或行)上检测,得到对应按键按下或弹起的信息,在查键码表即可实现按键的识别处理功能。
根据您的描述的问题,关于stm32l476矩阵键盘的实现,您给出的代码,是有什么问题吗,报错了还是咋样?按照你的思维和逻辑,我觉得应该是这样的:x*y的矩阵键盘 原理都是基于动态扫描实现的,在行(或列)上输出一个不断右移(或左移)的1,其他全0,同时在列(或行)上检测,得到对应按键按下或弹起的信息,在查键码表即可实现按键的识别处理功能。
```c
#include "stm32l476xx.h"
#include "keypad.h"
void Keypad_Init() {
//激活GPIOC 时钟
RCC->AHB2ENR |= RCC_AHB2ENR_GPIOCEN;
//设置输出 PIN 0, PIN1, PIN 2, PIN3,
GPIOC->MODER &= ~(GPIO_MODER_MODE0 | GPIO_MODER_MODE1 | GPIO_MODER_MODE2 | GPIO_MODER_MODE3);
GPIOC->MODER |= (GPIO_MODER_MODE0_0 | GPIO_MODER_MODE1_0 | GPIO_MODER_MODE2_0 | GPIO_MODER_MODE3_0);
//设置输入PIN4,PIN10, PIN11,PIN12
GPIOC->MODER &= ~(GPIO_MODER_MODE4 | GPIO_MODER_MODE10 | GPIO_MODER_MODE11 | GPIO_MODER_MODE12);
//选择 open train 模式
GPIOC->OTYPER |= (GPIO_IDR_ID0 | GPIO_IDR_ID1 | GPIO_IDR_ID2 | GPIO_IDR_ID3);
}
unsigned char keypad_scan() {
unsigned char row, col;
unsigned char key;
unsigned char keymap[4][4] = {
{'1','2','3','A'},
{'4','5','6','B'},
{'7','8','9','C'},
{'*','0','#','D'}
};
/* 这里我做的是 4x4 键盘
输出 1 2 3 A
输出 4 5 6 B
输出 7 8 9 C
输出 * 0 # D
4个输入
*/
// 设置 outputmask 为一个整数
uint32_t outputMask = GPIO_ODR_OD0 | GPIO_ODR_OD1 | GPIO_ODR_OD2 | GPIO_ODR_OD3;
// 设置 intputmask 为一个整数
uint32_t inputMask = GPIO_IDR_ID4 | GPIO_IDR_ID10 | GPIO_IDR_ID11 | GPIO_IDR_ID12;
// output 数组
uint32_t outputArray[4] = { GPIO_ODR_OD0 , GPIO_ODR_OD1 , GPIO_ODR_OD2 , GPIO_ODR_OD3 };
// intput 数组
uint32_t inputArray[4] = { GPIO_IDR_ID4 , GPIO_IDR_ID10 , GPIO_IDR_ID11 , GPIO_IDR_ID12 };
waitms(3); // 延迟
while( (GPIOC->IDR & inputMask) == inputMask) {;} // 等待按键
_output = 0xF; //先让输出都为0
for(row = 0; row < 4; row++) { // 检测横列
_output &= ~(outputArray[row]); 让单个输出依次为0
waitms(3); // short delay
for(col = 0; col < 4; col++) { // 检测竖排
if( (_input & _output) !=0xF){ //如果 输入 and 输出 不为1
key = keymap[row][col]; //在矩阵数组中确认按下的位置
return key;
}
}
}
return 0xFF; //如果没有按键 返回0xFF
}
// 延迟fuction
void waitms(unsigned int ms) {
int i, j;
for(i = 0; i < ms; i++) {
for(j=0; j < 4000; j++);
}
}
这个本身是没有问题的,如果对您有帮助,请点击一下旁边的采纳,感谢
请检查以下几点:
检查输入输出引脚的实际连接,确保连接是正确的。
确保输出引脚的电压是适当的,应该是 3.3V 或 5V。
检查代码中的宏定义是否与实际情况相符,例如 GPIO_MODER_MODE0 应该是否替换为你需要的值。
如果代码没有任何明显错误,请确保系统时钟正常工作,如果不正常,请重新配置时钟。
首先,等待循环中的状态需要修改。代码中判断的是当前输入接口的值是否都为1,但是在设置输入接口为0时,最终状态可能不是全为1,所以需要对该等待循环进行修改。
其次,代码中 _output = 0xF; 这一句话是错误的,因为在代码中没有定义 _output 变量,并且变量名也没有使用下划线开头,请将其修改为 output = 0xF;。
最后,程序没有处理没有按键的情况,如果没有按键,则需要返回无效值,如:
key = '\0';
for(row = 0; row < 4; row++) { // 检测横列
output &= ~(outputArray[row]); // 让单个输出依次为0
waitms(3); // short delay
for(col = 0; col < 4; col++) { // 检测竖排
if((GPIOC->IDR & inputArray[col]) == 0) { //如果输入与输出不为1
key = keymap[row][col]; //在矩阵数组中找到相应键值
break;
}
}
if(key != '\0') {
break;
}
}
if(key == '\0') {
key = 'N'; // 返回无效键值
}
return key;
修改后的代码如下:
unsigned char keypad_scan() {
unsigned char row, col;
unsigned char key;
unsigned char keymap[4][4] = {
{'1','2','3','A'},
{'4','5','6','B'},
{'7','8','9','C'},
{'*','0','#','D'}
};
uint