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.

[参考译文] CCS/TM4C1294NCPDT:TIVA129中的32位定时器

Guru**** 2481465 points


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

https://e2e.ti.com/support/microcontrollers/arm-based-microcontrollers-group/arm-based-microcontrollers/f/arm-based-microcontrollers-forum/703974/ccs-tm4c1294ncpdt-32-bit-timer-in-tiva129

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

工具/软件:Code Composer Studio

尊敬的所有人  

我正在进行一个需要脉冲很长时间的项目、到目前为止、所有项目都与我的老朋友 TM4C123完美配合、但现在我需要将代码移至129、因为我需要它的以太网功能。 我在123上使用了宽定时器、我知道 TM4C129没有、但我可以将它们配置为32位、以便我可以实现非常低的频率。 是否有人在这件事上有经验、或者在我丢失任何东西的情况下、是否可以查看我的代码。  

提前感谢  

void Timer1 (){//SH
uint32_t ulPeriod、dutyCycl1;

SysCtlPeripheralEnable (SYSCTL_Periph_GPIOA);
SysCtlPeripheralEnable (SYSCTL_Periph_TIMER2);
GPIOPinConfigure (GPIO_PA5_T2CCP1);
GPIOPinTypeTimer (GPIO_Porta_base、GPIO_PIN_5);


ulPeriod = g_ui32SysClock/0.5;
dutyCycl1 =(无符号长整型)(ulPeriod-1)*0.33;

TimerConfigure (TIMER2_base、TIMER_CFG_SPLIT_PAIRGE|TIMER_CFG_B_PWM);
TimerControlLevel (TIMER2_base、TIMER_B、1);

TimerLoadSet (TIMER2_base、TIMER_B、ulPeriod-1);
TimerMatchSet (TIMER2_base、TIMER_B、dutyCycl1);
TimerEnable (TIMER2_base、TIMER_B);

}

和我的系统时钟  

G_ui32SysClock = MAP_SysCtlClockFreqSet ((SYSCTL_XTAL_25MHz |
SYSCTL_OSC_MAIN | SYSCTL_USE_PLL |
SYSCTL_CFG_VCO_480)、120000000);

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

    以下几点:

    [引用用户="Israel Redo"]

    TimerConfigure (TIMER2_base、TIMER_CFG_SPLIT_PAIRGE|TIMER_CFG_B_PWM);
    

    [/报价]

    我认为 TIMER_CFG_SPLIT_PAIR 不是您想要的、因为它只配置定时器外设的16位 TimerB。 您需要将其配置为32位模式、这种模式会将两个16位半定时器连接在一起以形成一个32位定时器。

    [引用用户="Israel Redo"]

    ulPeriod = g_ui32SysClock/0.5;
    dutyCycl1 =(无符号长整型)(ulPeriod-1)*0.33;
    

    [/报价]

    您的里程可能会有所不同、但在多个 CPU/MCU 平台上和使用多个编译器时、我在将数字从 float 类型直接转换为 unsigned int 类型时遇到了问题。 我不确定、但我认为编译器的观点是、我要求浮点数的位模式、当我真正想要截断该数字的十进制部分并将剩余的整个部分转换为无符号整数时。 因此、我首先将浮点值转换为有符号整型、然后将其拼写为无符号整型。 在转换之前、我检查该值是否适合中间和最终 int 类型而不会溢出。

    此外、您没有指定什么是"非常低的频率"、但也许可以通过使用足够的预分频器和/或从较慢的源驱动时钟来实现。  

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    尊敬的@12ve12pm TimerConfigure 是我的主要问题(我正在处理此问题)、关于浮点类型转换是一个非常好的问题、我必须说我没有发现 Tiva 123的问题、因此我将其作为一个问题丢弃、但我会记住它。

    极低的频率约为0.5Hz (宽定时器让我惊讶于它的易用程度)、我尝试了预分频器但没有成功。 感谢您的回复、我将重新配置计时器并进行报告。
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    [引用用户="Israel Rebolledo]亲爱的@ü r 12ve12pm TimerConfigure 是我的主要怀疑对象(我正在研究这个问题)、关于浮点型转换是一个很好的问题、我必须说我没有发现 Tiva 123的问题、 因此、我放弃了这一问题、但我会记住这一点。

    极低的频率约为0.5Hz (宽定时器让我惊讶于它的易用程度)、我尝试了预分频器但没有成功。 感谢您的回复、我将重新配置计时器并进行报告。

    [/报价]

    您的0.5Hz 频率是否需要非常精确? 如果时间不是很关键、可以设置 SysTick 计时器(TM4C12x 嵌入式 Arm Cortex M4F CPU 的一部分)来提供1000Hz 中断。 我总是设置这样一个中断。 在中断处理程序中、我递增一个名为 Global. ticks 的全局易失性 uint32_t 变量。 该变量可用于从毫秒到大约49天(7周)范围内的低分辨率计时、之后会回滚到0。 要使用它、主上下文代码可以将 Global. tick 的值保存在变量中、然后从最新的 tick 计时器值中减去该值以计算经过的时间。 如果一段时间已经过去、新的 Global. ticks 值将保存到变量中、并执行一些操作。 令人惊讶的是、以毫秒、秒、分钟、小时或天为单位测量的东西有多少、 这种方法可以处理相对较好的准确度,这取决于主循环的执行频率,前提是主循环不会在某些阻止代码中“卡住”,从而阻止计时事件的处理。

    同时,为了生成0.5Hz 的波形,我会将输出引脚设置为 GPIO 模式,在 SysTick 中断处理程序中,我会计数到500,然后重置计数器并切换输出-- 这当然是假设您的波形不需要非常精确、因为它的软件性质会导致一些抖动。

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

    我写了一些伪代码来说明我在上一篇文章中描述的内容:

    #define system_clock_FREQ_Hz 120000000
    #define SYSTICKS_FREQ_Hz 1000
    
    
    结构{
    uint32_t SysClockFreqHz;
    uint32_t tick;
    //要放在此处的任何其他全局数据
    }全局;
    
    
    //确保 C 启动文件将此函数分配给正确
    的//中断矢量!!
    void IsrLowResTimerHandler (void)
    {
    static uint32_t Counter = 0;
    
    Global. ticks ++;
    
    //在这里生成0.5Hz 方波
    Counter++;
    if (Counter >= 1000){
    Counter = 0;
    ... 在此处切换 GPIO 引脚
    ...}
    }
    
    
    uint32_t TickGet (void)
    {
    return Global. ticks;
    }
    
    
    void Init (void)
    {
    //...
    MAP_FULazyStackingEnable();
    
    //以下两行用于 TM4C129,具有外部25MHz 时钟,
    //实现120MHz 系统时钟
    SysCtlMOSCConfigSet (sysctl_MOSC_HIGHFREQ);
    Global. SysCtlFreqHz = MAP_SysCtlClockFreqSet ((SYSC_MOSC_HCFG_);SysClock_TOT_SYSC_TOCLK
    
    ;SysTCL_SYSC_SYSC_TON.TX_ENCH
    
    
    
    //...
    }
    
    
    void Run (void)
    {
    static bool firsttime = true;
    static uint32_t LocalTicks = 0;
    
    if (firsttime){
    firsttime = false;
    LocalTicks = TickGet ();
    }
    
    if (TickGet ()- LocalTicks >= On_Hour_in_ticks){
    LocalTicks = Ticket ();
    
    ... 每小时执行一次...
    }
    }
    
    
    int main (void)
    {
    Init();
    while (1){
    Run();
    }
    
    

    希望这对您有所帮助