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.
工具与软件:
您好!
我让 SysTick 以800000/1024的周期运行、以每秒获取1024个周期、而我的 SysTickIntHandler 会:
void SysTickIntHandler(void) { g_ui32SysTickCount++; if(g_ui32SysTickCount % 1024 == 0) { g_ui32PosixTime++; g_ui32SysTickCount = 0; } }
因此、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
在这个例子中、我把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
//将 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 之前禁用中断。