系统时钟滴答实验很不难,我就在面简单说下,但其中涉及到了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中断入门)的更多相关文章

  1. stm32学习笔记之SysTick的思考

    原文来自--SevenZ的笔记.http://blog.21ic.com/user1/8247/archives/2011/85920.html ? 首先我们要明白什么是SysTick定时器? Sys ...

  2. STM32学习笔记(一)时钟和定时器

    由于近期在准备海洋航行器比赛,正好趁此机会学习一下ARM,看到周围很多同学都在使用32,所以我也买了一块STM32F103ZET6,准备好好地学习一下. STM32的时钟系统相当的复杂,包含了5个时钟 ...

  3. STM32学习笔记(九) 外部中断,待机模式和事件唤醒

    学会知识只需要不段的积累和提高,但是如何将知识系统的讲解出来就需要深入的认知和系统的了解.外部中断和事件学习难度并不高,不过涉及到STM32的电源控制部分,还是值得认真了解的,在本文中我将以实际代码为 ...

  4. java之jvm学习笔记六-十二(实践写自己的安全管理器)(jar包的代码认证和签名) (实践对jar包的代码签名) (策略文件)(策略和保护域) (访问控制器) (访问控制器的栈校验机制) (jvm基本结构)

    java之jvm学习笔记六(实践写自己的安全管理器) 安全管理器SecurityManager里设计的内容实在是非常的庞大,它的核心方法就是checkPerssiom这个方法里又调用 AccessCo ...

  5. STM32学习笔记(四)——串口控制LED(中断方式)

    目录: 一.时钟使能,包括GPIO的时钟和串口的时钟使能 二.设置引脚复用映射 三.GPIO的初始化配置,注意要设置为复用模式 四.串口参数初始化配置 五.中断分组和中断优先级配置 六.设置串口中断类 ...

  6. STM32学习笔记——OLED屏

    STM32学习笔记--OLED屏 OLED屏的特点: 1.  模块有单色和双色可选,单色为纯蓝色,双色为黄蓝双色(本人选用双色): 2.  显示尺寸为0.96寸 3.  分辨率为128*64 4.   ...

  7. STM32学习笔记——点亮LED

    STM32学习笔记——点亮LED 本人学习STM32是直接通过操作stm32的寄存器,使用的开发板是野火ISO-V2版本: 先简单的介绍一下stm32的GPIO: stm32的GPIO有多种模式: 1 ...

  8. stm32学习笔记----双串口同时打开时的printf()问题

    stm32学习笔记----双串口同时打开时的printf()问题 最近因为要使用串口2外接PN532芯片实现通信,另一方面,要使用串口1来将一些提示信息输出到上位机,于是重定义了printf(),使其 ...

  9. stm32学习笔记——外部中断的使用

    stm32学习笔记——外部中断的使用 基本概念 stm32中,每一个GPIO都可以触发一个外部中断,但是,GPIO的中断是以组为一个单位的,同组间的外部中断同一时间只能使用一个.比如说,PA0,PB0 ...

随机推荐

  1. Git的常用操作

    $ git log //查看commit记录 $ git add <file> //添加文件到commit中 .代表所有改动的文件 $ git commit -m 'meesage' // ...

  2. Geolocation

    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/ ...

  3. Maven-008-Nexus 私服部署发布报错 Failed to deploy artifacts: Failed to transfer file: ... Return code is: 4XX, ReasonPhrase: ... 解决方案

    我在部署构件至 maven nexus 私服时,有时会出现 Failed to deploy artifacts: Failed to transfer file: ... Return code i ...

  4. Python基础、collections补充

    collections collections是Python数据类型的补充,可以实现Counter计数.可命名元组(namedtuple).默认字典.有序字典.双向队列等功能 参考:http://py ...

  5. CentOS 配置网络yum源

    配置网络yum源(需要保证外网开通,使用网易163提供开源镜像站) 1.下载repo文件 方法一:下载到本地windows再上传到linux服务器上: 下载地址 : http://mirrors.16 ...

  6. spark的安装

    官方安装地址:http://spark.apache.org/docs/latest/spark-standalone.html 准备 1.三台机器(m2.m3.m4) 2.m2位master, m3 ...

  7. docker images之间相互通信 link

    同一个host上的两个container 首先启动一个nginx. container起名叫netease_nginx docker run --detach --name netease_nginx ...

  8. MSSQL 2012 拒绝了对对象 'extended_properties' (数据库 'mssqlsystemresource',架构 'sys')的 SELECT 权限

    查看数据库的表的时候报如下错误: MSSQL 拒绝了对对象 ) 解决方法: 在数据库里相应的用户权限中,把db_denydatareader的复选框的勾去掉.db_denydatareader是拒绝访 ...

  9. Java Servlet(四):Servlet接口service工作(ServletRequest,ServletResponse对象)(jdk7+tomcat7+eclipse)

    本篇将会记录,Servlet接收客户端传递来的参数信息,并返回信息使用的对象,及这些对象的函数相关用法. 还是在java ee工程中进行操作,在WebContent目录下创建一个login.jsp文件 ...

  10. 20145320 《Java程序设计》第5周学习总结

    20145320 <Java程序设计>第5周学习总结 教材学习内容总结 8.1 语法与继承架构 try.catch Java中的错误会被包装为对象,而使用try与catch,JVM会执行t ...