填坑-关于SysTick定时器
目录
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定时器相关推荐
- 填坑 ---- arcgis api for javascript 加载天地图
写在前面 首先要感谢 arcgis api for javascript 加载天地图 这篇文章,帮助我完成了在网页中加载天地图. 在此就不再描述加载天地图的方法与过程,只记录我遇到的一个坑与填坑方法. ...
- 微信小程序填坑 视频篇
写了一年小程序,每天接受数万付费用户的考验,踩过小程序的坑数不胜数.先写一下视频篇,写一些会影响到用户正常看视频功能和影响业务主体流程的坑. 1.一些低端设备无法播放高清视频 1080p 需要接入转码 ...
- 【填坑】ESP32 bootloader初探(下)
前言 我由于做软件业务的需要,在这几年开发经历中,发现一个现象:各家芯片厂商boot开放的资料较少,不支持或少量支持定制化功能.可能也是需求少吧,毕竟对基线的改动需要的工作量也不小.但这也导致各家芯片 ...
- [单片机][at32][填坑日记] [USB卡包] usb快速发包导致卡包
文章目录 一.问题现象 1. 发送频率过快,导致pc或mcu未能及时应答每一包,造成缓存区遗留上一次数据. 2. usb频发拔插枚举,导致pc/mcu数据丢失, ①mcu丢失数据,每次发送都只能发送上 ...
- 微信小程序填坑篇 2
微信小程序开发的时候,很多接口都不太能信任,需要作一些额外的兜底处理.保证程序在什么情况下都能尽可能健康的运行. 也要有一套健全的异常收集反馈机制,方便迅速发现问题解决问题. 小程序生态的异常监控体系 ...
- 【填坑】ESP32 bootloader初探(上)
前言 大名鼎鼎的乐鑫ESP8266 WIFI模组你应该不陌生,不用我多说了.在这之后乐鑫还更迭了更多高性能的芯片型号,比如这次我要记录的ESP32-C3,搭载近期很火的RISC-V指令集处理器,支持2 ...
- java.lang.OutOfMemoryError:GC overhead limit exceeded填坑心得
该文章出自:http://www.cnblogs.com/hucn/p/3572384.html 分析工具:http://www.blogjava.net/jjshcc/archive/2014/03 ...
- 20150726 填坑日记
三中内填坑: 1. 组合数递推什么的 C(m,n)=C(m,n-1)+C(m-1,n-1).填了个大坑,以前没认真听课QAQ 2. 裸题过河卒 3. 缺角正方形摆放车统计,分上下部分,枚举上部分放几个 ...
- 传统行业转型微服务的挖坑与填坑
原文:传统行业转型微服务的挖坑与填坑 一.微服务落地是一个复杂问题,牵扯到IT架构,应用架构,组织架构多个方面 在多家传统行业的企业走访和落地了微服务之后,发现落地微服务是一个非常复杂的问题,甚至都不 ...
最新文章
- Redis知识点汇总
- rails 3 使用 cucumber 和rspec 進行 測試
- NodeJS API简介
- bgp选路原则【第二部】
- VR可以用做除游戏外的哪些地方
- 关于Android中Animation的停止
- python递归查询并列出目录
- 【ZJOI2018】历史【结论】【LCT思想】
- Java IO: RandomAccessFile
- ACM竞赛常用STL(二)之STL--algorithm
- 《Linux内核分析》期末总结及学习心得
- npm发布vue组件
- tomcat中多个域名配置
- 超简单的Springboot中的日志管理配置
- 会话(状态)管理Cookie与Session(一)
- vb怎么调用oracle数据库连接,VB 连接Oracle数据库
- CRM——销售与客户
- docker进阶(1):使用cAdvisor监控容器
- 微信小程序添加激励式广告
- kotlin android 开源,Kotlin开源项目集合
热门文章
- 电大计算机网络技术基础,电大--2016年电大 计算机与网络技术基础小抄已排版.doc...
- c++设置一个二维字符组初值_C语言 | 统计一段话中的字符
- 解决Appium连接报错Could not find ‘apksigner.jar‘
- pandas to_sql保存数据到数据库后,添加自增长的主键ID(PRIMARY KEY)
- mysql创建数据库时使用sql/wordbench使主键(primary key)自增
- 浪潮服务器开启远程管理,浪潮服务器远程管理
- 关于c语言循环的格式,关于for循环的格式
- php反序列化总结与学习
- 【XLL 框架库函数】 Excel/Excel12f
- codeblocks 调试