英文:
stm32 keypad 4x4 IDR register always set
问题
我正在尝试将stm32 nucleo微控制器与4x4键盘接口。行使用上拉电阻设置,中断在下降沿触发。当按下键时,中断会正确触发(我使用EXTI,NVIC和TIM3进行振动检测)。列和行通过GPIOC连接,列端口:PC0,PC1,PC2,PC3,行端口:PC6,PC7,PC8,PC9。
示例GPIO配置:
// COL4 - PC3
GPIOoutConfigure(GPIOC, 3, GPIO_OType_PP, GPIO_Low_Speed, GPIO_PuPd_NOPULL);
// 配置行
// ROW1 - PC6
GPIOinConfigure(GPIOC, 6, GPIO_PuPd_UP, EXTI_Mode_Interrupt, EXTI_Trigger_Falling)
为了检查按钮按下,我将列输出设置为0(一个列设置为0,其余设置为1)。
void set_low_state(int col_row_pin) {
GPIOC->BSRR = 1 << (col_row_pin + 16);
}
void set_high_state(int col_row_pin) {
GPIOC->BSRR = 1 << col_row_pin;
}
当我检查列的ODR寄存器在设置为高或低时,它似乎被正确设置。
然而,我注意到,无论中断是否触发(最初在TIM3_IRQ处理程序中注意到,然后在按下键之前在主函数中检查),所有行的IDR寄存器始终被设置为:
if ((GPIOC->IDR >> 6) & 1) {
// 6:ROW1_PIN,即PC6
// 始终为真
}
是否有任何错误?我应该如何检查寄存器以了解行状态?是否有任何瓶颈我应该注意?我在互联网上找到了一些库文档,但我找不到我的方法与库之间的区别。
英文:
I am trying to interface stm32 nucleo microcontroler with 4x4 keypad. Rows are set with a pull-up resistor, interruptions triggered on a falling edge. The interruption is correctly triggered when a key is pressed (I use EXTI, NVIC and TIM3 - for vibration detection). Columns and rows linked through GPIOC, column ports: PC0, PC1, PC2, PC3, row ports: PC6, PC7, PC8, PC9.
Example GPIO configuration:
// COL4 - PC3
GPIOoutConfigure(GPIOC,
3,
GPIO_OType_PP,
GPIO_Low_Speed,
GPIO_PuPd_NOPULL);
// Configure rows
// ROW1 - PC6
GPIOinConfigure(GPIOC, 6, GPIO_PuPd_UP,
EXTI_Mode_Interrupt,
EXTI_Trigger_Falling)
In order to check the button pressed, I set column outputs to 0 (one column is set to 0, the rest is set to 1).
void set_low_state(int col_row_pin) {
GPIOC->BSRR = 1 << (col_row_pin + 16);
}
void set_high_state(int col_row_pin) {
GPIOC->BSRR = 1 << col_row_pin;
}
As I check ODR register for columns when set high or low, it seems to be correctly set.
However I have noticed, that whether interruption is triggered or not (first noticed it in TIM3_IRQ handler, then checked it in main before pressing the key) the IDR registers for ALL rows are ALWAYS set:
if ((GPIOC->IDR >> 6) & 1) {
// 6: ROW1_PIN, that is PC6
// always true
Is there any mistake? Which register and how should I check in order to get to know the row state? Are there any bottlenecks I should pay attention to? I have found some library docs over the Internet and I can't find the difference between my approach and the library.
答案1
得分: 1
在这种类型的键盘按钮按下检测中 - 使用上拉电阻 - 输入端口被设置为1,因此我需要检查逻辑零:
if (!((GPIOC->IDR >> 6) & 1)) {
...
}
英文:
In this type of keypad button press detection - with a pull-up resistor - input ports are set to 1, therefore I need to check for logical zero:
if (!((GPIOC->IDR >> 6) & 1)) {
...
}
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论