stm32-7SysTicks

来源:互联网 发布:数据库压力测试工具 编辑:程序博客网 时间:2024/06/05 09:44

stm32-7SysTicks


1.系统定时器的相关配置

首先跟踪一部分代码,下面为初始化滴答定时器的函数

    /* 配置SysTick为10ms中断一次*/    SysTick_Init();

跟踪到bsp_SysTicks.c文件中对他的定义

/**  * @brief  配置滴答定时器  * @param    * @retval   * @attention:配置中断的时间间隔,配置成功后关闭定时器  */void SysTick_Init(void){    /* 配置中断时间间隔     * SystemFrequency / 1000    1ms中断一次     * SystemFrequency / 100000  10us中断一次     * SystemFrequency / 1000000 1us中断一次     *///  if (SysTick_Config(SystemFrequency / 100000))   // ST3.0.0库版本    if (SysTick_Config(SystemCoreClock / 100000))   // ST3.5.0库版本    {         /* Capture error */         while (1);    }        // 关闭嘀嗒定时器      SysTick->CTRL &= ~ SysTick_CTRL_ENABLE_Msk;}

其中,函数SysTick_Config(SystemCoreClock / 100000) 配置中断时间间隔,配置失败返回1,跟踪到 core_cm3.h中:

/* #####################    SysTick function  ######################## */#if (!defined (__Vendor_SysTickConfig)) || (__Vendor_SysTickConfig == 0)/** * @brief  Initialize and start the SysTick counter and its interrupt. * * @param   ticks   number of ticks between two interrupts * @return  1 = failed, 0 = successful * * Initialise the system tick timer and its interrupt and start the * system tick timer / counter in free running mode to generate  * periodical interrupts. * ticks个时钟周期中断一次,中断时间=ticks*时钟周期 */static __INLINE uint32_t SysTick_Config(uint32_t ticks){   //检查输入的参数是否正确,ticks的值<=fffffff    if (ticks > SysTick_LOAD_RELOAD_Msk)  return (1);            /* Reload value impossible */    //将ticks-1的值装入RELOAD,从ticks-1减到0是ticks    SysTick->LOAD  = (ticks & SysTick_LOAD_RELOAD_Msk) - 1;      /* set reload register */    //配置系统滴答定时器中断SysTick中断的优先级    NVIC_SetPriority (SysTick_IRQn, (1<<__NVIC_PRIO_BITS) - 1);  /* set Priority for Cortex-M0 System Interrupts */    //配置相关寄存器STK_CTRL:时钟源、异常请求、使能    SysTick->VAL   = 0;                                   /* 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 (0);                                             /* Function successful */}#endif/* ###################    Reset function  ############################# */

这个内核中的函数中使用了位指示宏位屏蔽宏,先上代码,这是 core_cm3.h 中关于 SysTick 寄存器的一些定义

/* SysTick Control / Status Register Definitions */#define SysTick_CTRL_COUNTFLAG_Pos         16                                             /*!< SysTick CTRL: COUNTFLAG Position */#define SysTick_CTRL_COUNTFLAG_Msk         (1ul << SysTick_CTRL_COUNTFLAG_Pos)            /*!< SysTick CTRL: COUNTFLAG Mask */#define SysTick_CTRL_CLKSOURCE_Pos          2                                             /*!< SysTick CTRL: CLKSOURCE Position */#define SysTick_CTRL_CLKSOURCE_Msk         (1ul << SysTick_CTRL_CLKSOURCE_Pos)            /*!< SysTick CTRL: CLKSOURCE Mask */#define SysTick_CTRL_TICKINT_Pos            1                                             /*!< SysTick CTRL: TICKINT Position */#define SysTick_CTRL_TICKINT_Msk           (1ul << SysTick_CTRL_TICKINT_Pos)              /*!< SysTick CTRL: TICKINT Mask */#define SysTick_CTRL_ENABLE_Pos             0                                             /*!< SysTick CTRL: ENABLE Position */#define SysTick_CTRL_ENABLE_Msk            (1ul << SysTick_CTRL_ENABLE_Pos)               /*!< SysTick CTRL: ENABLE Mask *//* SysTick Reload Register Definitions */#define SysTick_LOAD_RELOAD_Pos             0                                             /*!< SysTick LOAD: RELOAD Position */#define SysTick_LOAD_RELOAD_Msk            (0xFFFFFFul << SysTick_LOAD_RELOAD_Pos)        /*!< SysTick LOAD: RELOAD Mask *//* SysTick Current Register Definitions */#define SysTick_VAL_CURRENT_Pos             0                                             /*!< SysTick VAL: CURRENT Position */#define SysTick_VAL_CURRENT_Msk            (0xFFFFFFul << SysTick_VAL_CURRENT_Pos)        /*!< SysTick VAL: CURRENT Mask */

其中的寄存器位指示宏:SysTick_xxx_Pos ,宏展开后即为xxx 在相应寄存器中的位置,如控制 SysTick 时钟源的 SysTick_CTRL_CLKSOURCE_Pos ,宏展开为 2,这个寄存器位正是在寄存器 STK_CTRL 中的 Bit2。

而寄存器位屏蔽宏:SysTick_xxx_Msk,宏展开是xxx 的位全部置 1 后,左移 SysTick_xxx_Pos 位。如控制 SysTick 时钟源的SysTick_CTRL_CLKSOURCE_Msk,宏展开为 (1ul << SysTick_CTRL_CLKSOURCE_Pos) ,把无符号长整型数值(ul) 1 左移 2 位,得到了一个只有 Bit2:CLKSOURCE 位被置 1,其它位为 0 的数值,这样的数值配合位操作&(按位与)、| (按位或)可以很方便地修改寄存器的某些位。假如控制 CLKSOURCE 需要四个寄存器位,这个宏就应该被改为(0xf ul << SysTick_CTRL_CLKSOURCE_Pos) ,这样就会得到一个关于 CLKSOURCE 的四位被置 1 的值,这些宏的参数就是这样被确定的。

2.利用滴答定时器实现精确延时

关于使用滴答定时器时间精确延时函数:

/**  * @brief      us延时程序,10us为一个单位»  * @param    * @arg nTime: Delay_us( counts ) 延时为 counts * 10us  * @retval     TimingDelay是全局变量  */void Delay_us(__IO u32 nTime){     TimingDelay = nTime;        //使用滴答定时器    SysTick->CTRL |=  SysTick_CTRL_ENABLE_Msk;    //直到TimingDelay减到0,延时结束    while(TimingDelay != 0);}

中断需要调用的TimingDelay自减函数

/**  * @brief  获取节拍程序   * @param    * @retval   * @attention  在 SysTick 中断函数 SysTick_Handler()调用  */void TimingDelay_Decrement(void){    if (TimingDelay != 0x00)    {         TimingDelay--;    }}

中断函数SysTick_Handler(),在stm32f10x_it.h中由用户填写,每中断一次调用一次TimingDelay_Decrement();使TimingDelay自减一次,直到TimingDelay == 0

/**  * @brief  This function handles SysTick Handler.  * @param  None  * @retval None  */void SysTick_Handler(void){    TimingDelay_Decrement();    }

注意

在一个文件里调用另外一个文件里的函数需要在该文件中用extern声明,不然会报错


End

0 0
原创粉丝点击