首页 > 编程知识 正文

stm32定时器更新中断,stm32定时器中断最短时间

时间:2023-05-04 15:33:06 阅读:112206 作者:1926

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_IRQHandler
EXTI9_5_IRQHandler (包含5、6、7、8、9)
EXTI15_10_IRQHandler(包含10、11、12、13、14、15)

使用外部中断来控制led亮灭
外部中断源文件:
exti.c

void My_EXTI_Init(void){ NVIC_InitTypeDef NVIC_InitStructure; //定义NVIC结构体EXTI_InitTypeDef EXTI_InitStructure; //定义EXTI结构体RCC_APB2PeriphClockCmd(RCC_APB2Periph_SYSCFG,ENABLE); //使能IO口时钟SYSCFG_EXTILineConfig(EXTI_PortSourceGPIOA,EXTI_PinSource0); //打开SYSCFG时钟 该函数定义位于stm32f4xx_syscfg.c中SYSCFG_EXTILineConfig(EXTI_PortSourceGPIOE,EXTI_PinSource2); //打开SYSCFG时钟是配置GPIO中断线映射的前提SYSCFG_EXTILineConfig(EXTI_PortSourceGPIOE,EXTI_PinSource3);SYSCFG_EXTILineConfig(EXTI_PortSourceGPIOE,EXTI_PinSource4);//EXTI0 NVIC 配置NVIC_InitStructure.NVIC_IRQChannel = EXTI0_IRQn;//EXTI0中断通道NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=2;//抢占优先级NVIC_InitStructure.NVIC_IRQChannelSubPriority =3;//子优先级NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;//IRQ通道使能NVIC_Init(&NVIC_InitStructure);//根据指定的参数初始化VIC寄存器//EXTI2 NVIC 配置NVIC_InitStructure.NVIC_IRQChannel = EXTI2_IRQn;//EXTI2中断通道NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=2;//抢占优先级NVIC_InitStructure.NVIC_IRQChannelSubPriority =2;//子优先级NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;//IRQ通道使能NVIC_Init(&NVIC_InitStructure);//根据指定的参数初始化VIC寄存器//EXTI3 NVIC 配置NVIC_InitStructure.NVIC_IRQChannel = EXTI3_IRQn;//EXTI3中断通道NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=2;//抢占优先级NVIC_InitStructure.NVIC_IRQChannelSubPriority =1;//子优先级NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;//IRQ通道使能NVIC_Init(&NVIC_InitStructure);//根据指定的参数初始化VIC寄存器//EXTI4 NVIC 配置NVIC_InitStructure.NVIC_IRQChannel = EXTI4_IRQn;//EXTI4中断通道NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=2;//抢占优先级NVIC_InitStructure.NVIC_IRQChannelSubPriority =0;//子优先级NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;//IRQ通道使能NVIC_Init(&NVIC_InitStructure);//根据指定的参数初始化VIC寄存器//初始化线上中断,设置KEY_UP触发条件EXTI_InitStructure.EXTI_Line=EXTI_Line0; //中断线的标号EXTI_InitStructure.EXTI_Mode=EXTI_Mode_Interrupt; //选择模式(中断或事件)EXTI_InitStructure.EXTI_Trigger=EXTI_Trigger_Rising; //根据按键电路选择触发方式EXTI_InitStructure.EXTI_LineCmd=ENABLE; //使能标志位EXTI_Init(&EXTI_InitStructure);//初始化线上中断,设置KEY_LEFT KEY_DOWN KEY_RIGHT触发条件EXTI_InitStructure.EXTI_Line=EXTI_Line2|EXTI_Line3|EXTI_Line4; EXTI_InitStructure.EXTI_Mode=EXTI_Mode_Interrupt;EXTI_InitStructure.EXTI_Trigger=EXTI_Trigger_Falling;EXTI_InitStructure.EXTI_LineCmd=ENABLE;EXTI_Init(&EXTI_InitStructure);}//设置各个按键的中断函数void EXTI0_IRQHandler(void){if(EXTI_GetITStatus(EXTI_Line0)==1) //读取中断标志位{myDelay_ms(10);if(K_UP==1){led2=0;}}EXTI_ClearITPendingBit(EXTI_Line0); //清除中断标志位}void EXTI3_IRQHandler(void){if(EXTI_GetITStatus(EXTI_Line3)==1){myDelay_ms(10);if(K_DOWN==0){led2=1;}}EXTI_ClearITPendingBit(EXTI_Line3);}void EXTI2_IRQHandler(void){if(EXTI_GetITStatus(EXTI_Line2)==1){myDelay_ms(10);if(K_RIGHT==0){led1=0;}}EXTI_ClearITPendingBit(EXTI_Line2);}void EXTI4_IRQHandler(void){if(EXTI_GetITStatus(EXTI_Line4)==1){myDelay_ms(10);if(K_LEFT==0){led1=1;}}EXTI_ClearITPendingBit(EXTI_Line4);}

主函数:

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;}}

参考博文

版权声明:该文观点仅代表作者本人。处理文章:请发送邮件至 三1五14八八95#扣扣.com 举报,一经查实,本站将立刻删除。