SysTick系统时钟滴答实验(stm32中断入门)
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,向量表就不需要重
SysTick系统时钟滴答实验stm32中断入 相关文章:
- Windows CE 进程、线程和内存管理(11-09)
- RedHatLinux新手入门教程(5)(11-12)
- uClinux介绍(11-09)
- openwebmailV1.60安装教学(11-12)
- Linux嵌入式系统开发平台选型探讨(11-09)
- Windows CE 进程、线程和内存管理(二)(11-09)