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.

[参考译文] TM4C129ENCZAD:无法将通用计时器清零。

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

https://e2e.ti.com/support/microcontrollers/arm-based-microcontrollers-group/arm-based-microcontrollers/f/arm-based-microcontrollers-forum/1476083/tm4c129enczad-unable-to-clear-general-purpose-timers-to-zero

器件型号:TM4C129ENCZAD

工具与软件:

您好!

我将使用通用计时器来对边沿进行计数并记录流量计的总流量。  

我需要清除计时器值、每当流程开始时让它再次从0开始、并且我需要记录边沿数。 但是、归零零件不起作用。 下面是我创建的用于定时器重置的函数代码。:

空洞
TimerReset (uint32_t ui32Base、uint32_t ui32Timer)

if (((ui32Timer & timer_A)== TIMER_A)

HWREG (ui32Base + TIMER_O_TAV)&= 0x00000000;
}
if (((ui32Timer & timer_B)== TIMER_B)

HWREG (ui32Base + TIMER_O_TBV)&= 0x00000000;
}
}

下面是用于基准的计时器设置代码:

SysCtlPeripheralEnable (SYSCTL_PERIPH_TIMER2);
TimerConfigure (TIMER2_BASE、
(TIMER_CFG_SPLIT_PAIR | TIMER_CFG_A_CAP_TIME_UP | TIMER_CFG_B_CAP_TIME_UP);
TimerControlEvent (TIMER2_BASE、TIMER_A、TIMER_EVENT_POS_EDGE);
TimerControlEvent (TIMER2_BASE、TIMER_B、TIMER_EVENT_NEG_EDGE);
TimerPrescaleSet (TIMER2_BASE、TIMER_BOTH、0xFF);
TimerLoadSet (TIMER2_BASE、TIMER_BOTH、0xFFFF);
TimerEnable (TIMER2_BASE、TIMER_BOTH)

我还尝试了在归零时禁用和启用计时器、但这也不起作用。  

希望在这方面提供任何帮助。

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

    您好!

       我现在要研究这个问题。

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

    您好!

     我无法重现您的问题。 我尝试将0x1234、0x5678和0xABCD 写入 TAV 寄存器、并且我可以看到 TAR 寄存器更新为相同的值。 请参见下文。  

    下面是我在 TivaWare 示例中使用的修改后的代码。 如果我在循环中不断写入不同的值、那么我还可以在寄存器窗口中看到 TAV 变化。

    int
    main(void)
    {
        //
        // Run from the PLL at 120 MHz.
        // Note: SYSCTL_CFG_VCO_240 is a new setting provided in TivaWare 2.2.x and
        // later to better reflect the actual VCO speed due to SYSCTL#22.
        //
        g_ui32SysClock = MAP_SysCtlClockFreqSet((SYSCTL_XTAL_25MHZ |
                                                 SYSCTL_OSC_MAIN |
                                                 SYSCTL_USE_PLL |
                                                 SYSCTL_CFG_VCO_240), 120000000);
    
        //
        // Enable the peripherals used by this example.
        //
        MAP_SysCtlPeripheralEnable(SYSCTL_PERIPH_TIMER0);
        MAP_SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOL);
    
        //
        // Configure the GPIO to be CCP pins for the Timer peripheral.
        //
        MAP_GPIOPinConfigure(GPIO_PL4_T0CCP0);
        MAP_GPIOPinConfigure(GPIO_PL5_T0CCP1);
    
        //
        // Configure the GPIO for the Timer peripheral.
        //
        MAP_GPIOPinTypeTimer(GPIO_PORTL_BASE, GPIO_PIN_4 | GPIO_PIN_5);
    
        //
        // Initialize the UART and write initial status.
        //
        ConfigureUART();
        UARTprintf("Edge Capture Example for measuring the high period of an"
                   "input signal.\n");
        UARTprintf("Input a square wave onto pins PL4 and PL5 of the "
                   "EK-TM4C1294XL.\n");
    
        //
        // Initialize Timers A yo run as periodic up-count edge capture
        // timers.  This will split the 32-bit timer into two 16-bit timers.
        //
        MAP_TimerConfigure(TIMER0_BASE, (TIMER_CFG_SPLIT_PAIR |
                TIMER_CFG_A_CAP_COUNT_UP ));
    
        //
        // To use the timer in Edge Time mode, it must be preloaded with initial
        // values.  If the prescaler is used, then it must be preloaded as well.
        // Since we want to use all 24-bits for both timers it will be loaded with
        // the maximum of 0xFFFF for the 16-bit wide split timers, and 0xFF to add
        // the additional 8-bits to the split timers with the prescaler.
        //
        MAP_TimerLoadSet(TIMER0_BASE, TIMER_BOTH, 0xFFFF);
        MAP_TimerPrescaleSet(TIMER0_BASE, TIMER_BOTH, 0xFF);
    
        //
        // Configure Timer A to trigger on a Positive Edge
        //
        MAP_TimerControlEvent(TIMER0_BASE, TIMER_A, TIMER_EVENT_POS_EDGE);
    
        //
        // Clear the interrupt status flag.  This is done to make sure the
        // interrupt flag is cleared before we enable it.
        //
        MAP_TimerIntClear(TIMER0_BASE, TIMER_CAPA_EVENT );
    
        //
        // Enable the Timer A interrupts for Capture Events.
        //
        MAP_TimerIntEnable(TIMER0_BASE, TIMER_CAPA_EVENT );
    
        //
        // Enable the interrupts for Timer A  on the processor (NVIC).
        //
        MAP_IntEnable(INT_TIMER0A);
    
        //
        // Enable processor interrupts.
        //
        MAP_IntMasterEnable();
    
        HWREG(TIMER0_BASE + TIMER_O_TAV) = 0x00001234;
        HWREG(TIMER0_BASE + TIMER_O_TAV) = 0x00005678;
        HWREG(TIMER0_BASE + TIMER_O_TAV) = 0x0000abcd;
    
    
        //
        // Enable both Timer A to begin the application.
        //
        MAP_TimerEnable(TIMER0_BASE, TIMER_A);
    
        while(1)
        {
            HWREG(TIMER0_BASE + TIMER_O_TAV) = 0x00001234;
            SysCtlDelay(10000);
            HWREG(TIMER0_BASE + TIMER_O_TAV) = 0x00005678;
            SysCtlDelay(10000);
            HWREG(TIMER0_BASE + TIMER_O_TAV) = 0x0000ABCD;
            SysCtlDelay(10000);
    
        }
    
    }

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

    这让人惊讶。 让我在最后尝试一下

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

    我试过以下代码:


    以下是日志输出、它显然表明归零从未起作用:

    我不知道我在做什么错。  

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

    我也尝试过这个:


    即使我将其设置为0、我也不会看到 TAV 和 TBV 都变为0。

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

    您是否已按原样尝试我的代码? 当我单步执行代码时、我可以清楚地看到使用来自 TAV 的值更新了 TAR。 为什么不这样做呢? 能否将您的代码与我的代码进行比较? 我不确定是否会遇到 这样的竞争情况:在向 TAV 写入一个新值的同时计数器递增到下一个值。 递增的值可能覆盖了您写入的值。 例如、当前 TAV 为1234、下一个增量值将为1235。 如果写入0、在下一个周期可能会被1235覆盖。 这只是一个想法。 为什么不在向 TAV 写入0之前尝试禁用计时器?  

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

    我在将0写入 TAV 之前尝试了禁用、但这也不起作用。 您的代码与我的代码非常相似、不同之处在于您使用的是 Timer0、我使用的是 Timer2、并且您要将值更新为随机值而不是0、因此我看不到任何特别需要尝试的地方。 竞态条件部分是的、但我想 TAV 是一个自由运行的计时器、当微控制器运行时、它应该始终递增、因此如果它覆盖了我写入的任何值、这基本上意味着计时器的复位功能不可用、但我怀疑是这种情况。 我可以尝试使用调试器逐步调试寄存器、但我猜会看到计数器寄存器没有设置为0。  

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

    您好!

     再说一次、您试过我的代码了。 我刚刚修改了代码以不断地将0写入 TAV、并且我可以在寄存器窗口中看到 TAR 等于0。  

    我甚至尝试直接在寄存器窗口中手动将 ABCD 写入 TAV 寄存器、并且我也会看到 TAR 更改为 ABCD。 为什么您不先尝试我的代码、不修改任何内容?您看到了什么?

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

    感谢 Charles 的帮助。 衷心感谢您付出巨大的努力来帮助解决这个问题。 让我尝试一下、然后回复您。