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:如何"restart"通用定时器?

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

https://e2e.ti.com/support/microcontrollers/arm-based-microcontrollers-group/arm-based-microcontrollers/f/arm-based-microcontrollers-forum/611966/tm4c123gh6pm-how-to-restart-a-general-purpose-timer

器件型号:TM4C123GH6PM
主题中讨论的其他器件:TM4C123

我正在尝试使用通用定时器外设来响应超时条件。 也就是说、在给定时间长度内没有特定事件的情况下、计时器应触发中断。

我在其他 MCU 上始终这样做的方法是设置计时器以生成周期性中断。 例如、如果事件预计每950us 发生一次、我可以配置一个周期计时器、每1ms 触发一次中断。 但我绝不允许触发该中断:每次发生相关事件时、事件处理程序都会重新启动计时器(根据计数方向将其计数器设置回0或最大值)。 如果事件没有发生、定时器会"超时"并触发中断、以处理缺少事件的情况。

我正在尝试使用 TivaWare 实现这一点。 我的思路是通过在每次事件发生时将开始值加载到 GPTMTAV 中来重新启动计时器(从而防止触发中断)。

我的问题:

1.这是不是"重新启动"计时器回到开始位置的正确方法?

2.如果是,TivaWare 提供函数 TimerValueGet (),但不提供函数 TimerValueSet()。 是否有可实现我所需功能的 TivaWare 函数?

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    单次触发模式不会对此更敏感?

    Robert

    或者更好的是、正确的系统事件计时器系统?
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    [引用 user="12ve12pm]...TivaWare 提供函数 TimerValueGet (),但不提供函数 TimerValueSet ()。   是否有可实现我所需内容的 TivaWare 函数?[/QUERP]

    相信、但由于您的经验和智慧、您"错过"这件事令人担忧(似乎)。   (注意:我的公司(仅限)采用了经过 StellarisWare 9453的版本(据信是"防弹型"-较新的版本-"不是太多!")   也许这个驻留在 StellarisWare 中的(应答)函数不会"传递"到您的"较新的"API。

    我提交,"TimerLoadSet()"-为了满足您的要求,非常出色(和预期)。   

    遵循此函数的详细说明。   (希望此函数"Do"能够应用于较新的 API 中...)

    27.2.2.17 TimerLoadSet
    设置计时器加载值。

    原型:
    无效
    TimerLoadSet (无符号长整型 ulBase、 无符号长整型 ulTimer、 无符号长整型 ulValue)

    参数:
    ulBase 是定时器模块的基地址。
    ulTimer 指定要调整的定时器;必须是 Timer_A、Timer_B 或 Timer_两者 之一。 当定时器被配置为全宽 运行时、只能使用定时器_A。
    ulValue 是加载值。

    描述:
    此函数用于配置定时器装载值;如果定时器正在运行、则该值会立即 装载到定时器中。   (即 "如您所需"- Mais oui?)

    注:
    此函 数可用于16/32位定时器的全宽和半宽模式以及32/64位定时器的半宽模式。   对于32/64位定时器的全宽模式、使用 TimerLoadSet64()。

    返回:
    无。

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

    无法"重新进入"我的帖子(如上)-原因是:"论坛升级(?);腕戴雨导致"一手"键入;由于"延迟"小时导致服务器编号/质量降低...

    这里揭示了"TimerLoadSet()"函数的本质-请注意、它运行在(不)"GPTMTAV"(您注意到的寄存器)-而是运行在"GPTMTAILR"(或 GPTMTBILR)上。    

    根据我的理解、寄存器"GPTMTAV"显示了定时器当前自由运行的值。   (这是您需要的!)   

    寄存器"GPTMTAILR"(或其"B"版本)加载定时器的"起始计数值"-这正是您所寻求的。  (海事组织)

    查看 StellarisWare 9453中的"timer.c"源代码:

    //如果需要,设置定时器的装载值。
    //
    if (ulTimer & timer_A)

    HWREG (ulBase + TIMER_O_TAILR)= ulValue;


    //
    //如果需要,设置定时器 B 的装载值。
    //
    IF (ulTimer & Timer_B)

    HWREG (ulBase + TIMER_O_TBILR)= ulValue;

    再说一次-虽然公司/我已经长期迁移到另一家的 Cortex M7 (>200MHz 和图形硬件加速器)、但我相信"TimerLoadSet()"证明"适合 Gov't (或您的)工作!"

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

    尊敬的 CB1_MOBILE:

    非常感谢您一如既往的帮助。

    我的印象是 GTPMxILR 寄存器(因此 TimerLoadSet())设置了在时钟开始新周期时加载到计数器中的计数。 我认为(但我不确定)这将导致时钟通过0并触发其中断、这不是我想要的。 但我是一名 TM4C n00b、因此我将对其进行测试、并很快返回到这里、结果是...

    很遗憾听到您的手腕。

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    Robert、在大多数情况下、我会按照您的建议使用软件事件计时器系统。 我始终实施用于非关键计时和超时的"低分辨率"计时器、其中可以接受一定程度的偏差。 不过、在这种特定情况下、相关事件是周期性的、每次不发生时、都必须通过我们的备用事件在确定的时间内进行补偿。
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    您好、12月12日下午、

    如果使用 TimerLoadSet (通过 CB1的方式、它在 TivaWare 中确实具有相同的功能)、也许我可以帮助澄清一点预期行为!

    从器件数据表的第11.3.2.1节中:

    如果软件在计数器递减的过程中更新了 GPTMTnILR 或 GPTMTnPR 寄存器、计数器将在下一个时钟周期加载新值、并且如果 GPTMTnMR 寄存器中的 TnILD 位清零、则从新值开始继续计数。 如果 TnILD 位置位、计数器在下一次超时后加载新值。

    这里的关键是  TnILD 位。 如果您确保该位为0、是的、它将再设置一个时钟周期来应用新值、 但此时计数将从新值开始、因此不应触发中断(除非该奇异时钟周期是中断发生的临界点、这听起来像是您根据初始说明添加缓冲时间来避免的)。 但是、如果您要设置 TnILD 位、那么它确实会继续计数、直到在这种情况下触发一个不需要的中断。 因此、您应该发现、只要  TnILD 位被清零、您就会得到预期的行为。

    让我们知道测试是如何进行的、以验证这一点。

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

    在我测试 TimerLoadSet()(我将很快执行此操作)之前,我将通过 TivaWare 安装目录中的所有文件再次搜索 TimerValueSet()。 我发现了一些有趣的东西...

    有一个文件 C:\ti\TivaWare_C_Series-2.1.4.178\nfclib\directmode.c

    它包含以下代码:

    //

    //

    //设置计时器值。

    // StellarisWare 计时器 API 中缺少此函数,所以它在这里

    //作为宏

    //

    //

    #define TimerValueSet (ulBase、ulTimer、ulValue)                \

      HWREG ((ulBase)+((ulTimer)=timer_A? Timer_O_TAV:Timer_O_TBV)=   \

        (ulValue)

    因此、这似乎证实了我先前的想法、即 TivaWare 中缺少该函数...

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    这是有道理的。 阅读说明后、数据表现在更有意义。 遗憾的是、数据表中的这一部分很难理解、因为有许多不同的解释会混合在一起。

    我还有一个问题:我正在使用一个80MHz 系统时钟并将定时器周期设置为1ms、这将转换为80、000个时钟周期、即0x13880、这需要一个24位值。 当我在启动时配置定时器时、通过调用 TimerPrescaleSet()将0x01写入 GPTMTAPR、通过调用 TimerLoadSet()将0x3880写入 GPTMTAILR。 当我想重新启动定时器时,是否有必要同时设置 GPTMTAPR 和 GPTMTAILR (即,调用两个函数来重新启动定时器),或者只通过调用 TimerLoadSet()来设置 GPTMTAILR 是否足够了?
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    我进行了进一步的实验。 由于24位计数、似乎有必要加载 GPTMTAPR 和 GPTMTAILR。

    非常感谢 CB1_MOBILE、Ralph 和 Robert 为您提供的所有帮助。

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

    我是否可以建议一种方法(安装时始终安装)来加快/简化/增强?

    您选择的"32位"定时器可以避免任何预分频所带来的复杂问题。   (虽然像(此处新禁止)和 kiss (在此处永久禁止)被供应商拒绝、但他们已使"数千"人"能够"系统地推动成功!"

    感谢您的"奖励"-遗憾的是、"鼓励、同事肯定的"已经(毫无道理)背离了这一"眼泪的传说!"

    KISS StellarisWare 9453 (仅支持"bullet-proof"的 API 版本:LM3S、LX4F、TM4C123)规则...    (注意:TM4C123支持输入电压为9453、只需添加一个输入电压为 PIN_MAP.h 的插件)

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    你是对的。 32位解决该问题。 或者、我可以继续使用16位计时器、但切换到周期模式、而不是 PWM 模式。 我不是在引脚上输出波形、而是仅使用该计时器生成中断。 如果我的理解是正确的,在周期模式下递减计数时,预分频器是一个真正的预分频器,因此我只需要使用 TimerLoadSet()。 我将在下一个页面中尝试、并让您了解它的运行情况。

    我想知道这个按钮发生了什么情况。 :-)
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    [引用 user="12ve12pm]]我想知道类似按钮发生了什么情况。 :-([/报价]

    我在"禁止"的第二天发表了一篇抗议/提问的帖子、并被介绍说"新的使用者(那些最不可能(曾经)使用"类似"的用户)"混淆了"、因此"相似"受到了指责。"   (供应商语言-略多-比我自己的语言"公司演讲"更好...)   

    著名的论坛海报"Robert &(even ) Jens"参加了"观看"(由 Moi 组织),同样"记录了他们的抗议!"    我们聚集在这里不是为了悼念“喜欢”,而是为了赞美“喜欢!”    说-"咖啡壶盖"是否只是(位)升起?   (当"灯熄灭"-达拉斯...)

    我相信您不需要 PWM 模式-您现有的周期(或 Robert 的"一次性")将起作用-尽管我相信 TimerLoadSet()函数-尤其是在您使用"倒计时"时-证明了您的要求的最佳(最轻松)满足...

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    考虑到几乎所有流行网站都有"类似"按钮、这很有趣。
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    [引用 USER="CB1_MOBILE "]

    我相信您不需要 PWM 模式-您现有的周期(或 Robert 的"一次性")将起作用-尽管我相信 TimerLoadSet()函数-尤其是在您使用"倒计时"时-证明了您的要求的最佳(最轻松)满足...

    [/报价]

    还可以! 周期模式的工作方式就像一种魅力。 要重新启动计时器,我现在只需要调用 TimerLoadSet()。 也无需调用 TimerPrescaleSet()。 我仍然只使用一半的计时器(16位模式)来保留更多计时器用于其他操作。

    为了便于参考和帮助将来可能需要的任何人、我设置了如下计时器:

    周期模式、拆分定时器(在本例中为16位、Timer B)、递减计数以获得真正的预分频器、GPTMTnMR 寄存器中的 TnILD 位清零以使 TimerLoadSet ()根据需要工作、预分频器在系统初始化时设置一次、 周期(GPTMTnILR)在系统初始化时设置、并在我们希望重新启动计时器时再次设置。

    以下代码中出现的一些定义:

    #define SYSTEM_CLOCK_FREQ_Hz   8000000

    #define M_TMR_FREQ_Hz        1000

    #define M_TMR_PREcaler       10.

    #define M_TMR_INPUT_FREQ_Hz    ((SYSTEM_CLOCK_FREQ_Hz)/(M_TMR_PRERR)

    #define M_TMR_PERIOD        ((M_TMR_INPUT_FREQ_Hz)/(M_TMR_FREQ_Hz)

    #define M_TMR_INTERRUPT_PRIORITY 3.

    定时器初始化:

    SysCtlPeripheralDisable (SYSCTL_Periph_Timer1);

    SysCtlPeripheralReset (SYSCTL_Periph_Timer1);

    SysCtlPeripheralEnable (SYSCTL_Periph_Timer1);

    while (SysCtlPeripheralReady (SYSCTL_Periph_Timer1)!= true){

    //等待外设激活

    //将半计时器配置为周期计时器

    TimerConfigure (Timer1_base、(TIMER_CFG_SPLIT_PAIR | TIMER_CFG_B_PERIODICASE));

    //非常重要:确保对 TimerLoadSet()的调用将在下一个时钟时重新启动计时器

    TimerUpdateMode (Timer1_base、timer_B、timer_up_load_immediate);

    //设置预分频器

    TimerPrescaleSet (Timer1_base、timer_B、(M_TMR_prescaler - 1));

    //设置周期

    TimerLoadSet (Timer1_base、timer_B、M_TMR_PERIOD);

    //设置中断优先级

    IntPrioritySet (INT_TIMER1B、M_TMR_INTERRUPT_PRIORITY);

    //启用中断

    TimerIntEnable (Timer1_base、timer_TIMB_TIMEOUT);

    IntEnable (INT_TIMER1B);

    //启用计时器

    TimerEnable (Timer1_base、timer_B);

    当我想重新启动计时器、防止超时中断时:

    TimerLoadSet (Timer1_base、timer_B、M_TMR_PERIOD);

    我同意他们应该返回"类似"按钮。 它还应像书签一样工作、以便您可以返回并轻松查找您喜欢的帖子、以便在以后引用它们。

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

    对您来说很好-您的帖子中的关注、努力和细节"肯定"会使其价值倍增!
    供应商的 Ralph 提出了一个好问题:"TnILD"-我不记得我们(旧版)的 API 是否包含您(单独)找到和部署的函数"TimerUpdateMode()-当"学生接替教师!"  (并且不会"摩擦"-太糟糕了!)

    您的书签创意显示"伟大"创意-在我公司的案例中-我们"复制/粘贴"此类"增强代码块和/或操作提示"到共享的 Word 文件中-每个新条目都按主题紧密组织。 (我们注意到供应商的"标签"(主要是广告)被证明是令人憎恶的-因此我经常创作-更好地表示"技术援助现实"。)

    快速/轻松地"查找关键技术数据"的能力-对于小型技术业务的成功和发展至关重要-在这里出现(几乎)"空间损失"、而优步使用(不是)"博客、小组、视频"享受"海滨位置"-对(近)零位访客来说!   (隐藏重要的技术数据可能没有太大意义-如果供应商的"风格指南可以成熟-包括大多数技术数据-在原始的红条纹(海滨)房地产中、用户知识将会大大增强。"   (crüe“无样的!”的另一种愤怒)

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    很难找到合适的技术数据。 搜索通常会使信息变得过于基本或过于高级。 此类论坛对于交流正确的信息非常重要。