STM32_Systick学习及例程改写

涉及的参考来自:野火的《【野火®】零死角玩转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 );
	} 

猜你喜欢

转载自blog.csdn.net/yhb1206/article/details/82356532