【发布时间】:2025-11-23 08:15:02
【问题描述】:
我遇到了一个与 GPIO 中断有关的问题。 任务是做一个简单的UI界面,所以需要用到3个按钮。 问题是我不明白如何为不同的引脚使用 GPIO 中断,而且我所有的按钮都以相同的方式工作。
代码如下:
#include <m8c.h> // part specific constants and macros
#include "PSoCAPI.h" // PSoC API definitions for all User Modules
#include <stdio.h>
#include <stdlib.h>
typedef struct {
int value; // the actual value which is used in the module
char string[16]; // string that is printed in LCD for user
} UI_ELEMENT;
#define FIRST_LEVEL 3
#define SECOND_LEVEL 3
#define PWM 0
#define PGA 1
#define ADC 2
#define PWM_STATE 0
#define PWM_PERIOD 1
#define PWM_WIDTH 2
#define PWM_STATE_OFF 0
#define PWM_STATE_ON 1
volatile int buttonRightPressed = 0;
#pragma interrupt_handler buttonRightInt
void buttonRightInt(void){
// disable button interrupt
M8C_DisableIntMask(INT_MSK0, INT_MSK0_GPIO);
buttonRightPressed = 1;
}
void initialize_LCD(void){
LCD_Position(0,0);
LCD_PrCString("PWM");
LCD_Position(1,0);
LCD_PrCString("< select >");
}
void update_LCD(int* lvl1){
if (*lvl1 == PWM || *lvl1 == 3){
LCD_Position(0,0);
LCD_PrCString("PWM");
*lvl1 = 0;
}
else if (*lvl1 == PGA){
LCD_Position(0,0);
LCD_PrCString("PGA");
}
else if (*lvl1 == ADC){
LCD_Position(0,0);
LCD_PrCString("ADC");
}
}
void main(void)
{
UI_ELEMENT userInterface[FIRST_LEVEL][SECOND_LEVEL];
int level_1_steper = PWM;
int i;
M8C_EnableGInt ; // Uncomment this line to enable Global Interrupts
PWM8_EnableInt();
LCD_Start();
M8C_EnableIntMask(INT_MSK0, INT_MSK0_GPIO);
initialize_LCD(); // set 'PWM' for upper row, '< select >' for lower row
while (1){
if (buttonRightPressed == 1){
for ( i = 0; i < 350; i++);
level_1_steper++;
update_LCD(&level_1_steper);
buttonRightPressed = 0;
// enable button interrupt again
M8C_EnableIntMask(INT_MSK0, INT_MSK0_GPIO);
}
}
}
【问题讨论】:
-
如果不指定您使用的是哪个 MCU,就谈论 GPIO 中断是完全没有意义的。我猜这是带有 ARM Cortex M0 的 Cypress PSoC 吗?此外,您需要对按钮进行去抖动处理,不能像任何 I/O 一样简单地读取它。而且由于按钮有信号反弹,您很可能不希望边缘触发的中断响应它们,或者您需要有一个外部 RC 滤波器来消除反弹。
-
问题已解决!通常解决方案非常简单:使用 GPIO 中断但测试按下了哪个按钮。 GPIO 中断:
void buttonInt(void){ // disable button interrupt M8C_DisableIntMask(INT_MSK0, INT_MSK0_GPIO); if (Right_Data_ADDR & Right_MASK) buttonRightPressed = 1; if (Left_Data_ADDR & Left_MASK) buttonLeftPressed = 1; if (Select_Data_ADDR & Select_MASK) buttonSelectPressed = 1; }
标签: c embedded interrupt gpio psoc