STM32键盘4×4的IDR寄存器始终被设置。

huangapple go评论57阅读模式
英文:

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-&gt;BSRR = 1 &lt;&lt; (col_row_pin + 16);
}

void set_high_state(int col_row_pin) {
	GPIOC-&gt;BSRR = 1 &lt;&lt; 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-&gt;IDR &gt;&gt; 6) &amp; 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-&gt;IDR &gt;&gt; 6) &amp; 1)) {
...
}

huangapple
  • 本文由 发表于 2023年2月27日 07:17:35
  • 转载请务必保留本文链接:https://go.coder-hub.com/75575599.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定