USB论坛
直播中

王平

8年用户 1428经验值
私信 关注
[问答]

FCX3无法进入GPIO中断是怎么回事?

我尝试将GPIO20配置成中断引脚,若输入为上升沿,则让GPIO24引脚输出低电平;若输入为下降沿,则让GPIO24引脚输出高电平。但是现在看起来无法进入GPIO中断。各位大佬可以帮我找下问题吗?
#include#include#include#include#include#include"rtc.h"
CyU3PThread gpioOutputThread; /* GPIO 线程结构 */
CyU3PThread gpioInputThread; /* GPIO 线程结构 */
CyU3PEvent glFxGpioAppEvent; /* GPIO 输入事件组。 */
/* GPIO 中断回调处理程序。 这是收到的
* 中断上下文。 因此 DebugPrint API 不可用
* 从这里。 在事件组中设置一个事件,以便
* GPIO线程可以打印事件信息。 */
无效 CyFxGpioIntrCb (
uint8_t gpioId /*表示触发中断的引脚*/

{
CyBool_t gpioValue = CyFalse;
CyU3PReturnStatus_t apiRetStatus = CY_U3P_SUCCESS;
/*获取引脚的状态*/
apiRetStatus = CyU3PGpioGetValue (gpioId,&gpioValue);
如果 (apiRetStatus == CY_U3P_SUCCESS)
{
/*检查引脚的状态*/
如果 (gpioValue == CyTrue)
{
/* Set GPIO high event */
CyU3PEventSet(&glFxGpioAppEvent, CY_FX_GPIOAPP_GPIO_HIGH_EVENT,
CYU3P_EVENT_OR);
CyU3PGpioSetValue (24, CyFalse);
}
别的
{
/* Set GPIO low Event */
CyU3PEventSet(&glFxGpioAppEvent, CY_FX_GPIOAPP_GPIO_LOW_EVENT,
CYU3P_EVENT_OR);
CyU3PGpioSetValue (24, CyTrue);
}
}
}
空白
CyFxGpioInit(空)
{
CyU3PGpioClock_t gpioClock;
CyU3PGpioSimpleConfig_t gpioConfig;
CyU3PReturnStatus_t apiRetStatus = CY_U3P_SUCCESS;
/* 初始化 GPIO 模块 */
gpioClock.fastClkDiv = 2;
gpioClock.slowClkDiv = 0;
gpioClock.simpleDiv = CY_U3P_GPIO_SIMPLE_DIV_BY_2;
gpioClock.clksrc=CY_U3P_SYS_CLK;
gpioClock.halfDiv = 0;
apiRetStatus = CyU3PGpioInit(&gpioClock, CyFxGpioIntrCb);
如果 (apiRetStatus != 0)
{
/* Error Handling */
CyU3PDebugPrint (4, "CyU3PGpioInit failed, error code = %dn", apiRetStatus);
}
/* 将 GPIO 20 配置为输入,并在两个边沿启用中断 */
apiRetStatus = CyU3PDeviceGpioOverride (20,CyTrue);
如果 (apiRetStatus != 0)
{
/* Error Handling */
CyU3PDebugPrint (4, "CyU3PDeviceGpioOverride failed, error code = %dn",
apiRetStatus);
}
gpioConfig.outValue = CyTrue;
gpioConfig.inputEn = CyTrue;
gpioConfig.driveLowEn = CyFalse;
gpioConfig.driveHighEn = CyFalse;
gpioConfig.intrMode = CY_U3P_GPIO_INTR_BOTH_EDGE;
apiRetStatus = CyU3PGpioSetSimpleConfig(20,&gpioConfig);
如果(apiRetStatus!=CY_U3P_SUCCESS)
{
/* Error handling */
CyU3PDebugPrint (4, "CyU3PGpioSetSimpleConfig failed, error code = %dn",
apiRetStatus);
}
CyU3PGpioSetioMode(20, CY_U3P_GPIO_IO_MODE_WPD);
/* 将 GPIO 24 配置为输出 */
apiRetStatus = CyU3PDeviceGpioOverride (24,CyTrue);
如果 (apiRetStatus != 0)
{
/* Error Handling */
CyU3PDebugPrint (4, "CyU3PDeviceGpioOverride failed, error code = %dn",
apiRetStatus);
}
gpioConfig.outValue = CyFalse;
gpioConfig.driveLowEn = CyTrue;
gpioConfig.driveHighEn = CyTrue;
gpioConfig.inputEn = CyFalse;
gpioConfig.intrMode = CY_U3P_GPIO_NO_INTR;
apiRetStatus = CyU3PGpioSetSimpleConfig(24,&gpioConfig);
如果 (apiRetStatus != CY_U3P_SUCCESS)
{
/* Error handling */
CyU3PDebugPrint (4, "CyU3PGpioSetSimpleConfig failed, error code = %dn",
apiRetStatus);
}
CyU3PGpioSetIoMode(24, CY_U3P_GPIO_IO_MODE_WPD);
}
另外,在main函数中:
io_cfg.gpioSimpleEn[0] = 0;
io_cfg.gpioSimpleEn[1] = 0;
io_cfg.gpioComplexEn[0] = 0;
io_cfg.gpioComplexEn[1] = 0;
并且已经将 CyU3PMipicsiInitializeGPIO () 替换为 CyFxGpioInit ()。

回帖(1)

徐开

2025-5-20 18:14:22

针对你遇到的问题,以下是逐步的排查和解决方案:




  1. 确认GPIO时钟和功能配置



    • 确保GPIO模块的时钟已启用。在初始化GPIO前调用:
      CyU3PDeviceGpioOverride(20, CyTrue);  // 将GPIO20覆盖为GPIO功能
      CyU3PDeviceGpioOverride(24, CyTrue);  // GPIO24同理

    • 检查CyU3PGpioInit()是否成功执行,确认返回值是否为CY_U3P_SUCCESS




  2. 正确配置中断参数



    • 在设置GPIO中断时,使用CyU3PGpioSetInt启用中断,并检查返回值:
      status = CyU3PGpioSetInt(20, CY_U3P_GPIO_INT_BOTH_EDGE);
      if (status != CY_U3P_SUCCESS) {
      // 错误处理
      }

    • 使用CyU3PGpioSetIntMode确认中断模式设置正确:
      CyU3PGpioSetIntMode(20, CY_U3P_GPIO_INT_BOTH_EDGE);




  3. 验证中断回调注册



    • 注册回调函数后检查状态:
      status = CyU3PGpioRegisterCallback(20, FxGpioApplnIntrCb, &glFxGpioAppEvent);
      if (status != CY_U3P_SUCCESS) {
      // 错误处理
      }




  4. 初始化事件和线程



    • 确保事件组已创建:
      CyU3PEventCreate(&glFxGpioAppEvent);

    • 检查输入线程是否正常运行,确保线程函数FxGpioApplnIntrThread中包含事件等待和处理逻辑:
      void FxGpioApplnIntrThread(uint32_t value) {
      CyU3PEvent_t event;
      while (1) {
           CyU3PEventGet(&glFxGpioAppEvent, CYU3P_EVENT_OR, &event, CYU3P_WAIT_FOREVER);
           // 处理中断,例如读取GPIO状态并设置GPIO24
           CyU3PEventClear(&glFxGpioAppEvent, event);
      }
      }




  5. 检查GPIO电气连接和外部电路



    • 使用示波器或逻辑分析仪确认GPIO20的输入信号确实产生了上升沿和下降沿。

    • 确保GPIO24的外部电路正确,例如没有短路或错误的上拉/下拉电阻。




  6. 调试技巧



    • 在中断回调函数中快速切换另一个未使用的GPIO(如GPIO25)以确认是否进入中断。

    • 在主循环中添加打印语句(注意中断上下文中不可用DebugPrint),在线程处理部分输出调试信息。




  7. 代码修正示例


    // 确保在初始化时覆盖GPIO功能并启用中断
    CyU3PGpioInit();
    CyU3PDeviceGpioOverride(20, CyTrue);
    CyU3PDeviceGpioOverride(24, CyTrue);

    // 配置GPIO20为输入,中断模式
    CyU3PGpioSimpleSetDirection(20, CY_U3P_GPIO_DIR_INPUT);
    CyU3PGpioSetInt(20, CY_U3P_GPIO_INT_BOTH_EDGE);
    CyU3PGpioSetIntMode(20, CY_U3P_GPIO_INT_BOTH_EDGE);

    // 注册中断回调
    CyU3PGpioRegisterCallback(20, FxGpioApplnIntrCb, &glFxGpioAppEvent);

    // 配置GPIO24为输出,初始高电平
    CyU3PGpioSimpleSetDirection(24, CY_U3P_GPIO_DIR_OUTPUT);
    CyU3PGpioSetValue(24, CyTrue);

    // 创建事件和线程
    CyU3PEventCreate(&glFxGpioAppEvent);
    CyU3PThreadCreate(&gpioInputThread, ..., FxGpioApplnIntrThread, ...);



通过以上步骤检查和修正,应该能够解决无法进入GPIO中断的问题。若仍存在问题,建议逐步调试各配置函数的返回值,并利用硬件工具验证信号。

举报

更多回帖

发帖
×
20
完善资料,
赚取积分