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:复位或设置 SysTick 重新处理计数器

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

https://e2e.ti.com/support/microcontrollers/arm-based-microcontrollers-group/arm-based-microcontrollers/f/arm-based-microcontrollers-forum/1418652/tm4c123gh6pm-resetting-or-setting-systick-remaning-counter

器件型号:TM4C123GH6PM

工具与软件:

您好!

我让 SysTick 以800000/1024的周期运行、以每秒获取1024个周期、而我的 SysTickIntHandler 会:

Fullscreen
1
2
3
4
void SysTickIntHandler(void) {
g_ui32SysTickCount++;
if(g_ui32SysTickCount % 1024 == 0) { g_ui32PosixTime++; g_ui32SysTickCount = 0; }
}
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

因此、POSIX_TIME 为秒、系统节拍计数介于0至1023之间

我还将使用 USB 串行以纳秒的时间发送 POSIX 时间数据包、我想与微控制器同步时间。

是否可以用任何方法将 SysTick 计数器重表示法时间复位、或者更好地将其设置为给定的值?

在外设参考的第536页中、显示:

"调用此函数不会导致 SysTick 计数器立即重新加载。 则该位为1
需要重新加载、必须写入 NVIC_ST_CURRENT 寄存器。 对该寄存器的任何写入
将 SysTick 计数器清零、并导致重新加载此处提供的 ui32Period
启用 SysTick 后的下一个时钟。"

因此、我想知道是否有任何方法可以将 计时器设置为给定的值。

此致、

CAN

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

    您好 CAN、

    [quote userid="91011" url="~/support/microcontrollers/arm-based-microcontrollers-group/arm-based-microcontrollers/f/arm-based-microcontrollers-forum/1418652/tm4c123gh6pm-resetting-or-setting-systick-remaning-counter 这样我想知道是否有办法将 计时器设置为给定值。

     您已使用正确的 API。 调用 SysTickPeriodSet 会将 SysTick 计数器加载到您的指定值。 当当前值寄存器到达0时、重载值寄存器(STRELOAD)的值被装载到当前值寄存器(STCURRENT)中。 如果希望指定的值生效、可以  使用 HWREG 直接写入当前值寄存器(STCURRENT)。  

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

    嗯、我做了一个测试用例、其中:

    uint8_t SysTick_counter = SysTickValueGet ();
    HWREG (NVIC_ST_RELOAD)= dt_period - 1;
    HWREG (NVIC_ST_CURRENT)= dt_period - 1;
    uint8_t SysTick_counter2 = SysTickValueGet ();

    uint8_t len = sprintf (loginfo_buffer、"%lu\n"、Systick _counter);
    UARTprintf (loginfo_buffer、len);
    len = sprintf (loginfo_buffer、"%lu\n"、Systick_counter2);
    UARTprintf (loginfo_buffer、len);

    其中 DT_PERIOD 为800000/1024。 在串行调试端口上、我总是会得到很小的数字、如

    "

    175.

    37.

    "

    如何检查 SysTick 是否从周期开始向下计数?

    此致、

    CAN

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

    您好 CAN、

     我给了你一个错误的信息。 写入  HWREG (NVIC_ST_CURRENT)时、无论写入何种值、都将清除寄存器。 您只需注释掉 HWREG (NVIC_ST_CURRENT)= dt_period - 1。 这样、NVIC_ST_CURRENT 将由 NVIC_ST_RELOAD 中存储的值进行加载、并开始计数(假设您也启用了 STCTRL 寄存器中的 SysTick)。  

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

    您好、Charles、

    现在有点困惑。 我这么做的原因是时间同步。 我想只更改一次 SysTick 计数器的周期、仲裁时、当同步数据包到达时、解析并计算从主机计算机获得的纳秒、然后设置剩余的 SysTick 计数器、使其在0到 dt_period 之间增大或减小。

    这是否可能?

    此致、

    CAN

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

    您好 CAN、

    我举一个例子。 假设您首先将值1000加载到  STRELOAD 寄存器中。 SysTick 计数器将从1000递减到0、然后在计数器值变为0时重新加载1000。 该过程重复进行。 假设在计数的中间且当前计数器值为300、则向 STRELOAD 寄存器写入值600。 会发生什么情况?  在这种情况下、计数器(可以从 STCURRENT 寄存器中读取)在计数器变为0之前不会加载600。 计数器当前为300、在新值600生效之前、它必须再计数300个周期、直到达到0。 如果希望新值600尽快生效、首先要  用新的重新加载值写入 STRELOAD、然后再对 STCURRENT 寄存器进行一次写入。 写入 STCURRENT 将把计数器清零、然后重新加载新值。 但是、完成对这两个寄存器的写入需要一些周期。  

    定时器包含3个寄存器:
    ■SysTick 控制及状态(STCTRL):一个用于配置其时钟的控制及状态计数器
    使能计数器、使能 SysTick 中断、并确定计数器状态。
    ■SysTick 重载值(STRELOAD):该计数器的重载值用于提供
    计数器的折返值。
    ■SysTick 当前值(STCURRENT):计数器的当前值。
    使能后、定时器将在每个时钟递减计数、从重载值逐个递减到0、重新装载(绕回)
    寄存器中的值保存到下一个时钟边沿上、然后在下一个时钟边沿上递减
    时钟。 如果将 STRELOAD 寄存器清零、则会在下次重载时禁用计数器。 配置一个寄存器
    达到零时、计数状态位被置位。 读取 COUNT 标志位后其自动清零。
    对 STCURRENT 寄存器进行写操作、即可将此寄存器清零、同时还将清零 COUNT 标志位。 写入操作
    不触发 SysTick 异常逻辑。 读取时、当前值是处的寄存器值
    寄存器被访问的时间

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

    在这个例子中、我把600写入 STRELOAD、然后写入 STCURRENT、那么下一个周期也将从600开始?

    我需要它来改变倒计时值、但下次它从原始 period_value 开始。

    我们写入 STCURRENT 的值是否重要、或者只是写入任何内容来复位计数器是否重要。

    此致、

    CAN

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    [报价 userid="91011" url="~/support/microcontrollers/arm-based-microcontrollers-group/arm-based-microcontrollers/f/arm-based-microcontrollers-forum/1418652/tm4c123gh6pm-resetting-or-setting-systick-remaning-counter/5438562 #5438562"]

    在这个例子中、我把600写入 STRELOAD、然后写入 STCURRENT、那么下一个周期也将从600开始?

    [报价]

    在通过向 STCURRENT 写入任意值来清零 STCURRENT 后、将重新加载新的 RELOAD 值600。

    [报价 userid="91011" url="~/support/microcontrollers/arm-based-microcontrollers-group/arm-based-microcontrollers/f/arm-based-microcontrollers-forum/1418652/tm4c123gh6pm-resetting-or-setting-systick-remaning-counter/5438562 #5438562"]

    我需要它来改变倒计时值、但下次它从原始 period_value 开始。

    [报价]

    我不清楚。 您希望它以600或1000重新加载? 600是新的重新加载值、1000是原始值。 在这里、您想从原始 period_set 开始。 我想您的意思是新的 reload 值600。  

    [报价 userid="91011" url="~/support/microcontrollers/arm-based-microcontrollers-group/arm-based-microcontrollers/f/arm-based-microcontrollers-forum/1418652/tm4c123gh6pm-resetting-or-setting-systick-remaning-counter/5438562 #5438562"]

    我们写入 STCURRENT 的值是否重要、或者只是写入任何内容来复位计数器是否重要。

    [报价]

    正确、向 STCURRENT 写入任何值都将复位计数器。  

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

    好的、原始周期是78125、即80M 的1/1024。

    例如、我想将计数器设置为专有值、让它从这种专有值开始倒计数、当它达到0时、下一个计数器值应该是原始周期78125。

    我可能:

    HWREG (NVIC_ST_RELOAD)= dt_period - p_st_current;

    HWREG (NVIC_ST_CURRENT)= 0x1;

    HWREG (NVIC_ST_RELOAD)= dt_period;

    这样就需要装载所需的值、通过写入 STCURRENT 将计数器设置为0、然后将 RELOAD 值设置为原始值。 我想知道这是否起作用、因为您说它需要几个时钟周期。

    或者、我可以使用 SysTickIntHandler 来查看计数器值是否已被修改、如果是、请将其设置为 Original、但任何一种情况都有倒数。

    此致、

    CAN

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

    我一直在试验、出现了一个问题。

    当 I:

    //将 SysTick 计数器重载为 value

    HWREG (NVIC_ST_RELOAD)=新周期;

    HWREG (NVIC_ST_CURRENT)= 0x01;

    这是否会立即触发 SysTick 中断? 它会导致计数器复位、但这次复位也会触发 SysTick 中断、如果是、我们如何解决该问题?

    此致、

    CAN

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    [报价 userid="91011" url="~/support/microcontrollers/arm-based-microcontrollers-group/arm-based-microcontrollers/f/arm-based-microcontrollers-forum/1418652/tm4c123gh6pm-resetting-or-setting-systick-remaning-counter/5439902 #5439902"]

    //将 SysTick 计数器重载为 value

    HWREG (NVIC_ST_RELOAD)=新周期;

    HWREG (NVIC_ST_CURRENT)= 0x01;

    这是否会立即触发 SysTick 中断? 它会导致计数器复位、但这次复位也会触发 SysTick 中断、如果是、我们如何解决该问题?

    [报价]

    向 NVIC_ST_CURRENT 写入任何值都会使计数器复位为零。 如果已启用、计数器中的零也会触发中断。 我可以想到两种方法。 首先、写入  NVIC_ST_CURRENT 以重置计数器、然后在 ISR 中、将新值加载到 NVIC_ST_RELOAD 中。 第二种方法是保留上述代码、但在写入 NVIC_ST_CURRENT 之前禁用中断。