微波EDA网,见证研发工程师的成长!
首页 > 硬件设计 > 嵌入式设计 > SysTick系统时钟滴答实验(stm32中断入门)

SysTick系统时钟滴答实验(stm32中断入门)

时间:11-19 来源:互联网 点击:
 系统时钟滴答实验很不难,我就在面简单说下,但其中涉及到了STM32最复杂也是以后用途最广的外设-NVIC,如果说RCC是实时性所必须考虑的部分,那么NVIC就是stm32功能性实现的基础,NVIC的难度并不高,但是理解起来还是比较复杂的,我会在本文中从实际应用出发去说明,当然最好去仔细研读宋岩翻译的第八章,注意这不是一本教你如何编写STM32代码的工具书,而是阐述Cortex-M3内核原理的参考书,十分值得阅读。

 SysTick系统时钟的核心有两个,外设初始化和Systick_Handle()中断处理函数。

 Systick配置:

static void SysTick_UserConfig(void){SysTick->CTRL &= 0xfffffffb;  //采用内核外部时钟,即SYSTICKSysTick->LOAD = 0x8;       //重装值寄存器,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 = 0;if(LED_Flag < 50){LED_1_ON();}if(LED_Flag >= 50){LED_1_OFF();}LED_Flag++;if(LED_Flag == 100){LED_Flag = 0;}}

 如此,就完成了简单的SysTick滴答实验,代码请参考:http://files.cnblogs.com/files/zc110747/6.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 0 at ResetAREA    RESET, DATA, READONLYEXPORT  __VectorsEXPORT  __Vectors_EndEXPORT  __Vectors_Size__Vectors       DCD     __initial_sp               ; Top of StackDCD     Reset_Handler              ; Reset HandlerDCD     NMI_Handler                ; NMI HandlerDCD     HardFault_Handler          ; Hard Fault HandlerDCD     MemManage_Handler          ; MPU Fault HandlerDCD     BusFault_Handler           ; Bus Fault HandlerDCD     UsageFault_Handler         ; Usage Fault HandlerDCD     0                          ; ReservedDCD     0                          ; ReservedDCD     0                          ; ReservedDCD     0                          ; ReservedDCD     SVC_Handler                ; SVCall HandlerDCD     DebugMon_Handler           ; Debug Monitor HandlerDCD     0                          ; ReservedDCD     PendSV_Handler             ; PendSV HandlerDCD     SysTick_Handler            ; SysTick Handler; External InterruptsDCD     WWDG_IRQHandler            ; Window Watchdog......DCD     OTG_FS_IRQHandler          ; USB OTG FS__Vectors_End__Vectors_Size  EQU  __Vectors_End - __VectorsAREA    .text, CODE, READONLY

其中_Vectors既是所提到的WORD数组,这就是定义的向量表,如果了解过指向函数的指针,那么就可以知道,DCD的每一项就是定义的中断服务例程,这样我们就知道为什么Systick中断的中断服务例程是SysTick_Handler,当然根据实际情况这个向量表只要和主函数代码保持一致就可以实现中断的查询,例如uC/os-ii移植中修改PendSV_Handler。

看到这解决了第二个问题,那么第一个问题,从上面可以看出来,向量表一直位于代码的最顶端,也就是偏移量0x0的位置,为什么有时还需要重定位呢?如果看过IAP那篇,了解了启动机制后,应该明白上电后系统会默认跳转0x00(flash地址0x08映射),然后读取向量表偏移寄存器,查询向量表,因为此时向量表的偏移量就是0x0,向量表就不需要重

Copyright © 2017-2020 微波EDA网 版权所有

网站地图

Top