你的浏览器版本过低,可能导致网站不能正常访问!
为了你能正常使用网站功能,请使用这些浏览器。

基于STM32F4库开发实战指南——读书笔记(一)SysTick

[复制链接]
数码小叶 发布时间:2018-12-7 09:54
本帖最后由 数码小叶 于 2018-12-19 10:22 编辑

第一眼拿到这本书,真的是把我惊到了,这么厚的一本干货
微信图片_20181203210544.jpg

微信图片_20181203210554.jpg
比一般的书厚两倍都不止。打开发现一共有45个章节,一下看完肯定是不可能的。先按照当初申请时写的那样,一周一个章节,完成4个章节的学习。
第一周就是学习第17章,SysTick——系统定时器。SysTick在平时作为一个节拍时钟还是很常用到的。SysTick是一个24位的递减计数器,每计一个数的时间是1/SYSCLK,直到减到0,产生一个中断。相比于普通定时器,它的优势在哪呢,那就是便于移植性,因为他是内核中的一个外设,内嵌在NVIC中。像常见的FreeRTOS就是利用SysTick产生时基。
首先,读完了书上关于SysTick的基本介绍内容,然后结合实际例程去学习,因为电脑上基本都是HAL库,但是实际一点也不影响整个学习,书本上这一章节对相关的寄存器都做了很详细的介绍。首先入口是
  1. void SystemClock_Config(void);
复制代码
这是整个的时钟系统设置,在这个函数里面可以找到关于SysTick的配置部分,如下
  1. HAL_SYSTICK_Config(HAL_RCC_GetHCLKFreq()/1000);
  2. HAL_SYSTICK_CLKSourceConfig(SYSTICK_CLKSOURCE_HCLK);
复制代码
第二个可以不用去细看,就是配置时钟来源,这个F4的时钟树一看就明白了,重点是第一个函数,这个函数位于stm32f1xx_hal_cortex.c里,
  1. uint32_t HAL_SYSTICK_Config(uint32_t TicksNumb)
  2. {
  3.    return SysTick_Config(TicksNumb);
  4. }
复制代码


这个看不出,还得继续,就到了core_cm3.h里的SysTick_Config
  1. __STATIC_INLINE uint32_t SysTick_Config(uint32_t ticks)
  2. {
  3.   if ((ticks - 1UL) > SysTick_LOAD_RELOAD_Msk)
  4.   {
  5.     return (1UL);
  6.   }

  7.   SysTick->LOAD  = (uint32_t)(ticks - 1UL);
  8.   NVIC_SetPriority (SysTick_IRQn, (1UL << __NVIC_PRIO_BITS) - 1UL);
  9.   SysTick->VAL   = 0UL;
  10.   SysTick->CTRL  = SysTick_CTRL_CLKSOURCE_Msk |
  11.                    SysTick_CTRL_TICKINT_Msk   |
  12.                    SysTick_CTRL_ENABLE_Msk;
  13.   return (0UL);
  14. }
复制代码
这里面都是些很实质的东西了。
首先判断给定的参数是否超出最大值,没有就把计数值赋给重装载寄存器。然后设置中断优先级。__NVIC_PRIO_BITS 值为4,即左移4位,因为STM32 的中断使用了 4 位作为优先级,而且是用的高4位,低4位不用。结果是15,即最低优先级。然后就是赋计数初值0了。最后是配置SysTick的控制及状态寄存器:选择时钟源、使能定时器中断、使能定时器。至此,SysTick就配合完成了。再来看SysTick的一个实际用法,就是HAL_Delay()函数:
  1. __weak void HAL_Delay(uint32_t Delay)
  2. {
  3.   uint32_t tickstart = HAL_GetTick();
  4.   uint32_t wait = Delay;

  5.   if (wait < HAL_MAX_DELAY)
  6.   {
  7.     wait += (uint32_t)(uwTickFreq);
  8.   }

  9.   while ((HAL_GetTick() - tickstart) < wait)
  10.   {
  11.   }
  12. }
复制代码
__weak 意味着我们可以重新定义,一但重新定义,这个函数就将失去意义。这里面只有一个HAL_GetTick()函数
  1. __weak uint32_t HAL_GetTick(void)
  2. {
  3.   return uwTick;
  4. }
复制代码


粗看貌似和SysTick没啥关系,所以得继续往里看,注意到uwTick这个变量,应该是变化的,但是这个值在哪改变的呢,keil可以定位到下面这个函数
  1. __weak void HAL_IncTick(void)
  2. {
  3.   uwTick += uwTickFreq;
  4. }
复制代码
继续往下,还得找出在哪调用的
  1. void SysTick_Handler(void)
  2. {
  3.   HAL_IncTick();
  4.   HAL_SYSTICK_IRQHandler();
  5. }
复制代码
到这就可以看出来了,在SysTick的中断服务程序里调用的。至此就豁然开朗了,配置好SysTick后,在SysTick中断服务程序里改变延时函数的值,达到定时的目的。那么,还剩下最后一个问题,就是时间到底是多少?就追到了最初的一个配置:
  1. HAL_SYSTICK_Config(HAL_RCC_GetHCLKFreq()/1000);
复制代码
这里的HAL_RCC_GetHCLKFreq()可以获取系统运行频率,假设这里F4跑到180MHz,那这里设置的计数值就是180MHz/1000;SysTick将重载值减到0后触发中断,因此定时时间为(180MHz/1000)*(1/180MHz),后者为计数一次的时间,可以算出来,最后的时间就是1ms。同理,可以设置为HAL_RCC_GetHCLKFreq()/1000000就是1us。

评分

参与人数 1 ST金币 +20 收起 理由
STMCU + 20

查看全部评分

收藏 评论1 发布时间:2018-12-7 09:54

举报

1个回答
ldptest 回答时间:2018-12-7 11:11:26
呵呵,这是字典。

所属标签

STM32团队

意法半导体微控制器和微处理器拥有广泛的产品线,包含低成本的8位单片机和基于ARM® Cortex®-M0、M0+、M3、M4、M33、M7及A7内核并具备丰富外设选择的32位微控制器及微处理器


最新内容

相似分享

关于
我们是谁
投资者关系
意法半导体可持续发展举措
创新与技术
意法半导体官网
联系我们
联系ST分支机构
寻找销售人员和分销渠道
社区
媒体中心
活动与培训
隐私策略
隐私策略
Cookies管理
行使您的权利
官方最新发布
STM32N6 AI生态系统
STM32MCU,MPU高性能GUI
ST ACEPACK电源模块
意法半导体生物传感器
STM32Cube扩展软件包
关注我们
st-img 微信公众号
st-img 手机版