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.

[参考译文] Starterware/EK-TM4C1294XL:TIVAC- 1294xl Launchpad 上的 Button (SW1)中断

Guru**** 2442090 points


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

https://e2e.ti.com/support/microcontrollers/arm-based-microcontrollers-group/arm-based-microcontrollers/f/arm-based-microcontrollers-forum/629304/starterware-ek-tm4c1294xl-button-sw1-interrupts-on-tivac--1294xl-launchpad

器件型号:EK-TM4C1294XL

工具/软件:Starterware

您好!  

我一直在使用 TIVAC-1294xl launchpad。 我已经使用了计时器中断、并希望了解开关的中断。  

我执行了以下步骤。  

SysCtlPeripheralEnable (SYSCTL_Periph_GPIOJ);
GPIODirModeSet (GPIO_PORTJ_BASE、GPIO_PIN_0、GPIO_DIR_MODE_IN);
GPIOPadConfigSet (GPIO_PORTJ_BASE、GPIO_PIN_0、GPIO_Strength _2mA、GPIO_PIN_TYPE_STD_WPU);//针对开关1
IntMasterEnable();
IntEnable (INT_GPIOJ);

 在启动文件中、我定义了一个函数 buttonpress 来代替 GPIO 端口 J、还将 extern 函数定义为 void buttonpress (void); 

现在、在 main.c 中、我有以下代码。

void buttonpress (void)
{
if (GPIOPinRead (GPIO_PORTJ_BASE、GPIO_PIN_0)=0)
{
//使 LED 闪烁以进行调试
}
}

有人能解释一下开关中断的正确流程吗?

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

    [引用 user="Nishit"]现在在 main.c 中,我有以下代码。  

    void buttonpress (void)
    您的“主题行”列出了“切换中断”,但您列出了位于“main”中的“buttonpress ()”。   它是否应该(有些)远离主中断-并且位于(其他)中断之间?   (如有)

    最重要的是-您是否在您的"启动文件"中放置并声明了"buttonpress()函数-并将其与"端口 J 的 ISR 插槽"匹配?   请注意、有一个 ISR 源的"长列表"-每个源都必须在"投入使用"时命名。   (“buttonpress”将与 Port J ISR 放在同一行...  假定端口 J 不提供"位类型"中断)

    我在您的代码列表中找不到此(重要)函数:"GPIOIntTypeSet()。"   

    该函数的建议参数(可能)包括:"GPIO_PORTJ_BASE、GPIO_PIN_0、 GPIO_RISING (或下降)_EDGE (或电平)"。

    SW-TM4C-DRL"用户指南"非常详细-帮助用户舒适、快速和理解...  (并提供"合理"的示例。)   (但"努力"-显然是为了"不受欢迎/放松的论坛降级(即(类似)的激励...)。

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

    出于"未知"的原因(即使在所称论坛"升级"之后)、我也无法编辑上述内容。

    下面是如何管理"我们的启动文件"的详细图示。   (根据您的用途而调整-请注意、我已在您的函数名称中添加"int"、以强化其用作中断的作用!)

    //应用程序使用的中断处理程序的外部声明。
    //
    //
    extern void IntDefaultHandler (void);
    extern void intbuttonpress (void);//您必须输入此-如此处所示



    //矢量表。 请注意、必须将适当的构造放置在到上
    //确保它最终位于物理地址0x0000.0000。
    //
    //
    __root const uVectorEntry __vector_table[]@".intvec"=

    {.ulPtr =(无符号长整型) pulStack + sizeof (pulStack)}、
    //初始堆栈指针
    ResetISR、//复位处理程序
    NmiSR、// NMI 处理程序
    FaultISR、//硬故障处理程序
    IntDefaultHandler、// MPU 故障处理程序
    IntDefaultHandler、//总线故障处理程序
    IntDefaultHandler、//用法故障处理程序



    Intbuttonpress、       // GPIO 端口 J
    IntDefaultHandler、     // GPIO 端口 K
    IntDefaultHandler、     // GPIO 端口 L

    怀疑上面的帖子-由此处放大-应该会使您"空中!"  (至少是按中断操作...)

    我会避免使用 IntRegister(),因为它会使(许多)情况下的情况变得复杂,并且没有什么好处...   按照指示在启动文件中简单放置、可轻松使中断成功!

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

    是的、我在启动文件中完成了与上述内容完全相同的操作。 在 int main()中,我进行了如下更改。

    int main (void)
    {
    G_ui32SysClock = MAP_SysCtlClockFreqSet ((SYSCTL_XTAL_25MHz |SYSCTL_OSC_MAIN |SYSCTL_USE_PLL |SYSCTL_CFG_VCO_480)、120000000);
    
    // //
    // 配置 LED 引脚 //
    
    SysCtlPeripheralEnable (SYSCTL_Periph_GPION);
    GPIOPinTypeGPIOOutput (GPIO_PORTN_BASE、GPIO_PIN_0);
    
    // //
    
    //********* //
    // 配置交换机 //
    
    SysCtlPeripheralEnable (SYSCTL_Periph_GPIOJ);
    GPIODirModeSet (GPIO_PORTJ_BASE、GPIO_PIN_0、GPIO_DIR_MODE_IN);
    GPIOPadConfigSet (GPIO_PORTJ_BASE、GPIO_PIN_0、GPIO_Strength _2mA、GPIO_PIN_TYPE_STD_WPU);
    
    // //
    
    // //
    // 使能中断 //
    
    IntMasterEnable();
    IntEnable (INT_GPIOJ);
    GPIOIntTypeSet (GPIO_PORTJ_BASE、GPIO_PIN_0、GPIO_FALLING_EDGE);
    
    // //
    
    while (1)
    {
    
    }
    
    返回0;
    } 

    而 buttonpress()例程出现在 main.c 中,其中包括如下所示的代码。

    void buttonpress (void)
    {
    if (GPIOPinRead (GPIO_PORTJ_BASE、GPIO_PIN_0)=0)
    {
    GPIOPinWrite (GPIO_PORTN_BASE、GPIO_PIN_0、GPIO_PIN_0);
    for (ui32Loop = 0;ui32Loop < 200000;ui32Loop +)
    {
    }
    GPIOPinWrite (GPIO_PORTN_BASE、GPIO_PIN_0、0x0);
    for (ui32Loop = 0;ui32Loop < 200000;ui32Loop +)
    {
    }
    }
    


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

    如果-正如您声称的-您已在矢量表中正确放置了"buttonpress()(即与 Port-J 对齐)-并且"已声明它"-这在您的初始帖子中从未提及-则需要此类详细信息。

    现在-您是否已经测试并确认任何此类"按钮按压"(即通过硬件)会导致您"进入"按钮按压 ISR?
    如果是这样-"if 子句"的要点是什么-因为它必须"是真的"、即在 PJ0上"感觉"了负边沿。

    更重要的是,您永远不会在 button() ISR 中“清除中断”。 这是必需的...

    请注意、您"停留"在"流程"上-但代码基础知识(似乎)是问题的根源。   而且(一如既往)海报未能说明其选择/信仰的理由...

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    是的。 我在发布上述代码后了解到、不需要 ISR 中的 IF 子句。 在我的第一篇文章中,我还提到我已经在端口 J 的位置定义了 buttonpress(),并且还使用 extern 定义了函数。 我将从下一次开始进行更详细的解释。 注意到。 我还检查了您提到的关于执行是否曾进入 ISR 的第二条语句。

    执行永远不会进入 ISR。 是的,我将在 buttonpress() ISR 中包含清除中断。 但首先它应该进入 ISR。
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    很难想象-如果你(现在)说/报告的内容证明是真的-不会进入"buttonpress" ISR。

    一阶会看到、"Testing of the switch signal "aching (Testing of the switch signal "aching" PJ0 (@ the MCU -请小心)、并且 PJ0从~3V3转换到 GND -当开关被按下/保持时。 (3V3是由您启用 MCU 内部的"WPU"(弱上拉)产生的)

    请注意、为清楚起见-我自己/他人(通常)"前缀"一个 ISR w/"int"-它很好地表示此类中断角色。 我的(示例)代码遵循了这一做法-如果您"混合" intbuttonpress 和 buttonpress -应该会导致错误、并且 MCU 混淆... (伴无电帮助者...)

    我们注意到您对"GPIODirModeSet()"的使用。 您可以通过另一个 API 函数将 PJ0设置为用作 GPIO 输入。 (在 DRL 用户指南中注明-之前提到)如果您的中断(仍然)退出激活-我将替换"dirmodeset"。
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    [引用 USER="CB1_MOBITION]*请注意、为清楚起见-我本人/其他人(通常)"前缀" ISR w/"int"-这很好地表示此类中断角色。 我的(示例)代码遵循了这一做法-如果您"混合" intbuttonpress 和 buttonpress -应该会导致错误、并且 MCU 混淆... (以及无电帮助者...)[/引述]

    我不明白你在这里说什么?  

    您能用更清晰的语言再次解释一下吗?

    谢谢!

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    您将 ISR 命名为"buttonpress"。 在我提供的代码中-为了"更好"标记(或表示) ISR -它被命名为"intbuttonpress"。

    ISR 的名称-包含在主程序中-和包含在"启动文件"中-必须匹配。

    我想确保我使用"更易于识别"的 intbuttonpress 不会与您继续使用 buttonpress "混合"。 (不易识别为 ISR。

    您对仔细"探测" PJ0的方向"无提示"(即未响应)-开关启动且空闲时均为"探测" PJ0、并确认 PJ0从~3V3转换到 GND。 (启动开关时为 GND (启动时假设开关电路"闭合"至 GND)。 我没有您的 MCU 和电路板-"下降沿"中断限定符"取决于您的开关"接近 GND"。
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    Nishit、您好!

    您可以在 Tivaware "interrupts"示例程序中看到一些 CB1建议。

    还有一个按钮驱动程序、用于 QS_IoT 示例程序。

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

    [引用 USER="CB1_MOBIT)]第一个订单将看到您的:"测试开关信号"到达" PJ0 (@ MCU -请小心)、PJ0从~3V3转换到 GND -当开关被按下/保持时。 (3V3是由您启用 MCU 内部的"WPU"(弱上拉)产生的)[/quot]

    我检查了微控制器 PJ0引脚上的电压。 每当按下按钮时、它都会将状态从3V3更改为 GND。  

    [引用 user="CB1_MOBIST]我们注意到您使用的是"GPIODirModeSet()"。 您可以通过另一个 API 函数将 PJ0设置为用作 GPIO 输入

    我也更改了这个并使用了  

    GPIOPinTypeGPIOInput (GPIO_PORTJ_BASE、GPIO_PIN_0); 

    将 GPIO 引脚用作输入。  

    在 buttonpress() ISR 中,现在我要使板载 LED 闪烁以进行调试,但执行不会进入 ISR。  

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

    [引用 USER="Nishit]]在 buttonpress() ISR 中,现在我要使板载 LED 闪烁以进行调试,但执行不会进入 ISR。  [/报价]

    这很奇怪-感谢您执行测试@实际 MCU 引脚 PJ0。   您对"GPIOPinTypeGPIOInput()"的更改非常好。  (应其他 PJ0配置之前发生。)

    假设您已经在 buttonpress() ISR 中放置了一个包含中断点,这是正确的吗?   您是否可以添加一条简单的 GPIO 指令"w/in and 顶层"该 ISR -并将断点放置在该代码行上?

    所有其他代码应(暂时)删除-我们只希望让 MCU "在简单循环中旋转"-并且只能在唯一(仅) PJ0发生时退出/退出-下降沿中断!

    我即将"沮丧-疲惫":按照您 的 ISR 的指示添加:

    void buttonpress (void)(空)

    GPIOPinRead (GPIO_PORTJ_BASE、GPIO_PIN_0);  //在此代码行(而不是函数名称)上设置断点并消除(更早版本) IF


    是否不能达到此断点-您可以在任何代码行上断点-任何位置?   真的吗?   您上次检查是在什么时候?  (最好的是现在!)

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

    以下是我在您的指导下、按照一些旧学校方法(如使用数字万用表)尝试的所有操作。 :p

    我将2个 Berk 引脚焊接在 launchpad 边缘提供的用于 PJ0和 PJ1的分线板上。 然后、我检查了这些引脚与开关焊盘的连接(我们只考虑中的 SW1)。 在这里、每当我按下开关时、我都会得到一个连接。 在这里、我注意到 PJ0的默认状态是接地(如果没有通过代码分配任何内容来更改引脚的默认状态)。 因此、我在代码中进行了以下更改、以将默认状态更改为弱上拉。 (GPIOPadConfigSet)

    我还添加了 GPIOIntRegister API、它在我之前的代码中缺失。  

    void buttonpress (void)
    {
    GPIOIntClear (GPIO_PORTJ_BASE、GPIO_INT_PIN_0); //首先清除中断标志。
    ledblink();
    }
    int main (void)
    {
    G_ui32SysClock = MAP_SysCtlClockFreqSet ((SYSCTL_XTAL_25MHz |SYSCTL_OSC_MAIN |SYSCTL_USE_PLL |SYSCTL_CFG_VCO_480)、120000000);
    
    // //
    // 配置 LED 引脚 //
    
    SysCtlPeripheralEnable (SYSCTL_Periph_GPION);
    GPIOPinTypeGPIOOutput (GPIO_PORTN_BASE、GPIO_PIN_0);
    
    // //
    
    //********* //
    // 配置交换机 //
    
    SysCtlPeripheralEnable (SYSCTL_Periph_GPIOJ);
    GPIOPinTypeGPIOInput (GPIO_PORTJ_BASE、GPIO_PIN_0); //将引脚设置为输入。
    GPIOPadConfigSet (GPIO_PORTJ_BASE、GPIO_PIN_0、GPIO_Strength _2mA、GPIO_PIN_TYPE_STD_WPU); //将默认状态设为上拉状态。
    
    // //
    
    // //
    // 使能中断 //
    
    GPIOIntRegister (GPIO_PORTJ_BASE、buttonpress); //指定它应该跳转到的 ISR。
    GPIOIntTypeSet (GPIO_PORTJ_BASE、GPIO_PIN_0、GPIO_LOW_LEVEL); //指定触发跳转的状态。
    GPIOIntEnable (GPIO_PORTJ_BASE、GPIO_PIN_0); //为特定引脚启用中断。
    IntMasterEnable(); //为控制器启用中断。
    
    // //
    
    while (1)
    {
    
    }
    
    返回0;
    }
    

    后来、针对两个按钮(SW1和 SW2)尝试了相同的代码、并且运行顺利、符合预期。  

    感谢您在提出任何问题时快速而又敏锐的回答。  

    此致、

    Nishit。

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

    [引用 user="Nishit">感谢您在提出任何问题时快速而又快速地作出答复。  [/报价]

    感谢您的善意和(早期)坚持接受一些/轻微的技术方向。

    请注意、您已将代码从"下降沿检测"更改为"GPIO 低电平"。   现在、这种"液位检测"虽然持续存在、但很可能会导致(近)连续、"返回到您的"按钮按压"ISR 的条目!"   这(真的)是您想要的吗?   "边沿检测"方法避免了这种情况。

    虽然您的善意评论很受欢迎、但"验证答案"的授予已"逃脱"我的任何/所有职位。   (如果没有"被流放的类似"按钮-此类"验证奖励"(应用于"帮助者"帖子)证明非常有用...