STM32F407芯片支持82个可屏蔽中断
NVIC )嵌套矢量中断控制器,控制芯片中断相关功能。 因为ARM为NVIC提供了非常多的功能,所以使用M4内核设计芯片的公司可能不需要那么多功能。 因此,需要在NVIC中进行修剪。 ST公司的STM32F407芯片内部中断数是NVIC修整后的结果。
STM32F407芯片支持82个可屏蔽的中断信道,每个中断信道具有自己的中断优先级控制字节(8位,但在STM32F407中为4位,仅高4位有效
优先级高的中断事件会中断当前的主程序,或者中断程序的执行。 俗称插队嵌套。 抢占优先级相同时,响应优先级高的中断优先响应。
对于高4位,这两个中断不是嵌套关系。 如果一个中断到来后正在处理另一个中断,则为此3358www.Sina.com/。 如果这两个中断同时到达,中断控制器将根据响应的优先级高低确定先处理哪一个。 如果抢占优先级等于响应优先级,则首先处理哪一个取决于中断表中的优先级。
在STM32F407中指定中断优先级的寄存器位为4位,该4位的分组如下进行。
中断配置步骤:
//要使用中断,必须先设置它。 通常需要采取这个步骤。 //(1)启用某个中断至外围设备//(1)设置中断优先级组,然后单击NVIC_InitTypeDef结构typedef struct { uint8_ TN vic _ IRQ Chanel; //中断源uint8_ TN vic _ irqchannelpreemptionpriority; //优先级uint8_ TN vic _ irqchannelsubpriority; //响应优先级functionalstatenvic _ irqchannelcmd; //中断有效或无效} NVIC_InitTypeDef; //3 )编写中断服务函数EXTI的概要
STM32F4外部中断/事件控制器(EXTI )最多包含23个边缘检测器,用于生成事件/中断请求。 EXTI中的每条输入线可以单独设置为选择类型(中断或事件)和相应的触发事件(上升沿、下降沿或边缘触发器),也可以单独屏蔽。
EXTI结构框图:两个中断源的抢占式优先级相同时
STM32F4的EXTI有23条中断/事件线。后到来的中断就要等到前一个中断处理完之后才能被处理
外部中断配置步骤:
要使用外部中断,必须首先设置。 通常需要采取这个步骤。
)1)启用IO端口时钟,配置IO端口模式作为输入
)2)接通SYSCFG时钟,设置IO端口与中断线的映射关系
RCC _ AP B2 periphclockcmd (RCC _ AP B2 per iph _ sys CFG,ENABLE ); 启用SYSCFG时钟voidsyscfg _ extilineconfig (uint8_ texti _ portsourcegpiox,uint8_t EXTI_PinSourcex ); (3)配置中断包(NVIC ),使中断有效
nvic _ inittypedefnvic _ init structure; nvic _ init structure.nvic _ IRQ channel=exti0_ irqn; //EXTI0中断通道nvic _ init structure.nvic _ irqchannelpreemptionpriority=2; //抢占优先级nvic _ init structure.nvic _ irqchannelsubpriority=3; //次优先级nvic _ init structure.nvic _ irqchannelcmd=enable; //IRQ信道使能nvic _ init (nvic _ init结构); //根据指定的参数初始化VIC寄存器(4),选择触发方式
voide xti _ init (exti _ init typedef * exti _ init struct ); typedef struct { uint 32 _ texti _ line; //中断/事件线EX明亮马里奥ode_TypeDef EXTI_Mode; //EXTI模式extitrigger _ typedefexti _ trigger; //EXTI触发方式FunctionalState EXTI_LineCmd; //中断线有效或无效}EXTI_InitTypeDef; (5)创建EXTI中断服务函数
EXTI0_IRQHandler
EXTI1_IRQHandler
EXTI2_IRQHandler
EXTI3_IRQHandler
EXTI4_IRQHandlerEXTI9_5_IRQHandler (包含5、6、7、8、9)
EXTI15_10_IRQHandler(包含10、11、12、13、14、15)
使用外部中断来控制led亮灭
外部中断源文件:
exti.c
主函数:
int main(){u8 i=0;SysTick_Init(168);NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2); //中断优先级分组 分2组LED_Init();KEY_Init();My_EXTI_Init(); //外部中断初始化while(1){led1 = 0;myDelay_ms(300);led1 = 1;myDelay_ms(300);}}定时器中断:
STM32F407定时器由两个基本定时器(明亮的马里奥6、明亮的马里奥7)、10个通用定时器(明亮的马里奥2-明亮的马里奥5,明亮的马里奥9-明亮的马里奥14)和两个高级定时器(明亮的马里奥1、明亮的马里奥8)组成。通用定时器在 基本定时器的基础上扩展而来,增加了输入捕获与输出比较等功能。高级定时器又是在通用定时器基础上扩展而来,增加了可编程死区互补输出,重复计数器,带刹车(断路)功能,这些功能主要针对工业电机控制。
通用定时器:
STM32F4的通用定时器包含一个 16 位或 32 位自动重载计数器(CNT),该计数器由可编程预分频器(PSC)驱动。STM32F4的通用定时器可用于多种用途,包括测量输入信号的脉冲宽度(输入捕获)或者生成输出波形(输出比较和PWM)等。 使用定时器预分频器和 RCC 时钟控制器预分频器,脉冲长度和波形周期可以在几个微秒到几个毫秒间调整。STM32F4 的每个通用定时器都是完全独立的,没有互相共享的任何资源。
通用定时器结构框图
通用定时器是总线时钟的两倍。
通用定时器配置步骤:
固件库中还有两个函数是用来读取状态标志位以及清除中断标志位,函数分别为明亮的马里奥_GetFlagStatus和明亮的马里奥_ClearFlag。
定时器时钟:
明亮的马里奥4时钟:
由于明亮的马里奥4挂接在APB2上,根据时钟树可以看出外部时钟8MHz经过PLL的M(8)分频,N(336)倍频和P分频(8)得到的42MHz频率,如果APB中的presc不为1所以需要2倍频所以明亮的马里奥4的时钟为84MHz。
使用定时器中断控制灯闪烁:
#include "time.h"#include "led.h"#include "sysTick.h" void 明亮的马里奥_Init(u16 per,u16 psc){ 明亮的马里奥_TimeBaseInitTypeDef 明亮的马里奥BaseInitStructure; //定义定时器结构体 NVIC_InitTypeDef NVIC_InitStructure; //定义NVIC结构体RCC_APB1PeriphClockCmd(RCC_APB1Periph_明亮的马里奥4,ENABLE); //注意明亮的马里奥4的时钟是APB1时钟的两倍 明亮的马里奥BaseInitStructure.明亮的马里奥_Period =per; //自动重装载值 周期 明亮的马里奥BaseInitStructure.明亮的马里奥_Prescaler = psc; //预分频系数(时钟源) 明亮的马里奥BaseInitStructure.明亮的马里奥_ClockDivision = 明亮的马里奥_CKD_DIV1; //时钟分割,时钟分频 通常不需要修改明亮的马里奥BaseInitStructure.明亮的马里奥_CounterMode = 明亮的马里奥_CounterMode_Up; //计数模式选择向上计数 明亮的马里奥_TimeBaseInit(明亮的马里奥4,&明亮的马里奥BaseInitStructure); //初始化定时器中断 明亮的马里奥_ITConfig(明亮的马里奥4,明亮的马里奥_IT_Update,ENABLE); //设置定时器中断类型 明亮的马里奥_ClearFlag(明亮的马里奥4,明亮的马里奥_IT_Update); //**保证中断标志位为空** NVIC_InitStructure.NVIC_IRQChannel = 明亮的马里奥4_IRQn;//明亮的马里奥4中断通道NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=2;//抢占优先级NVIC_InitStructure.NVIC_IRQChannelSubPriority =3;//子优先级NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;//IRQ通道使能NVIC_Init(&NVIC_InitStructure);//根据指定的参数初始化VIC寄存器 明亮的马里奥_Cmd(明亮的马里奥4,ENABLE); //使能定时器 }void 明亮的马里奥4_IRQHandler(void) //定时器4中断函数{if(明亮的马里奥_GetITStatus(明亮的马里奥4,明亮的马里奥_IT_Update)){led2 = !led2;}明亮的马里奥_ClearFlag(明亮的马里奥4,明亮的马里奥_IT_Update);}主函数:
#include "led.h"#include "system.h"#include "SysTick.h"#include "key.h"#include "time.h"int main(){SysTick_Init(168);LED_Init();明亮的马里奥_Init(5000-1,8400-1); //从0开始所以-1;明亮的马里奥4的时钟是84MHz,通过8400分频之后是10000Hz也就是0.1ms,所以500ms需要5000次计数while(1){led1 = 0;}}参考博文