STM32学习笔记(六) SysTick系统时钟滴答实验(stm32中断入门)
系统时钟滴答实验很不难,我就在面简单说下,但其中涉及到了STM32最复杂也是以后用途最广的外设-NVIC,如果说RCC是实时性所必须考虑的部分,那么NVIC就是stm32功能性实现的基础,NVIC的难度并不高,但是理解起来还是比较复杂的,我会在本文中从实际应用出发去说明,当然最好去仔细研读宋岩翻译的<Cortex-M3权威指南>第八章,注意这不是一本教你如何编写STM32代码的工具书,而是阐述Cortex-M3内核原理的参考书,十分值得阅读。
SysTick系统时钟的核心有两个,外设初始化和Systick_Handle()中断处理函数。
Systick配置:
static void SysTick_UserConfig(void)
{
SysTick->CTRL &= 0xfffffffb; //采用内核外部时钟,即SYSTICK
SysTick->LOAD = 0x8000; //重装值寄存器,VAL内数值为0时重装
SysTick->VAL = 0x00; //SysTick当前值寄存器 清零
SysTick->CTRL = 0x03; //SysTick定时器使能,中断使能
}
NVIC配置:
void NVIC_UserConfig(void)
{
NVIC_SetVectorTable(NVIC_VectTab_FLASH,0x0); //将指针指向flash中的中断向量表
}
中断函数:
void SysTick_Handler(void)
{
static uint32_t LED_Flag = ;
if(LED_Flag < )
{
LED_1_ON();
}
if(LED_Flag >= )
{
LED_1_OFF();
}
LED_Flag++;
if(LED_Flag == )
{
LED_Flag = ;
}
}
如此,就完成了简单的SysTick滴答实验,代码请参考:http://files.cnblogs.com/files/zc110747/4.SysTick.7z
看到这是不是就结束了,不过记得当时我写完这个程序,疑问有以下几点:
1.向量表是如何定义的,重定位的操作有什么作用
2.为什么中断函数名一定要是void SysTick_Handler(void),怎么确定的
3.中断打乱了正常的程序流程,cpu怎么知道回到之前运行的位置
4.中断优先级如何配置和理解
如何解决这些问题,这都需要从原理方面来解决了,了解过IAP和uC/os-ii的对这些问题应该有一定认知,下面我就系统的讲解下我的想法:
1~2问题. 当 CM3 内核响应了一个发生的异常后,对应的异常服务例程(ESR)就会执行。为了决定 ESR 的入口地址,这就是所谓的“向量表查表机制”。向量表其实是一个 WORD( 32 位整数)数组,每个下标对应一种异常,该下标元素的值则是该 ESR 的入口地址。如果细心查看startup_stm32f10x_cl.s,就会发现下面语句:
; Vector Table Mapped to Address at Reset
AREA RESET, DATA, READONLY
EXPORT __Vectors
EXPORT __Vectors_End
EXPORT __Vectors_Size __Vectors DCD __initial_sp ; Top of Stack
DCD Reset_Handler ; Reset Handler
DCD NMI_Handler ; NMI Handler
DCD HardFault_Handler ; Hard Fault Handler
DCD MemManage_Handler ; MPU Fault Handler
DCD BusFault_Handler ; Bus Fault Handler
DCD UsageFault_Handler ; Usage Fault Handler
DCD ; Reserved
DCD ; Reserved
DCD ; Reserved
DCD ; Reserved
DCD SVC_Handler ; SVCall Handler
DCD DebugMon_Handler ; Debug Monitor Handler
DCD ; Reserved
DCD PendSV_Handler ; PendSV Handler
DCD SysTick_Handler ; SysTick Handler ; External Interrupts
DCD WWDG_IRQHandler ; Window Watchdog
......
DCD OTG_FS_IRQHandler ; USB OTG FS
__Vectors_End __Vectors_Size EQU __Vectors_End - __Vectors AREA |.text|, CODE, READONLY
其中_Vectors既是所提到的WORD数组,这就是定义的向量表,如果了解过指向函数的指针,那么就可以知道,DCD的每一项就是定义的中断服务例程,这样我们就知道为什么Systick中断的中断服务例程是SysTick_Handler,当然根据实际情况这个向量表只要和主函数代码保持一致就可以实现中断的查询,例如uC/os-ii移植中修改PendSV_Handler。
看到这解决了第二个问题,那么第一个问题,从上面可以看出来,向量表一直位于代码的最顶端,也就是偏移量0x0的位置,为什么有时还需要重定位呢?如果看过IAP那篇,了解了启动机制后,应该明白上电后系统会默认跳转0x00000000(flash地址0x08000000映射),然后读取向量表偏移寄存器,查询向量表,因为此时向量表的偏移量就是0x0,向量表就不需要重定义。而在IAP模式下,应用代码的起始地址并不是flash首地址,而是由偏移量0x8000(假定值),从上面也可以简单推出应用代码的向量表偏移量也是0x8000,此时向量表偏移寄存器就需要重定义了。
下图来自于list下生成的.map文件
再参考生成的bin文件和启动文件:
可以很清晰证实上面的观点。
3.了解M3芯片基础的应该知道,M3拥有通用寄存器组R0~R15,这些寄存器在程序运行中保存着代码流程的所有信息,包括当前地址,正在修改的变量参数。因此在中断触发时,只要将R0~R15依次压栈,中断结束后出栈,代码就会回到运行之前的位置(uC/OS-ii正是模拟该过程实现任务切换的),当然这只是最简单的一种情况,因为m3芯片本身支持中断优先级和中断嵌套,实际复杂度远高于此.其实可以简化为如下流程:
主程序暂停 -〉相关位置和状态参数入栈-〉中断服务例程执行-〉相关位置和状态参数出栈-〉主程序恢复
4. Cortex-M3支持最多240个可配置中断,中断优先级的数目3~8位,也就是支持8~256个优先级,而事实上一般并没有支持那么多,如8,16,32级,其中最多支持128个抢占级。arm中断及复位控制寄存器中的3~8位设定优先级的部分,通过配置可将其分割为两部分,前面为抢占级,后面为亚优先级,并且亚优先级至少为1位,分组是可以从保留的优先级组开始的。一个中断的优先级可通过以下顺序判断,优先级依此降低。
优先级组:抢占级 > 亚优先级
优先级: 数值小 > 数值大
中断号: 中断号小 > 中断号大
抢占级和亚优先级的区别:
抢占级是在发生在中断嵌套的基础,上面提到了中断打断了线程的流程,但是如果有抢占级的加入,中断本身也会被优先级更高的中断打断,具体流程如下:
主程序暂停 -〉低优先级中断 -〉高优先级中断-〉低优先级中断-〉主程序恢复
亚优先级表示没有发生中断的嵌套,一个中断只有在它结束后另一个亚优先级的中断才会响应,即不会发生中断嵌套。
此外为了加快中断执行的流程,Cortex-M3提供了基于优先级的四种动作:
1.占先: 主要发生在抢占级中,即高优先级中断低优先级执行,发生中断嵌套
2.末尾连锁: 若占先发生上一个中断的末尾出栈之前,则打断出栈动作,直接执行高优先级中断,结束后如果没有发生抢占,才执行出栈
3.迟来 若占先发生在中断的开始入栈阶段,则继续入栈,低优先级中断挂起。
4.返回 出栈过程,如果收到高优先级中断则停止并产生末尾连锁
从上面可以看出,中断优先级和中断嵌套在加上ARM基于优先级机制的优化,可以让中断中高优先级任务更快执行,正是优先级设定的意义。
STM32学习笔记(六) SysTick系统时钟滴答实验(stm32中断入门)的更多相关文章
- stm32学习笔记之SysTick的思考
原文来自--SevenZ的笔记.http://blog.21ic.com/user1/8247/archives/2011/85920.html ? 首先我们要明白什么是SysTick定时器? Sys ...
- STM32学习笔记(一)时钟和定时器
由于近期在准备海洋航行器比赛,正好趁此机会学习一下ARM,看到周围很多同学都在使用32,所以我也买了一块STM32F103ZET6,准备好好地学习一下. STM32的时钟系统相当的复杂,包含了5个时钟 ...
- STM32学习笔记(九) 外部中断,待机模式和事件唤醒
学会知识只需要不段的积累和提高,但是如何将知识系统的讲解出来就需要深入的认知和系统的了解.外部中断和事件学习难度并不高,不过涉及到STM32的电源控制部分,还是值得认真了解的,在本文中我将以实际代码为 ...
- java之jvm学习笔记六-十二(实践写自己的安全管理器)(jar包的代码认证和签名) (实践对jar包的代码签名) (策略文件)(策略和保护域) (访问控制器) (访问控制器的栈校验机制) (jvm基本结构)
java之jvm学习笔记六(实践写自己的安全管理器) 安全管理器SecurityManager里设计的内容实在是非常的庞大,它的核心方法就是checkPerssiom这个方法里又调用 AccessCo ...
- STM32学习笔记(四)——串口控制LED(中断方式)
目录: 一.时钟使能,包括GPIO的时钟和串口的时钟使能 二.设置引脚复用映射 三.GPIO的初始化配置,注意要设置为复用模式 四.串口参数初始化配置 五.中断分组和中断优先级配置 六.设置串口中断类 ...
- STM32学习笔记——OLED屏
STM32学习笔记--OLED屏 OLED屏的特点: 1. 模块有单色和双色可选,单色为纯蓝色,双色为黄蓝双色(本人选用双色): 2. 显示尺寸为0.96寸 3. 分辨率为128*64 4. ...
- STM32学习笔记——点亮LED
STM32学习笔记——点亮LED 本人学习STM32是直接通过操作stm32的寄存器,使用的开发板是野火ISO-V2版本: 先简单的介绍一下stm32的GPIO: stm32的GPIO有多种模式: 1 ...
- stm32学习笔记----双串口同时打开时的printf()问题
stm32学习笔记----双串口同时打开时的printf()问题 最近因为要使用串口2外接PN532芯片实现通信,另一方面,要使用串口1来将一些提示信息输出到上位机,于是重定义了printf(),使其 ...
- stm32学习笔记——外部中断的使用
stm32学习笔记——外部中断的使用 基本概念 stm32中,每一个GPIO都可以触发一个外部中断,但是,GPIO的中断是以组为一个单位的,同组间的外部中断同一时间只能使用一个.比如说,PA0,PB0 ...
随机推荐
- iOS仿网易新闻栏目拖动重排添加删除效果
仿网易新闻栏目选择页面的基本效果,今天抽了点时间教大家如何实现UICollectionView拖动的效果! 其实实现起来并不复杂,这里只是基本的功能,没有实现细节上的修改,连UI都是丑丑的样子,随手画 ...
- C语言 ---- 数组 iOS学习-----细碎知识点总结
#pragma mark - 数组:用来存放同一数据类型的数据 // 数组的定义:类型说明符 数组名[常量表达式] = {值1, 值2, 值3...}; // 定义一个float类型的数组,用来 ...
- Metro 页面间跳转报错、打包和安装一个本地的Metro类型应用
1.模板页面间传值跳转报错误 参照:http://www.cnblogs.com/dagehaoshuang/archive/2012/08/31/2665166.html#2862480 强烈推荐, ...
- mongoDB(1)
1.查询时,不写条件的查询,速度要远远大于有条件的查询. 2.消除重复数据: 3.db.listCommands() 查看mongo的runCommand支持哪些功能了. db.runCommand( ...
- jQuery源代码学习之四——jQuery.callbacks
自己实现的callbacks模块相较于jquery源代码中的callbacks模块有所简化,表面上看没有考虑firing这个参数,没有对之进行任何处理,即没有考虑在函数执行过程中,再次调用add,re ...
- 九步轻松实现SVN创建管理项目
本节向大家描述一下在Windows上使用Subversion中如何使用SVN创建管理项目,在这里和大家分享一下,欢迎大家一起来学习在 使用SVN创建管理项目的方法.首先看一下SVN介绍. Subver ...
- @Autowired获取被@Service注解的bean为null的问题
先说结论:Spring容器还没有加载完Bean,你就去调用了! 一般的注解没加,bean的名字写错都好检查,但是逻辑错误就需要看清自己的思维过程了. 实例:在使用ActiveMq的过程中,第一步对Ac ...
- 解决 No resource found that matches the given name (at 'icon' with value '@drawable/icon') 问题
对新解决方案Xamarin的Android项目在项目属性 换图标后 会出现 No resource found that matches the given name (at 'icon' with ...
- 【转】ACM/ICPC生涯总结暨退役宣言—alpc55
转自:http://hi.baidu.com/accplaystation/item/ca4c2ec565fa0b7fced4f811 ACM/ICPC生涯总结暨退役宣言—alpc55 前言 早就该写 ...
- HDU 1258 Sum It Up
Sum It Up Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others)Total S ...