【问题标题】:GPIO interrupt for different pins in PSoC 1PSoC 1 中不同引脚的 GPIO 中断
【发布时间】: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 &amp; Right_MASK) buttonRightPressed = 1; if (Left_Data_ADDR &amp; Left_MASK) buttonLeftPressed = 1; if (Select_Data_ADDR &amp; Select_MASK) buttonSelectPressed = 1; }

标签: c embedded interrupt gpio psoc


【解决方案1】:

问题已解决!通常解决方案非常简单:使用 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;
}

【讨论】: