SysTick定时器,也叫滴答定时器或者系统定时器。
SysTick-系统定时器是属于CM3内核中的一个外设,内嵌在NVIC中。系统定时器是一个24位的向下递减的计数器,计数器每计数一次的时间为1/SYSCLK,一般我们设置系统时钟SYSCLK等于72MHz。当重装载数值寄存器的值递减到0的时候,系统定时器就产生一次中断,以此循环往复。
因为SysTick是属于CM3内核的外设,所以所有基于CM3内核的单片机都具有这个系统定时器,这是的软件在CM3单片机中可以很容易被移植。系统定时器一般用于操作系统,用于产生时基,维持操作系统的心跳。
- Systick定时器是一个比较简单的定时器,常用于延时或者计时,也可以用作实时系统的心跳时钟。节省通用定时器的资源。
- 只要不把Systick定时器关闭,它就会循环往复计时,在睡眠模式下也能工作。
- Systick中断的优先级也可以设置。
4个Systick寄存器
SysTick库函数
SysTick中断服务函数
void SysTick_Handler(void);
库函数中SysTick的定义以及其寄存器对应地址的映射如下:
1. //systick寄存器对应的映射地址,包装在一个结构体中 2. 3. typedef struct 4. { 5. __IO uint32_t CTRL; /*!< Offset: 0x00 SysTick Control and Status Register */ 6. __IO uint32_t LOAD; /*!< Offset: 0x04 SysTick Reload Value Register */ 7. __IO uint32_t VAL; /*!< Offset: 0x08 SysTick Current Value Register */ 8. __I uint32_t CALIB; /*!< Offset: 0x0C SysTick Calibration Register */ 9. } SysTick_Type;
Delay延时函数
相比于51单片机直接生成的延时函数,STM32的延时函数就比较复杂了,但是可以直接cv
1. #include "stm32f10x.h" 2. #include "Delay.h" 3. 4. 5. static uint8_t us = 0; 6. static uint16_t ms = 0; 7. 8. void Delay_Init(uint8_t MHz) //72MHz 9. { 10. SysTick_CLKSourceConfig(SysTick_CLKSource_HCLK_Div8); //8分频,72M/8=9M 11. us = MHz/8; //1us计数9个 12. ms = (uint16_t)us*1000; //1ms计数9000个 13. } 14. 15. /*说明 16. 2的24次方 = 3个2的8次方 = 256*256*256 = 16777216 (24位递减计数器计数个数) 17. 16777216/9000 = 1864.135 (能计时1864ms,最多计时1.864s) 18. 注意最大定时时间为1.864s 19. */ 20. 21. /** 22. * @brief 毫秒级延时 23. * @param xms 延时时长,参数最大写1864 24. * @retval 无 25. */ 26. void Delay_ms(uint32_t xms) 27. { 28. uint32_t temp; 29. SysTick ->LOAD = (uint32_t)ms*xms; //重载值 30. SysTick ->VAL = 0; 31. SysTick ->CTRL |= SysTick_CTRL_ENABLE_Msk;//软件方式开启计数器,使能 32. //开启计数器另一种写法 SysTick ->CTRL = 0x01; 33. do{ 34. temp = SysTick ->CTRL; 35. }while( (temp & 0x01) && !(temp & (1<<16)) ); //COUNTFLAG = 1,就代表计数完毕 36. //(temp & 0x01) 检查计数器是否开启 37. 38. SysTick ->VAL = 0; 39. SysTick ->CTRL &= ~SysTick_CTRL_ENABLE_Msk; 40. //关闭计数器另一种写法 SysTick ->CTRL = 0x00; 41. } 42. 43. 44. /** 45. * @brief 微秒级延时 46. * @param ums 延时时长 47. * @retval 无 48. */ 49. void Delay_us(uint32_t xus) 50. { 51. uint32_t temp; 52. SysTick ->LOAD = us*xus; 53. SysTick ->VAL = 0; 54. SysTick ->CTRL |= SysTick_CTRL_ENABLE_Msk; 55. do{ 56. temp = SysTick ->CTRL; 57. }while( (temp & 0x01) && !(temp & (1<<16)) ); 58. 59. SysTick ->VAL = 0; 60. SysTick ->CTRL &= ~SysTick_CTRL_ENABLE_Msk; 61. } 62. 63. void Delay_s(uint32_t xs) 64. { 65. while(xs--) 66. { 67. Delay_ms(1000); 68. } 69. }
在使用延时函数前,记得初始化延时函数
Delay_Init(72); //初始化延时函数
另一版本……也可以直接用
1. /** 2. * @brief 微秒级延时 3. * @param xus 延时时长,范围:0~233015 4. * @retval 无 5. */ 6. void Delay_us(uint32_t xus) 7. { 8. SysTick->LOAD = 72 * xus; //设置定时器重装值 9. SysTick->VAL = 0x00; //清空当前计数值 10. SysTick->CTRL = 0x00000005; //设置时钟源为HCLK,启动定时器 11. while(!(SysTick->CTRL & 0x00010000)); //等待计数到0 12. SysTick->CTRL = 0x00000004; //关闭定时器 13. } 14. 15. /** 16. * @brief 毫秒级延时 17. * @param xms 延时时长,范围:0~4294967295 18. * @retval 无 19. */ 20. void Delay_ms(uint32_t xms) 21. { 22. while(xms--) 23. { 24. Delay_us(1000); 25. } 26. } 27. 28. /** 29. * @brief 秒级延时 30. * @param xs 延时时长,范围:0~4294967295 31. * @retval 无 32. */ 33. void Delay_s(uint32_t xs) 34. { 35. while(xs--) 36. { 37. Delay_ms(1000); 38. } 39. }
这个就不需要初始化等,直接用即可