目录

01、坑的由来

02、填坑

03、修改代码验证

04、总结


本文主要来填坑,更正之前文章的错误。也进一步加深了我对SysTick定时器的理解,希望对你有帮助。

01、坑的由来

在之前的推文中《STM32延时的四种方法》介绍了使用查询定时器精确延时,使用的就是systick定时器,具体代码如下

void delay_us(uint32_t nus)
{uint32_t temp;SysTick->LOAD = RCC_Clocks.HCLK_Frequency/1000000/8*nus;SysTick->VAL=0X00;//清空计数器SysTick->CTRL=0X01;//使能,减到零是无动作,采用外部时钟源do{temp=SysTick->CTRL;//读取当前倒计数值}while((temp&0x01)&&(!(temp&(1<<16))));//等待时间到达SysTick->CTRL=0x00; //关闭计数器SysTick->VAL =0X00; //清空计数器
}
void delay_ms(uint16_t nms)
{uint32_t temp;SysTick->LOAD = RCC_Clocks.HCLK_Frequency/1000/8*nms;SysTick->VAL=0X00;//清空计数器SysTick->CTRL=0X01;//使能,减到零是无动作,采用外部时钟源do{temp=SysTick->CTRL;//读取当前倒计数值}while((temp&0x01)&&(!(temp&(1<<16))));//等待时间到达SysTick->CTRL=0x00; //关闭计数器SysTick->VAL =0X00; //清空计数器
}

对于《STM32延时的四种方法》文中所说的内容如下

也就是下面代码中/8的原因。

SysTick->LOAD = RCC_Clocks.HCLK_Frequency/1000/8*nms;

我对此深信不疑,并在STM32F207参考手册(RM0033)上找到“证据”。

上图①处直接是8分频,而不像②出的1/2/4/8分频。所以我确信是SYSTICK的时钟固定为HCLK时钟的1/8。

我在学习RTThread的时候,看到配置SysTick定制器代码如下

我心里一堆问号,STM32官方手册,明明写了SYSTICK的时钟固定为HCLK时钟的1/8。我使用示波器测量,RTThread的配置是没有问题,可以正常延时的。

02、填坑

这个坑其实很简单,在《STM32延时的四种方法》也提到了,只是自己没有注意这个细节

位2置1,表示时钟频率为AHB,也就是默认的120000000Hz。

位2清0,表示时钟频率为AHB/8,也就是120000000/8Hz。

RTThread配置为内部时钟

之前的文章配置为外部时钟源

这个细节我没有留意,导致我看RTThread代码时有点懵逼。在这里我更正《STM32延时的四种方法》中的错误描述

准确的描述是:

SYSTICK的时钟可以为HCLK时钟的1分频或8分频,在这里我们选用外部时钟源120M,所以SYSTICK的时钟为(120/8)M。

特此更正。

关于这点,STM32的标准外设库提供的SysTick_Config函数,也是使用内部时钟的

/** \brief  System Tick ConfigurationThis function initialises the system tick timer and its interrupt and start the system tick timer.Counter is in free running mode to generate periodical interrupts.\param [in]  ticks  Number of ticks between two interrupts\return          0  Function succeeded\return          1  Function failed*/
static __INLINE uint32_t SysTick_Config(uint32_t ticks)
{if (ticks > SysTick_LOAD_RELOAD_Msk)  return (1);            /* Reload value impossible */SysTick->LOAD  = (ticks & SysTick_LOAD_RELOAD_Msk) - 1;      /* set reload register */NVIC_SetPriority (SysTick_IRQn, (1<<__NVIC_PRIO_BITS) - 1);  /* set Priority for Cortex-M0 System Interrupts */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 */
}

调用方法,产生1ms中断调用方法

SysTick_Config(SystemCoreClock / 1000);

关于时钟源的选择,除了操作寄存器外,还有库函数可以选择。

/*** @brief  Configures the SysTick clock source.* @param  SysTick_CLKSource: specifies the SysTick clock source.*   This parameter can be one of the following values:*     @arg SysTick_CLKSource_HCLK_Div8: AHB clock divided by 8 selected as SysTick clock source.*     @arg SysTick_CLKSource_HCLK: AHB clock selected as SysTick clock source.* @retval None*/
void SysTick_CLKSourceConfig(uint32_t SysTick_CLKSource)
{/* Check the parameters */assert_param(IS_SYSTICK_CLK_SOURCE(SysTick_CLKSource));if (SysTick_CLKSource == SysTick_CLKSource_HCLK){SysTick->CTRL |= SysTick_CLKSource_HCLK;}else{SysTick->CTRL &= SysTick_CLKSource_HCLK_Div8;}
}

除上外,我找到了其他证据来说明,SYSTICK的时钟可以为HCLK时钟的1分频或8分频。

在STM32CubeMx配置软件中,可以选择1分频或8分频。

03、修改代码验证

把《STM32延时的四种方法》文中涉及的代码修改成1分频的。

void delay_ms(uint16_t nms)
{uint32_t temp;SysTick->LOAD = RCC_Clocks.HCLK_Frequency/1000*nms-1;SysTick->VAL=0X00;//清空计数器SysTick->CTRL=0X01;SysTick_CLKSourceConfig(SysTick_CLKSource_HCLK);do{temp=SysTick->CTRL;//读取当前倒计数值}while((temp&0x01)&&(!(temp&(1<<16))));//等待时间到达SysTick->CTRL=0x00; //关闭计数器SysTick->VAL =0X00; //清空计数器
}

然后调用

GPIO_SetBits(GPIOE,GPIO_Pin_4);  //熄灭LED灯
delay_ms(500);//延时500ms
GPIO_ResetBits(GPIOE,GPIO_Pin_4);//点亮LED灯
delay_ms(500);//延时500ms

就踩到另一个坑,延时不准。

原因是:此时SYSTICK时钟频率是120MHz的24位的倒计数定时器,也就是说一个周期,最多定时139.810125ms。不能延时500ms。

这里再更正之前的一个错误,如下图

这个计数器的值,我们减去了1,这样才更准确。需要减1的具体原因在定时器讲解的文章中讲解过了,不明白的同学请看《STM32基础定时器讲解》。

04、总结

总结:STM32官方手册并不一定是准确的,要亲自做实验,自己动手验证。这是个老生常谈的问题,大家都知道,关键还在于实践

点击查看本文所在的专辑,STM32F207教程

关注公众号,第一时间收到文章更新

填坑-关于SysTick定时器相关推荐

  1. 填坑 ---- arcgis api for javascript 加载天地图

    写在前面 首先要感谢 arcgis api for javascript 加载天地图 这篇文章,帮助我完成了在网页中加载天地图. 在此就不再描述加载天地图的方法与过程,只记录我遇到的一个坑与填坑方法. ...

  2. 微信小程序填坑 视频篇

    写了一年小程序,每天接受数万付费用户的考验,踩过小程序的坑数不胜数.先写一下视频篇,写一些会影响到用户正常看视频功能和影响业务主体流程的坑. 1.一些低端设备无法播放高清视频 1080p 需要接入转码 ...

  3. 【填坑】ESP32 bootloader初探(下)

    前言 我由于做软件业务的需要,在这几年开发经历中,发现一个现象:各家芯片厂商boot开放的资料较少,不支持或少量支持定制化功能.可能也是需求少吧,毕竟对基线的改动需要的工作量也不小.但这也导致各家芯片 ...

  4. [单片机][at32][填坑日记] [USB卡包] usb快速发包导致卡包

    文章目录 一.问题现象 1. 发送频率过快,导致pc或mcu未能及时应答每一包,造成缓存区遗留上一次数据. 2. usb频发拔插枚举,导致pc/mcu数据丢失, ①mcu丢失数据,每次发送都只能发送上 ...

  5. 微信小程序填坑篇 2

    微信小程序开发的时候,很多接口都不太能信任,需要作一些额外的兜底处理.保证程序在什么情况下都能尽可能健康的运行. 也要有一套健全的异常收集反馈机制,方便迅速发现问题解决问题. 小程序生态的异常监控体系 ...

  6. 【填坑】ESP32 bootloader初探(上)

    前言 大名鼎鼎的乐鑫ESP8266 WIFI模组你应该不陌生,不用我多说了.在这之后乐鑫还更迭了更多高性能的芯片型号,比如这次我要记录的ESP32-C3,搭载近期很火的RISC-V指令集处理器,支持2 ...

  7. java.lang.OutOfMemoryError:GC overhead limit exceeded填坑心得

    该文章出自:http://www.cnblogs.com/hucn/p/3572384.html 分析工具:http://www.blogjava.net/jjshcc/archive/2014/03 ...

  8. 20150726 填坑日记

    三中内填坑: 1. 组合数递推什么的 C(m,n)=C(m,n-1)+C(m-1,n-1).填了个大坑,以前没认真听课QAQ 2. 裸题过河卒 3. 缺角正方形摆放车统计,分上下部分,枚举上部分放几个 ...

  9. 传统行业转型微服务的挖坑与填坑

    原文:传统行业转型微服务的挖坑与填坑 一.微服务落地是一个复杂问题,牵扯到IT架构,应用架构,组织架构多个方面 在多家传统行业的企业走访和落地了微服务之后,发现落地微服务是一个非常复杂的问题,甚至都不 ...

最新文章

  1. Redis知识点汇总
  2. rails 3 使用 cucumber 和rspec 進行 測試
  3. NodeJS API简介
  4. bgp选路原则【第二部】
  5. VR可以用做除游戏外的哪些地方
  6. 关于Android中Animation的停止
  7. python递归查询并列出目录
  8. 【ZJOI2018】历史【结论】【LCT思想】
  9. Java IO: RandomAccessFile
  10. ACM竞赛常用STL(二)之STL--algorithm
  11. 《Linux内核分析》期末总结及学习心得
  12. npm发布vue组件
  13. tomcat中多个域名配置
  14. 超简单的Springboot中的日志管理配置
  15. 会话(状态)管理Cookie与Session(一)
  16. vb怎么调用oracle数据库连接,VB 连接Oracle数据库
  17. CRM——销售与客户
  18. docker进阶(1):使用cAdvisor监控容器
  19. 微信小程序添加激励式广告
  20. kotlin android 开源,Kotlin开源项目集合

热门文章

  1. 电大计算机网络技术基础,电大--2016年电大 计算机与网络技术基础小抄已排版.doc...
  2. c++设置一个二维字符组初值_C语言 | 统计一段话中的字符
  3. 解决Appium连接报错Could not find ‘apksigner.jar‘
  4. pandas to_sql保存数据到数据库后,添加自增长的主键ID(PRIMARY KEY)
  5. mysql创建数据库时使用sql/wordbench使主键(primary key)自增
  6. 浪潮服务器开启远程管理,浪潮服务器远程管理
  7. 关于c语言循环的格式,关于for循环的格式
  8. php反序列化总结与学习
  9. 【XLL 框架库函数】 Excel/Excel12f
  10. codeblocks 调试