This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

[参考译文] TM4C123GH6PM:屏蔽掉 GPIO 中断错误地触发

Guru**** 2383570 points
请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

https://e2e.ti.com/support/microcontrollers/arm-based-microcontrollers-group/arm-based-microcontrollers/f/arm-based-microcontrollers-forum/1497038/tm4c123gh6pm-masked-out-gpio-interrupts-triggering-erroneously

器件型号:TM4C123GH6PM

工具/软件:

我的电路包含一个 H 桥电机驱动器和2个接近传感器、目的是使电机沿一个方向移动、直到一个传感器被触发、然后停止电机、然后沿另一个方向移动、直到另一个传感器永久被触发。 传感器处于低电平有效状态。 电机驱动器位于引脚2和3上、接近传感器位于引脚4和5上、所有位于 Porta 上。

接近传感器引脚配置为低电平中断。 中断处理程序函数如下所示:

void pos_sensor_int_handler (){

   GPIOIntClear (GPIO_Porta_BASE、GPIO_INT_PIN_4 | GPIO_INT_PIN_5);   //清除接近传感器中断
   静态 uint32_t 状态;
   状态= GPIOIntStatus (GPIO_PORTA_BASE、TRUE);                        //获得屏蔽中断状态
   xQueueSendFromISR (pos_sensor_int_queue、&state、NULL);                //将其发送到实际处理事件的任务
}

我按如下方式设置 GPIO:

int main(){

  ROM_FPULazyStackingEnable ();

  ROM_SysCtlClockSet (SYSCTL_SYSDIV_2_5 | SYSCTL_USE_OSC | SYSCTL_OSC_MAIN | SYSCTL_XTAL_16MHz);

  ROM_SysCtlPeripheralEnable (SYSCTL_PERIPH_GPIOA);
  while (!SysCtlPeripheralReady (SYSCTL_PERIPH_GPIOA)){}

   GPIOIntRegister (GPIO_Porta_base、pos_sensor_int_handler);

   ROM_GPIOPinTypeGPIOOutput (GPIO_PORTA_BASE、MOTOR_CONTROL_PIN_R | MOTOR_CONTROL_PIN_L);   //GPIO 引脚2和3用于控制电机

   ROM_GPIOPinTypeGPIOInput (GPIO_PORTA_BASE、POS_SENSOR_PIN_L | POS_SENSOR_PIN_R);         //GPIO 引脚4和5是接近传感器

   GPIOIntTypeSet (GPIO_Porta_base、pos_sensor_pin_L | pos_sensor_pin_R、GPIO_LOW_LEVEL);

   GPIOIntEnable (GPIO_Porta_BASE、GPIO_INT_PIN_4 | GPIO_INT_PIN_5);

}

(省略我认为不相关的代码)

引脚4和5的中断确实符合预期、但问题是我也收到了虚假中断。 使用调试器,我可以看到处理程序函数  pos_sensor_int_handler () 是随机的(而且通常很频繁)被进入,即使这些引脚上没有电平变化。

使用"Register"视图、我可以看到端口 A GPIO 中断屏蔽寄存器(GPIO_IM)正确设置为0x00000030、这是16 (引脚5)和32 (引脚4)的 OR 结果。 当错误中断发生时、GPIO 原始中断状态寄存器(GPIO_RIS)读为0x00000080、表示引脚7上有一个中断、我从未启用过! 因此、我尝试显式禁用引脚的中断:

GPIOIntDisable (GPIO_PORTA_BASE、GPIO_INT_PIN_7);

现在、当发生这 种情况时、GPIO_RIS 只读取全0。 这怎么可能? 端口 A 上的所有中断是否都应该反映在 GPIO_RIS 中? 如何通过 在已启用的引脚上设置低电平以外的任何其他方式进入该中断处理程序?

谢谢你

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    Unknown 说:
    引脚4和引脚5的中断确实符合预期、但问题是我也收到了虚假中断。 使用调试器,我可以看到处理程序函数  pos_sensor_int_handler () 是随机的(通常很频繁)被进入,即使这些引脚上没有电平变化。

    我认为问题在于您使用的是  GPIO_LOW_LEVEL。   如果触发器为低电平有效、则应尝试对传感器输入使用 GPIO_FALLING_EDGE。  

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    感谢您的答复。

    我先尝试了 GPIO_FALLING_EDGE、但后来切换到 GPIO_LOW_LEVEL、因为 GPIO_FALLING EDGE 似乎根本不起作用。 使用调试器、我可以看到中断确实会触发、但 GPIOIntStatus (GPIO_Porta_base、true)始终返回0。 我尝试将 bMasked 位设置为 FALSE、结果相同。

    您知道问题可能是什么吗? 同样、端口 A 上显式启用的唯一中断是引脚4和5。 因此、据我所知、应该不可能将状态返回为0。

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    您有以下代码。 首先清除中断标志、然后读取状态。 您应该先获取状态、然后清除状态、以实现相反的操作。 您似乎也在运行 FreeRTOS。 我建议您首先运行裸机代码、以便在移植到 FreeRTOS 之前使中断正常工作、因为您不知道 FreeRTOS 是否会阻止任何情况发生。 只是从故障排除中找出一个很大的变量。  

    void pos_sensor_int_handler (){

       GPIOIntClear (GPIO_Porta_BASE、GPIO_INT_PIN_4 | GPIO_INT_PIN_5);   //清除接近传感器中断
       静态 uint32_t 状态;
       状态= GPIOIntStatus (GPIO_PORTA_BASE、TRUE);                        //获得屏蔽中断状态
       xQueueSendFromISR (pos_sensor_int_queue、&state、NULL);                //将其发送到实际处理事件的任务
    }

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    我更改了此函数、首先获取状态、然后按照您的建议清除中断、这似乎有所帮助。 虚假中断变得不那么频繁、当它们发生时、屏蔽状态不再回为0。 相反、屏蔽状态以48 (0x30)的形式返回。 如果我将其更改为读取未屏蔽状态、则会在100和200之间随机更改数字。

    总之、我发现这个问题是由两个直流电机产生的噪声引起的、这两个电机从 TM4C 开启的同一电路板上驱动。 我在传感器输入和 TM4C 之间添加了串联电阻器、加上从传感器输入到接地的电容器、并且虚假中断停止发生。 我仍然很好奇未启用的中断如何触发 ISR、但我认为问题已解决(目前)。

    感谢你的帮助