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:代码进入 exit.c

Guru**** 2952510 points

Other Parts Discussed in Thread: EK-TM4C123GXL

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

https://e2e.ti.com/support/microcontrollers/arm-based-microcontrollers-group/arm-based-microcontrollers/f/arm-based-microcontrollers-forum/820957/tm4c123gh6pm-code-goes-into-exit-c

器件型号:TM4C123GH6PM
Thread 中讨论的其他器件:EK-TM4C123GXL

由主持人编辑(问题在标题中):
问题1:当我运行,以下的代码时,它始终进入 exit.c (void abort(void))  ,如果我在 末尾添加一个 while (1),它将不会进入 exit.c 问题2:我使这个项目测试下面的 ButtonPoll(),我从 www.ti.com/.../tidcb5复制了它

/**
 * main.c
 *

#include
#include
#include "inc/hw_types.h"
#include "inc/hw_memmap.h"
#include "inc/hw_gpio.h"
#include "driverlib/fpu.h"
#include "driverlib/gpio.h"
#include "driverlib/sysctl.h"
#include "driverlib/rom.h"
#include "driverlib/pin_map.h"
#include "driverlib/interrupt.h"
#include "driverlib/gpio.h"

uint8_t ButtonPoll (uint8_t *、uint8_t *);

  两个按键状态,初始化为高,按下 uint8_t g_ui8ButtonStates = GPIO_PIN_0|GPIO_PIN_4;//μ s

uint8_t * pui8Delta = 0;
uint8_t * pui8RawState = 0;
uint8_t ui8Buttons = 0;

int main (空)
{
   SysCtlClockSet (SYSCTL_SYSDIV_5|SYSCTL_USE_PLL|SYSCTL_XTAL_16MHz|SYSCTL_OSC_MAIN);
   SysCtlPeripheralEnable (SYSCTL_Periph_GPIOF);
   HWREG (GPIO_PORTF_BASE + GPIO_LO_LOCK)= GPIO_LOCK_KEY;
   HWREG (GPIO_PORTF_BASE + GPIO_O_CR)|= 0x01;
   HWREG (GPIO_PORTF_BASE + GPIO_LO_LOCK)= 0;
   GPIOPinTypeGPIOOutput (GPIO_PORTF_BASE、(GPIO_PIN_1 + GPIO_PIN_2 + GPIO_PIN_3));
   GPIOPinTypeGPIOInput (GPIO_PORTF_BASE、(GPIO_PIN_0 + GPIO_PIN_4));

   GPIODirModeSet (GPIO_PORTF_BASE、 GPIO_PIN_0|GPIO_PIN_4、GPIO_DIR_MODE_IN);
   GPIOPadConfigSet (GPIO_PORTF_BASE、GPIO_PIN_0|GPIO_PIN_4、
                           GPIO_Strength _2mA、GPIO_PIN_TYPE_STD_WPU);

   G_ui8ButtonStates = GPIOPinRead (GPIO_PORTF_BASE、GPIO_PIN_0|GPIO_PIN_4);

//   while (1)
//   {
//       SysCtlDelay (SysCtlClockGet ()/3000);
//       ui8Buttons = ButtonPoll (pui8Delta、pui8RawState);
//   }

}

uint8_t ButtonPoll (uint8_t * pui8Delta、uint8_t * pui8RawState)
{
   uint32_t ui32Delta;
   uint32_t ui32Data;
   静态 uint8_t ui8SwitchClockA = 0;
   静态 uint8_t ui8SwitchClockB = 0;

   //
   //读取按钮的原始状态。  保存原始状态
   //(反转位检测)(如果调用方为提供存储)
   //原始值。
   //
   ui32Data =(GPIOPinRead (GPIO_PORTF_BASE、GPIO_PIN_0|GPIO_PIN_4));
   if (pui8RawState)          //指针非空
   {
       * pui8RawState =(uint8_t)~ui32Data;//现在的状态取反得到原来的状态
   }

   //
   //确定与反跳状态不同的开关(抖动)
   //状态。
   //
   ui32Delta = ui32Data ^ g_ui8ButtonStates;

   //
   //将时钟递增一。
   //
   ui8SwitchClockA ^= ui8SwitchClockB;
   ui8SwitchClockB =~ui8SwitchClockB;

   //
   //重置与状态未改变的开关对应的时钟。
   //
   ui8SwitchClockA &= ui32Delta;
   ui8SwitchClockB &= ui32Delta;

   //
   //获取新的反跳开关状态。
   //
   g_ui8ButtonStates &= ui8SwitchClockA | ui8SwitchClockB;
   g_ui8ButtonStates |=(~(ui8SwitchClockA | ui8SwitchClockB))和 ui32Data;

   //
   //确定刚刚更改去抖状态的开关。
   //
   ui32Delta ^=(ui8SwitchClockA | ui8SwitchClockB);

   //
   //存储为返回而更改的按钮的位掩码
   //调用方。
   //
   if (pui8Delta)
   {
       * pui8Delta =(uint8_t) ui32Delta;
   }

   //
   //将反跳按钮状态返回给调用方。  将该位反相
   //进行检测,使'1'指示按钮被按下,即 A
   //解释返回值的明智方法。
   //
   return (~g_ui8ButtonStates);
}

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

    你好,利国

    如果您在末尾没有 while (1)、则没有更多代码可执行、因此 MCU 不再需要执行任何操作、并会如您所见退出。 如果您希望代码继续运行、则需要 while (1)。 这是每个 MCU 的标准。

    对于问题2、它被截断、因为您尝试将其放在标题中。 请在帖子中解释您的问题。

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

    您好、Ralph、我从  某个位置复制了这个函数 uint8_t ButtonPoll (uint8_t * pui8Delta、uint8_t * pui8RawState)、正如您在上面看到的、它的注释也在解释

    它可以帮助判断 SW1和 SW2的状态,但我真的对 该函数如何实现其目标感到困惑。 我的英语不是很好,所以我不 能理解它的评论和逻辑;

    至于 Q1、我的代码总是在 exit.c (更具体的是:abort 函数)中跳闸、我认为这不是正常的、所以我想知道为什么、毕竟、如果代码运行正确、它不会进入 exit.c 和 abort。 我可以通过添加 while (1)来防止它中止、但这不是一种好方法。

    感谢你的帮助。

    此致

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

    你好,利国

    应该使用 while (1)、而不使用 while (1)是不好的。 如果没有 while (1)并且代码运行正确、则它将始终以 exit.c 结束 如果没有 while (1)、则没有更多代码需要处理、因此它会因为程序完成而中止。 没有什么可做的。

    尝试查看我的意思。

    从用于 LaunchPad 的 TivaWare 中加载 hello 工程、并按开箱即用的方式运行。

    然后、注释掉 while (1)循环、该循环没有任何作用、只能使 LED 闪烁。

    查看当您注释掉 while (1)时代码结束的函数。

    关于您的第二个问题、我建议您通读 EK-TM4C123GXL 用户指南中的按钮驱动程序部分。 您可以在 TivaWare 的 docs 文件夹中找到该指南。 标题为 SW-EK-TM4C123GXL-UG-2.1.4.178.pdf。

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

    您好、Ralph、

    您对" while 循环"的"必要性"有非常好的解释和解释。

    我 认为(不是太谦虚)、"海报的学习欲望"值得称赞。

     按钮驱动程序部分中的特定代码虽然良好、但  远比(真正)所需的"间接和复杂"多得多。   这 是 此海报(和其他人)抵制和/或混淆的可能原因。

    读取连接到 MCU 引脚的开关需要" 现实世界"识别"切换抖动 "、这并不总是到达-在 MCU 手册的1K+页中(甚至)。  

    通常情况下、MCU 必须被订购为"等待"-在"反弹周期"过期后、必须订购为"只读开关"。  

    (如果读取太快-很可能会记录(非法)退回事件-如果读取太晚-开关可能已经释放!)  这是一个(非常)好的收获- 22 -是不是?

    我的公司试图 通过 以下方式解决这一困境:

    • 选择具有可预测(和可重复)抖动周期的开关
    • 定期监控这些开关-确保反弹周期保持预期
    • 导致初始开关闭合(通常接地)产生"开关准备读取中断"
    • 然后插入适当的延时时间-刚好超过最大开关抖动时间
    • 然后-执行 Switch Read 命令 (详细信息如下-为"等式方法序列"保留的空间)

    我不在办公室-但(可能)记得(大多数)上述程序的详细信息。  合理的"静脉"机械开关可能会"抖动"(触点"抖动"-或"反复"震颤")-可能长达30 - 50mS。  "人按键"在150毫秒内不可能释放。  因此、存在一个(接近) 100mS 间隔、其中钥匙(或开关)已停止弹跳、并且在钥匙释放之前(仍然)!   然后、这是读取该"开关或钥匙"的"理想时间窗口"。   采用 R-C 滤波器也很有用-可减少抖动周期。   但仍然-建议"避免开关读数"、直到之后-任何/所有潜在的钥匙弹出停止!

    请注意、这种方法在读取(偶数)多个开关时很有效-尽管在这种情况下- 必须采用"多个中断"(以及后续延迟)。

    有时、"更具价值的方法"证明...  尤其是当程序完全/正确地详细时-这(可能只是)-这里的情况...

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

     大家好、CB1_MOBILE、再次感谢您的帮助、您的知识非常丰富、我希望将来能从您那里了解更多信息。

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

    您好、Ralph、感谢您的耐心帮助、我将听从您的建议并尝试一下。

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

    也谢谢王先生。   帮助那些"有高度学习动力"的人是令人高兴的-正如你(如此清楚)所说的那样。   您提醒我、我公司的大多数员工-年轻、努力、寻求无限挑战。   (敢说——热情(熟练)的管理!)

    现在请遵守 Ralph 的指导-他"完全正确!"    我向您保证-及时-您"将完全理解"-"while 循环"的关键/关键价值。

    如果您可以"采集示波器"-您可以使用各种不同的机械开关进行实验-并观察前面所述的"接触振荡器"。  朋友或附近的学校或(甚至)"实验者俱乐部"可能有这样的器械-如果您没有的话。   查看不同的信号-并注意它们之间的关键、定时关系-将极大地帮助您学习。

    我想说拉尔夫的帖子"赢得了你的"验证-这样做将使拉尔夫解放出来帮助(很多)其他人...