First, the system timer
SysTick called a system clock tick, the system timer , belonging to a peripheral Cortex-M4 kernel , it 24bit down counter decrements
Second, the system timer interrupt usage
1. initialization code
// initialize the system timer, 1S kernel interrupt trigger 1000, the timing of that white 1ms SysTick_Config (SystemCoreClock / 1000 );
2. write interrupt service function
void SysTick_Handler ( void ) { static uint32_t CNT = 0 ; CNT ++ ; // arrival timing 500ms of IF (CNT> = 500 ) { CNT = 0 ; PFout ( . 9 ) = ^ . 1 ; } }
3. The timer time calculated
SysTick_Config(SystemCoreClock/频率);
Let the system timer trigger one second break if you can? If not, the largest of regular time then what is?
You can not trigger one second interruption.
At the rated frequency, the maximum timing time = 2 ^ 24/168 000 000 ≈ 99.86ms
Overclocking frequency ( at 216MHz), the maximum timing time = 2 ^ 24 / 216000000≈ 77.67ms
Test Results:
// initialize the system timer, 1S kernel interrupt trigger 1000, plainly timed 1ms, can successfully // SysTick_Config (SystemCoreClock / 1000); // initialize the system timer, 1S kernel interrupt trigger 10 times, plainly timed 100ms, the phenomenon failure SysTick_Config (SystemCoreClock / 10 ); // initialize the system timer, 1S kernel interrupt trigger 11 times, plainly timed 90.90ms, can successfully SysTick_Config (SystemCoreClock / 11 );
Third, the system timer uses
Two aspects:
No operating system: only for delay
有操作系统(ucos2 ucos3 freertos....):为操作系统提供精准的定时中断(1ms~50ms)
四、使用系统定时器用于延时的用途
If you want to use the SysTick timer in polling mode, you can use the count flag in the SysTick Control and
Status Register (SysTick->CTRL) to determine when the timer reaches zero.
For example, you can create a timed delay by setting the SysTick timer to a certain value and waiting until it reaches zero:
SysTick->CTRL = 0; // Disable SysTick SysTick->LOAD = 0xFF; // Count from 255 to 0 (256 cycles) SysTick->VAL = 0; // Clear current value as well as count flag SysTick->CTRL = 5; // Enable SysTick timer with processor clock while ((SysTick->CTRL & 0x00010000)==0);// Wait until count flag is set SysTick->CTRL = 0; // Disable SysTick
1. 配置系统定时器的时钟源
/** * @brief Configures the SysTick clock source. * @param SysTick_CLKSource: specifies the SysTick clock source. * This parameter can be one of the following values: * @arg SysTick_CLKSource_HCLK_Div8: AHB clock divided by 8 selected as SysTick clock source. * @arg SysTick_CLKSource_HCLK: AHB clock selected as SysTick clock source. * @retval None */ void SysTick_CLKSourceConfig(uint32_t SysTick_CLKSource) { /* Check the parameters */ assert_param(IS_SYSTICK_CLK_SOURCE(SysTick_CLKSource)); if (SysTick_CLKSource == SysTick_CLKSource_HCLK) { SysTick->CTRL |= SysTick_CLKSource_HCLK; } else { SysTick->CTRL &= SysTick_CLKSource_HCLK_Div8; } }
2,系统定时器寄存器
1. 当SysTick使用168MHz系统时钟频率时,代码编写如下:
void delay_us(uint32_t nus) { SysTick->CTRL = 0; // Disable SysTick SysTick->LOAD = (SystemCoreClock/1000000)*nus; // 计数值 SysTick->VAL = 0; // Clear current value as well as count flag SysTick->CTRL = 5; // Enable SysTick timer with processor clock while ((SysTick->CTRL & 0x00010000)==0);// Wait until count flag is set SysTick->CTRL = 0; // Disable SysTick } void delay_ms(uint32_t nms) { SysTick->CTRL = 0; // Disable SysTick SysTick->LOAD = (SystemCoreClock/1000)*nms; // 计数值 SysTick->VAL = 0; // Clear current value as well as count flag SysTick->CTRL = 5; // Enable SysTick timer with processor clock while ((SysTick->CTRL & 0x00010000)==0);// Wait until count flag is set SysTick->CTRL = 0; // Disable SysTick } 最大的延时为99.86ms
2. 当SysTick使用168MHz系统时钟频率并进行8分频时,代码编写如下:
void delay_us(uint32_t nus) { SysTick->CTRL = 0; // Disable SysTick SysTick->LOAD = (SystemCoreClock/8/1000000)*nus; // 计数值 SysTick->VAL = 0; // Clear current value as well as count flag SysTick->CTRL = 1; // Enable SysTick timer with processor clock while ((SysTick->CTRL & 0x00010000)==0);// Wait until count flag is set SysTick->CTRL = 0; // Disable SysTick } void delay_ms(uint32_t nms) { SysTick->CTRL = 0; // Disable SysTick SysTick->LOAD = (SystemCoreClock/8/1000)*nms; // 计数值 SysTick->VAL = 0; // Clear current value as well as count flag SysTick->CTRL = 1; // Enable SysTick timer with processor clock while ((SysTick->CTRL & 0x00010000)==0);// Wait until count flag is set SysTick->CTRL = 0; // Disable SysTick } 思考题,当前最大的延时时间是多少?如何优化代码,支持秒级别或更长时间的延时? 最大的延时时间 = 2^24 / 21000000 ≈ 798.91ms void delay_ms(uint32_t nms) { uint32_t m,n; m = nms/500; n = nms %500; //m个500ms的延时 while(m--) { SysTick->CTRL = 0; // Disable SysTick SysTick->LOAD = (SystemCoreClock/8/1000)*500; // 计数值 SysTick->VAL = 0; // Clear current value as well as count flag SysTick->CTRL = 1; // Enable SysTick timer with processor clock,当使用21MHz的时候,1;当使用168MHz的时候,5; while ((SysTick->CTRL & 0x00010000)==0);// Wait until count flag is set SysTick->CTRL = 0; // Disable SysTick } //不足500ms的延时 if(n) { SysTick->CTRL = 0; // Disable SysTick SysTick->LOAD = (SystemCoreClock/8/1000)*n; // 计数值 SysTick->VAL = 0; // Clear current value as well as count flag SysTick->CTRL = 1; // Enable SysTick timer with processor clock,当使用21MHz的时候,1;当使用168MHz的时候,5; while ((SysTick->CTRL & 0x00010000)==0);// Wait until count flag is set SysTick->CTRL = 0; // Disable SysTick } }