涉及的参考来自:野火的《【野火®】零死角玩转STM32—F103霸道》、野火例程
1.systick进中断不用清标志的,这个好奇怪,难道是因为它是内核外设?
2.第二个不同之处是它的优先级的奇怪,其优先级没有主和子优先级之说,并且STM32只保留了其高4bit有效,也就是其优先级可设范围为0~15;
直接调用NVIC_SetPriority实现
NVIC_SetPriority (SysTick_IRQn, (1<<__NVIC_PRIO_BITS) - 1); /* set Priority for Systick Interrupt */
但是虽然它没有主和子优先级之说,但是碰到其他外设时,怎么比较?还是按照优先级分组的配置来比较,也就是按照优先级分组的比例来拆分,进行比较。
3. 不管开不开其中断,其计数器值一旦递减为0,计数标志就置1,有中断进中断,无中断也没啥事,继续重载计数。
4.systick优先级设的时候是和那个NVIC的优先级分组没关系,不受NVIC怎么分组的影响,而且systick不分主和子优先级的。但是比较的时候是按NVIC的分组值比的,比的时候将其值按分组值进行拆分再比。
5.计数-1的问题,可以这么理解,比如你设置n,那么它进一次中断时n,接下来就是,n-1,n-2,……,0,实际运行了n+1,所以要-1.这样理解就行了。为啥不用递增理解?因为这个计数器是递减计数器,虽然可以用递增来理解但它没有说明它内部是+1操作的,所以我觉得如果举递增的理解方式会有误导,虽然道理一样。
6.野火例程的改写
针对其第二个在程序中检测计数器标志的延时,我是看它还是开中断,而且每次都要重新配置,我就闲累,于是改写成不开中断,配置一次,之后只是开计数器关计数器。
RCC_ClocksTypeDef RccClocks;
uint32_t SystemClockFrequency = 0, u32Cnt = 0;
RCC_GetClocksFreq(&RccClocks);
SystemClockFrequency = RccClocks.HCLK_Frequency;
u32Cnt = SystemClockFrequency/1000;
if ((u32Cnt - 1) > SysTick_LOAD_RELOAD_Msk) /* Reload value impossible */
{
/* Capture error */
while (1);
}
else
{
SysTick->LOAD = u32Cnt - 1; /* set reload register */
NVIC_SetPriority (SysTick_IRQn, (1<<__NVIC_PRIO_BITS) - 1); /* set Priority for Systick Interrupt */
SysTick->VAL = 0; /* Load the SysTick Counter Value */
SysTick->CTRL = SysTick_CTRL_CLKSOURCE_Msk;
SysTick->CTRL &= ~(SysTick_CTRL_ENABLE_Msk | SysTick_CTRL_TICKINT_Msk); /* Disable SysTick IRQ and SysTick Timer */
}
u16 i;
for(;;)
{
LED1( ON );
// 配置 counter 计数器的值
SysTick->VAL = 0;
SysTick->CTRL |= SysTick_CTRL_ENABLE_Msk; /* Enable SysTick Timer,But diable SysTick IRQ*/
for(i=0;i<1000;i++)
{
// 当计数器的值减小到0的时候,CRTL寄存器的位16会置1
// 当置1时,读取该位会清0
while( !((SysTick->CTRL)&(1<<16)) );
}
// 关闭SysTick定时器
SysTick->CTRL &=~ SysTick_CTRL_ENABLE_Msk;
// SysTick_Delay_Ms( 1000 );
LED1( OFF );
LED2( ON );
// 配置 counter 计数器的值
SysTick->VAL = 0;
SysTick->CTRL |= SysTick_CTRL_ENABLE_Msk; /* Enable SysTick Timer,But diable SysTick IRQ*/
for(i=0;i<1000;i++)
{
// 当计数器的值减小到0的时候,CRTL寄存器的位16会置1
// 当置1时,读取该位会清0
while( !((SysTick->CTRL)&(1<<16)) );
}
// 关闭SysTick定时器
// 配置 counter 计数器的值
SysTick->CTRL &=~ SysTick_CTRL_ENABLE_Msk;
// SysTick_Delay_Ms( 1000 );
LED2( OFF );
LED3( ON );
// 配置 counter 计数器的值
SysTick->VAL = 0;
SysTick->CTRL |= SysTick_CTRL_ENABLE_Msk; /* Enable SysTick Timer,But diable SysTick IRQ*/
for(i=0;i<1000;i++)
{
// 当计数器的值减小到0的时候,CRTL寄存器的位16会置1
// 当置1时,读取该位会清0
while( !((SysTick->CTRL)&(1<<16)) );
}
// 关闭SysTick定时器
SysTick->CTRL &=~ SysTick_CTRL_ENABLE_Msk;
// SysTick_Delay_Ms( 1000 );
LED3( OFF );
}