STM32基础系列包含了三件套,掌握了这三件套,类似于掌握了程咬金三板斧,就可以开始干项目,创造价值了。毕竟,真正的编程是一项实战性很强的技术,掌握编程主要靠实战,而不是靠知识灌输。

STM32的编程三件套就是:

  1. GPIO初始化;
  2. TIM定时器(含中断),也可以用SYSTICK替代;
  3. USART串口;

前面详细讲了第一板斧,如何初始化GPIO,顺道讲了如何跟着ST学编程,如何降低代码之间的耦合性。

详细可以复习一下下面:

(24条消息) 每节课都是一个项目 手把手用STM32打造联网气象站-3-STM32基础三件套-掌握GPIO初始化_可志嵌入式的博客-CSDN博客

本节讲解第二板斧,如何使用TIM定时器,如何采用TIM定时器实现精准定时。

1. 定时器的意义

我们先考虑一个问题:如果我们需要精确的设置LED点亮100S,那么应该怎么做呢?

在没有操作系统的代码中,程序执行一般分为双循环模式:

  • while大循环
  • 定时器中断

大循环中,设置cnt为100,然后点亮LED,并不断检查定时器实际是否到达。在中断处理中,每隔1S,检查cnt大于0时,将cnt自减。

当cnt自减到0时,LED将熄灭。这样就实现了准确的100S延时。

那么另外有一个问题:为何不直接用delay函数来实现呢?例如:

LEDON;
delay(100);
LEDOFF;

上面的方法虽然简单,但是在执行delay(100)这个语句时,MCU是阻塞的,并不响应任何输入,因此,长时间的delay在真实项目中,是不能使用的!真实项目中,需要采用非阻塞的方式进行,才能避免代码执行中被卡死。

2. 定时器的初始化

在理解定时器初始化之前,我们先回忆一下GPIO初始化部分:定义一个结构体,初始化时钟,定义结构体参数并传递到GPIO_Init函数中。具体参见下面链接。

每节课都是一个项目 手把手用STM32打造联网气象站-3-STM32基础三件套-掌握GPIO初始化_可志嵌入式的博客-CSDN博客

TIM定时器的初始化非常类似,也是这样步骤:定义一个TIM结构体,初始化TIM时钟,设定参数并传递到TIM_Init函数中。这些步骤是一模一样的。

但是定时器初始化还会多几个步骤 :清楚中断标志位,开启定时器中断,使能定时器。

同样的,对于定时器初始化的过程,我们了解这些步骤即可,真正移植过程中,将主要查看.h文件,并且修改宏定义,实现代码移植和调用。

2.1定时器初始化步骤

第一步:定义结构体变量;

第二步:开启定时器时钟;

第三步:设定定时器参数,并且调用Init函数写入参数;

第四步:请中断标志;

第五步:开启中断;

第六步:使能定时器;

本教程中,会把STM32F1的六路定时器都单独进行初始化和中断定时,方便后续在不同项目总,根据管脚配置和项目配置,启动对应项目。

2.2定时器计算方式

定时器的计算取决于Period和Prescaler两个参数。STM32主频为72MHz (比1996年486的速度还快),72/(Prescaler+1) =72/(71+1) 1MHz,也就是对应这1us,1us*Period=1us*1000=1ms。因此这里1ms触发一次中断。如果需要10MS触发一次中断,我们只需要把Period修改为10000即可。

3.中断的初始化

定时器的基本功能是按照固定时间计时,并且达到时间后,触发中断。因此,使用定时器就一定要初始化中断。定时器内部仅仅计时而已,中断函数内,才会真的处理对应问题。

中断初始化和GPIO初始化,TIM初始化都非常类似,也是三部曲:

第一步:定义结构体变量;

第二步:有点特殊,需要设定中断分组,这里放到下面详细讲解;

第三步:设定结构体参数,并调用Init函数,写入参数;

当我们反复熟悉掌握这些三部曲之后,就会发现其实STM32的各个初始化都非常类似。

3.1中断分组设置

Cortex M3内核支持256个中断,其中包括16个内核中断和240个外部中断,且具有256级的可编程中断设置,而STM32只用了其中一部分。

STM32有84个中断,包括16个内核中断和68个可屏蔽中断,具有16级可编程中断优先级。而我所使用的103系列只有60个可屏蔽中断。我们把这60个可屏蔽中断列一下:

这么多的中断,如果没有一个好的管理方式进行管理,会乱成一团。所以STM32中,采用中断分组的方法。

它把中断分成了5组,分别对应了NVIC_PriorityGroup0~NVIC_PriorityGroup5。

对于第0组,有0位抢占优先级,4位响应优先级,也就是总共有16个响应优先级;

第1组,1位抢占,3位响应,也就是2个抢占,8个响应优先级;

第2组,2位抢占,2位响应,也就是4个抢占,4个响应;

第3组,3位抢占,1位响应,也就是8个抢占,2个响应;

第4组,4位抢占,1位响应,也就是16个抢占,1个响应;

这里解释一下抢占优先级和响应优先级,两个都是翻译过来的,听起来有些别扭。按照通俗的说法,抢占优先级和响应优先级,两者对应关系可以看下图。抢占>响应。

上图是分组2的情况,这时会有4级抢占,4级响应。如果uart1中断位抢占2,响应1, tim2中断为抢占1,响应4,那么tim2中断的优先级更高,它可以屏蔽uart1的中断。也就是优先级更高的中断在办事的时候,优先级低的中断,是不能打断它的。而优先级低的中断在办事的时候,则可以被优先级高的中断打断。

这里需要注意:高抢占优先级可以打断低抢占优先级的中断,从而实现中断嵌套。若两个中断的抢占优先级相同,不可发生嵌套,其中响应优先级高的先执行,若两中断无论是抢占优先级还是响应优先级数值都相等,中断控制器将根据中断向量表中的位置来觉得执行顺序

 3.2中断初始化

中断初始化步骤和其他初始化步骤相比较,没啥明显区别。步骤类似,内容不同。关于中断优先级的初始化步骤,还是需要专门理解一下的。因为实际项目中,往往会遇到多个中断的情况。

第一步:创建结构体变量;

第二步:设置优先级分组,也就是前面所说的分组0~分组4之间,选一个分组。这里选择了分组0;

第三步:设置参数:我们需要设定中断源,这里通道为TIM6_IRQ;需要设置抢占优先级,这里只有一个选择,就是0;需要设置响应优先级,这里可以设置0~15,我们选择了3;然后使能中断;

第四步:将配置的参数带入函数中;

// 中断优先级配置
static void BASIC_TIM_NVIC_Config(void)
{NVIC_InitTypeDef NVIC_InitStructure; // 设置中断组为0NVIC_PriorityGroupConfig(NVIC_PriorityGroup_0);     // 设置中断来源NVIC_InitStructure.NVIC_IRQChannel = BASIC_TIM_IRQ ;  // 设置主优先级为 0NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;   // 设置抢占优先级为3NVIC_InitStructure.NVIC_IRQChannelSubPriority = 3;    NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;NVIC_Init(&NVIC_InitStructure);
}

对于中断优先级配置,我们需要掌握下面几点:

1. 这里只用了一个中断,我们把中断分组设置放到了定时器初始化函数中;如果用到多个中断,则需要把中断分组设置单独拎出来了;

2. 每隔中断,需要指定中断源,设置抢占优先级,设置响应优先级;

  3.3定时器初始化

最后完成定时器初始化即可。

 3.4中断处理函数

完成了上面的配置后,我们的代码就会乖乖地每隔1ms,进一次中断。

进了中断之后,在中断向量表中,指定了中断源和中断处理函数的关系。也就是中断处理函数的名字是定死的,不能随意修改。

比如在MDK的startup_stm32f10x_hd.s中,就明确指定了TIM6中断处理函数为TIM6_IRQHandler。

中断处理函数中,主要做了3 件事情:

1. 检查对应中断标志位是否已经被设定了;

2. 倒计时直到0;

3. 清除标志位;

4.实现0.5HZ的LED闪烁

完成了前面几个步骤后,我们已经完成了定时器的初始化和中断处理函数,使得每隔1ms就会进一次中断。但是这样还不能实现LED定时闪烁,我们只实现了前面双循环的右边。

我们还需不断把cnt设置为一个较大的数值。

这里不断把time设置为1000。每当time在定时器中,被自减到0时,就会在主循环中被设置为1000。如此不断循环,即可实现0.5HZ led闪烁。

而且整个过程中,没有用到一句delay,全部代码流畅运行,没有任何阻塞。

5.代码的移植注意事项

要移植,看头文件。如果我们需要把这里的定时器函数tim.c和tim.h移植到别的工程中,我们只需要看tim.h文件中实施的定义即可。

如果需要修改定时器中断间隔,我们修改Prescaler和Period即可;

如果需要修改点灯的频率,修改HALF_PERIOD这个宏定义即可;

6.SysTick定时器的使用

这是一个24位的系统节拍定时器system tick timer,SysTick,具有自动重载和溢出中断功能,所有基于Cortex_M3处理器的微控制器都可以由这个定时器获得一定的时间间隔。

6.1 SysTick初始化

SysTick_Init()函数调用Core_cm3中的SysTick_Config,进行Systick的配置。函数入参为SystemCoreClock,也就是72M,然后再除以1000,对应的是72000这个数字,这个数字为Systick的滴答时钟。由于Systick时钟为1/72M , 间隔时间为72000/72000000=1000,单位为us,因此systick间隔时间为1ms。如果需要加快间隔时间,比如,变为100us,则需要把1000修改为10000,这样心跳间隔就会变为100us。

6.2 SysTick产生1us延时

Delay_us的工作原理是:

1.start从SysTick->VAL中获取当前的滴答计数器的数值,也就是开始延时时的值。这个VAL会不断自减,自减的时间间隔就是systickConfig中配置的时间。

2. reload则读取LOAD中的数值,这个数值就是初始化SystickConfig中设定的数值。us_tick设定的则是常量72。

3. 在do while循环中,将从VAL中读取当前值,然后再delta中进行计算,如果start>now,说明没有还没有被减到0,这时delta=start-now, 如果start<now,说明已经减到0,并且重新加上了reload了,那delta=start-now+reload.

4.最后如果delta<us_tick*us,说明时间间隔还没有达到,则继续等待下去。

例如:如果一开始val为500, 也就是start是500,now读出来为200,比start小,说明delta为500-200。如果now读出来是1500,比start大,则说明已经减到0并重新加载relad值72000,这个时候就需要将delta计算为72000+500-1500,这个时间才是间隔时间。

用这种方法延时时间最大不超出1ms,也就是一个reload对应的时间。

6.3 SysTickHandler中断延时

延时时间到了之后,会自动调用SysTick_Handler中。

这个SysTick Handler在启动函数hd.s中定义,我们的中断函数只要名字相同就行了。中断处理函数中,每隔20ms检查一次按键处理函数。

以上就是Systick的用法。

纸上得来终觉浅,绝知此事要躬行!

马上下载测试代码,看看效果。

测试代码链接

https://download.csdn.net/download/book_drabit/85914311

并且试着修改一下LED闪烁频率,观察一下效果。

接下来会一步一步带你完成家庭气象站的开发工作,敬请收藏关注,以免下次找不到了。

每节课都是一个项目 手把手用STM32打造联网气象站-4-STM32基础三件套-TIM定时器和SYSTICK初始化相关推荐

  1. 每节课都是一个项目 手把手用STM32打造联网气象站-10-带有屏幕显示的番茄时钟

    目录 1.课程回顾 2. 升级你的番茄时钟 2.1项目需求-带有屏幕显示的番茄钟 2.2 需求分析 2.2.1 屏幕上方用中文字体显示:番茄时钟: 2.2.2 中文下方,带有时间倒计时显示: 2.2. ...

  2. 每节课都是一个项目 手把手用STM32打造联网气象站-7-诚不欺我,用TIM, GPIO, USART三板斧干项目(挖坑篇)

    终于,我们把STM32的入门三板斧的武功讲完了.有了这三板斧,我们就可以完成一些基本的项目了.终于熬出头了,从这一节开始,我们就用这三板斧,来玩不同的项目了. 当然.我们的项目不仅仅是玩,每一个项目都 ...

  3. 设计Course类:处理课程信息,每门课都有一个名字以及选课的学生,要能够向/从这个课程添加/删除一个学生

    public class Course {private String coureName;//课程名private String[] students = new String[5];//一个储存该 ...

  4. 一个项目三个坑,我懵了

    我常常在想,一个人具备怎样的素质和能力,才称得上高级工程师?估计不少人会说,"基础过硬.熟练掌握一门编程语言.至少看过一个优秀开源项目源码.有过高并发工作经验.沟通能力强". 这些 ...

  5. 视频教程-图形图像-Adobe PhotoshopCS6超速入门,一节课学会PS [实用技能]-其他

    图形图像-Adobe PhotoshopCS6超速入门,一节课学会PS [实用技能] 全栈工程师,曾担任多家互联网公司技术总监.运营经理,在技术与运营方面积累了大量实战经验,同时也是清华大学出版社特约 ...

  6. 一节计算机课作文500,难忘的一节课作文500字4篇

    上过那么多课,有没有哪节课是你觉得最难忘的,下面是关于难忘的一节课的作文,欢迎大家参阅! 难忘的一节课作文500字1 去年的一天早晨,我正在被窝里看漫画,只听见老妈对我说:"今天去学作文!& ...

  7. 图形图像-Adobe PhotoshopCS6超速入门,一节课学会PS [实用技能]-韦语洋(Lccee)-专题视频课程...

    图形图像-Adobe PhotoshopCS6超速入门,一节课学会PS [实用技能]-44130人已学习 课程介绍         该视频为"Photoshop CS6视频教程"C ...

  8. 2019年vipkid最新评价,vipkid多少钱一节课

    最近关于vipkid少儿英语的评价不少,也有不少关于vipkid费用的问题,早前我在地铁上,看到这家vipkid铺天盖地的广告,感觉还做的很到位的,现在给孩子学习英语容易多了,只要报名线上的机构,也可 ...

  9. Tomcat快速入门(Tomcat安装 把一个项目发布到tomcat中 Eclipse配置Tomcat idea配置tomcat)

    文章目录 服务器的概念 服务器 Web服务器软件:接收客户端发送的请求和响应客户端请求. 常见的Web服务器软件 Tomcat安装 win下启动乱码问题解决 Tomcat目录介绍 如何把一个项目发布到 ...

最新文章

  1. 哈尔滨商业大学计算机与信息工程学院地址,计算机与信息工程学院
  2. eclipse中output folder和deployment assembly用法有什么不同?
  3. Easyui入门视频教程 第01集---认识Easyui
  4. NYOJ 23 取石子(一)
  5. Android---Activity 生命周期(三)Stopping Activity Restarting Activity
  6. C小项目——电子词典
  7. 运行时修改Standard shader的Mode
  8. Wide-Baseline Image Matching Using Line Signatures
  9. r语言岭回归参数选择_78-预测分析-R语言实现-岭回归与LASSO回归
  10. 面面俱到,这 23 个公共数据集赶紧Mark起来!
  11. 如果估算IT的测试Pattern数
  12. python数字图像处理(2):图像的读取、显示与保存
  13. MyCat分片规则之固定hash分片
  14. c语言中药品管理系统报告,C语言 药品管理系统.doc
  15. android x5全屏白色,x5webview 自定义全屏界面(示例代码)
  16. Python入门习题(64)——OpenJudge百练习题:最长单词
  17. linux上删除rime方案_Linux中Rime输入法安装使用小结
  18. Eureka 没凉,别过度悲伤
  19. 多语言适配分享会演讲稿
  20. 有助于睡眠的15首歌曲,听着最容易入睡的歌曲推荐

热门文章

  1. Shiro 生成秘钥
  2. 用devc++表白_【理工大表白墙】19级倪yl,风吹起如花般破碎的流年,而你的笑容摇晃摇晃,成为我命途中最美的点缀...
  3. Excel2016图片缩放后不清晰
  4. CentOS7下载与图文安装
  5. java php nodejs python旅游网站设计与开发需求分析Springboot SpringcloudVue汇总一览
  6. edge浏览器ie模式设置方法介绍
  7. 计算机房灭火器单具基准,灭火器计算题这6个步骤吃透了,此考点的分数也不会丢了...
  8. 四年级计算机考试反思,考试反思四年级作文
  9. 回复整理 080307
  10. Asp.Net MVC学习记录之“一个实体对象不能由多个 IEntityChangeTracker 实例引用”