目次
1はじめに
CM4コアの処理はCM3と同じです。内部にSysTickタイマーが含まれています。SysTickは24ビットのカウントダウンタイマーです。カウントが0に達すると、RELOADレジスタからタイミング初期値が自動的にリロードされます。SysTick制御およびステータスレジスタのイネーブルビットをクリアしない限り、停止することはありません。このように、システムタイマーを占有することなく、サイスティックを使用して遅延タイミング機能を実現することができます。Systickは、freeRTOSやその他のOSなどのシステムのクロックビートとしても使用されます。スケジューラーが開始されると、systickはシステムにハートビートを提供するシステムクロックとして構成されます。systickには4つのレジスタCTRL、LOAD、VAL、CALIBがあります
2.サイスティック構成に関する注意事項
CubeMX構成を使用して生成されたコードでは、SystemClock_Config()関数が自動的に生成され、シングルチップマイクロコンピューターのクロックが構成され、systickが構成されます。
void SystemClock_Config()
{
...........
LL_SYSTICK_SetClkSource(LL_SYSTICK_CLKSOURCE_HCLK);
LL_SetSystemCoreClock(32000000);
#ifndef SYSTICK_IRQ
LL_Init1msTick(32000000); //使能systick但是不开启systick中断
#else
SysTick_Config(SystemCoreClock / 1000);//使能systick同时开启systick中断
#endif
}
ただし、ここで注意が必要なのは、systick割り込みを有効にする必要があるかどうかです。!!!
1. systickを遅延として使用するだけで、プログラムが割り込みによって中断されたくない場合は、systick割り込みを開く代わりに、systickを有効にして、LL_Init1msTickを呼び出すだけです。
void LL_Init1msTick(uint32_t HCLKFrequency)
---> LL_InitTick(HCLKFrequency, 1000U);
---> __STATIC_INLINE void LL_InitTick(uint32_t HCLKFrequency, uint32_t Ticks)
{
/* Configure the SysTick to have interrupt in 1ms time base */
SysTick->LOAD = (uint32_t)((HCLKFrequency / Ticks) - 1UL); /* set reload register */
SysTick->VAL = 0UL; /* Load the SysTick Counter Value */
SysTick->CTRL = SysTick_CTRL_CLKSOURCE_Msk |
SysTick_CTRL_ENABLE_Msk; /* Enable the Systick Timer */
}
ただし、遅延関数を自分で作成する必要があり、HALライブラリによって提供されるHAL_Delay()を使用することはできません。その理由は次のとおりです。HAL_Delayの実装はuwTickFreq変数に依存し、uwTickFreqはHAL_IncTickに蓄積され、SysTick_Handler割り込み関数で定期的に呼び出す必要があるため、HAL_Delayにベンチマークがあります。
__weak void HAL_IncTick(void)
{
uwTick += uwTickFreq;
}
__weak uint32_t HAL_GetTick(void)
{
return uwTick;
}
__weak void HAL_Delay(uint32_t Delay)
{
uint32_t tickstart = HAL_GetTick();
uint32_t wait = Delay;
/* Add a period to guaranty minimum wait */
if (wait < HAL_MAX_DELAY)
{
wait += (uint32_t)(uwTickFreq);
}
while((HAL_GetTick() - tickstart) < wait)
{
}
}
カスタム私たちの遅延
void my_delay_us(uint32_t nus)
{
uint32_t temp;
uint32_t fac_us = SystemCoreClock/1000000; //为系统时钟的1/1000000
SysTick->LOAD = nus*fac_us; //时间加载
SysTick->VAL = 0x00; //清空计数器
SysTick->CTRL |= SysTick_CTRL_ENABLE_Msk ; //开始倒数
do
{
temp = SysTick->CTRL;
}
while((temp & 0x01) &&! (temp&(1 << 16))); //等待时间到达
SysTick->CTRL &= ~ SysTick_CTRL_ENABLE_Msk; //关闭计数器
SysTick->VAL = 0X00; //清空计数器
}
2. systickシートシステムのクロックビートを使用する場合は、systick割り込みをオンにする必要があります。直接、SysTick_Configを呼び出して構成するか、HAL_Initを使用して構成すると、HAL_Init構成は最終的にSysTick_Config関数を呼び出します。
HAL_Init(void)
---> HAL_InitTick(uint32_t TickPriority)
---> SysTick_Config(uint32_t ticks)
{
if ((ticks - 1UL) > SysTick_LOAD_RELOAD_Msk)
{
return (1UL); /* Reload value impossible */
}
SysTick->LOAD = (uint32_t)(ticks - 1UL); /* set reload register */
NVIC_SetPriority (SysTick_IRQn, (1UL << __NVIC_PRIO_BITS) - 1UL); /* set Priority for Systick Interrupt */
SysTick->VAL = 0UL; /* Load the SysTick Counter Value */
SysTick->CTRL = SysTick_CTRL_CLKSOURCE_Msk |
SysTick_CTRL_TICKINT_Msk |
SysTick_CTRL_ENABLE_Msk; /* Enable SysTick IRQ and SysTick Timer */
return (0UL); /* Function successful */
}
この構成が完了した後、systickの割り込みでosSystickHandlerとHAL_IncTickを呼び出す必要があります
void SysTick_Handler(void)
{
osSystickHandler();//为OS提供系统时钟节拍
HAL_IncTick();//为HAL库提供时钟基准
}