【STM32】STM32中断体系

一、STM32的NVIC和起始代码中的ISP

1.NVIC(嵌套向量中断控制器)

(1)数据手册中相关部分浏览
(2)地址映射时0地址映射到Flash或SRAM
(3)中断向量表可以被人为重新映射,一般用来IAP中
(4)STM32采用一维的中断向量表
(5)中断优先级设置有点复杂,后面细说

1.特征

2.系统嘀嗒(SysTick)校准值寄存器

3.向量表

在每一个中断函数在startup_stm32f10x_md.s中都有进行定义

2、起始代码中的ISR

(1)其实代码中定义了一个Vector数组
(2)WEAK声明的默认ISR
(3)用户根据需要提供自己真正有用的ISR
(4)中断要配置使能,ISR中要清挂起等,这一点和其他CPU一样

二、STM32的外部中断(EXTI)

1.EXTI 控制器的主要特性如下:

2.外部中断/事件控制器框图

3.外部中断与I/O 映像(AFIO的的中断)

AFIO中与中断相关的寄存器有4个

记得再使用之前一定要使能时钟!!!!!

我们有4个AFIO的中断寄存器,则一个寄存器中应该可以处理16个引脚。

最好使用引脚时,设置PA0,PA1....

使用AFIO中的EXTICRx寄存器进行操作

/*** @brief  Selects the GPIO pin used as EXTI Line.* @param  GPIO_PortSource: selects the GPIO port to be used as source for EXTI lines.*   This parameter can be GPIO_PortSourceGPIOx where x can be (A..G).* @param  GPIO_PinSource: specifies the EXTI line to be configured.*   This parameter can be GPIO_PinSourcex where x can be (0..15).* @retval None*/
void GPIO_EXTILineConfig(uint8_t GPIO_PortSource, uint8_t GPIO_PinSource)
{uint32_t tmp = 0x00;/* Check the parameters */assert_param(IS_GPIO_EXTI_PORT_SOURCE(GPIO_PortSource));assert_param(IS_GPIO_PIN_SOURCE(GPIO_PinSource));tmp = ((uint32_t)0x0F) << (0x04 * (GPIO_PinSource & (uint8_t)0x03));AFIO->EXTICR[GPIO_PinSource >> 0x02] &= ~tmp;AFIO->EXTICR[GPIO_PinSource >> 0x02] |= (((uint32_t)GPIO_PortSource) << (0x04 * (GPIO_PinSource & (uint8_t)0x03)));
}

1.外部中断配置寄存器 1(AFIO_EXTICR1)

2.外部中断配置寄存器 2(AFIO_EXTICR2)

4.如何实际编程使用外部中断

(1)时钟设置并打开相应GPIO模块时钟
(2)将相应GPIO配置为浮空输入
(3)NVIC设置
(4)将外部中断线和配套的GPIO进行连接映射


(5)外部中断线使能触发
(6)准备好ISR,并在ISR处等待执行中断程序即可

(7)记得!!!!!!!!!执行完ISR后记得将中断清除。

5.外部中断 VS 外部事件中断

外部中断:需要CPU,中断处理程序的参与

外部事件中断:不需要CPU参与

我们一般使用外部中断,不使用外部事件中断,因为我们不知道该器件是否接受脉冲信号。

6.相关寄存器

1. 上升沿触发选择寄存器(EXTI_RTSR)

2.下降沿触发选择寄存器(EXTI_FTSR)

3.中断屏蔽寄存器(EXTI_IMR)

4.挂起寄存器(EXTI_PR)

三、标准库中NVIC(中断优先级)模块分析

因为中断处理是在CPU内部进行的,所以没有单独的.c和.h文件

NVIC在【misc.c】中

1.抢占优先级 VS 次优先级

当抢占优先级的不同时,抢占优先级小的先执行,然后在执行优先级大的。

当抢占优先级相同时,次优先级小的不能抢占次优先级大的

当相同抢占优先级的程序进行中断时,次优先级小的可以抢先执行,在执行次优先级大的。

//PreemptionPriority:抢优先级uint8_t NVIC_IRQChannelPreemptionPriority;  /*!< Specifies the pre-emption priority for the IRQ channelspecified in NVIC_IRQChannel. This parameter can be a valuebetween 0 and 15 as described in the table @ref NVIC_Priority_Table */
//次优先级【同一个抢占级别中进行判断的】uint8_t NVIC_IRQChannelSubPriority;         /*!< Specifies the subpriority level for the IRQ channel specifiedin NVIC_IRQChannel. This parameter can be a valuebetween 0 and 15 as described in the table @ref NVIC_Priority_Table */

2.优先级组

/**pre-emption:抢占优先级subpriority:次优先级
*/
#define NVIC_PriorityGroup_0         ((uint32_t)0x700) /*!< 0 bits for pre-emption priority4 bits for subpriority=》2的4次方*/
#define NVIC_PriorityGroup_1         ((uint32_t)0x600) /*!< 1 bits for pre-emption priority3 bits for subpriority=>2的3次方*/
#define NVIC_PriorityGroup_2         ((uint32_t)0x500) /*!< 2 bits for pre-emption priority2 bits for subpriority */
#define NVIC_PriorityGroup_3         ((uint32_t)0x400) /*!< 3 bits for pre-emption priority1 bits for subpriority */
#define NVIC_PriorityGroup_4         ((uint32_t)0x300) /*!< 4 bits for pre-emption priority0 bits for subpriority */

3.启动方式

RAM或者FLASH

/**启动方式:RAM或者FLASH从0x0000 0000到0x080 0000之间的地址是用来设置映射关系因为我们使用FLASH启动,所以将其映射到0x0800 0000*/
#define NVIC_VectTab_RAM             ((uint32_t)0x20000000)
#define NVIC_VectTab_FLASH           ((uint32_t)0x08000000)
#define IS_NVIC_VECTTAB(VECTTAB) (((VECTTAB) == NVIC_VectTab_RAM) || \((VECTTAB) == NVIC_VectTab_FLASH))

4.函数

1.NVIC_PriorityGroupConfig

在使用时一定设置使用哪一个优先级

/*** @brief  Configures the priority grouping: pre-emption priority and subpriority.* @param  NVIC_PriorityGroup: specifies the priority grouping bits length. *   This parameter can be one of the following values:*     @arg NVIC_PriorityGroup_0: 0 bits for pre-emption priority*                                4 bits for subpriority*     @arg NVIC_PriorityGroup_1: 1 bits for pre-emption priority*                                3 bits for subpriority*     @arg NVIC_PriorityGroup_2: 2 bits for pre-emption priority*                                2 bits for subpriority*     @arg NVIC_PriorityGroup_3: 3 bits for pre-emption priority*                                1 bits for subpriority*     @arg NVIC_PriorityGroup_4: 4 bits for pre-emption priority*                                0 bits for subpriority* @retval None*/
void NVIC_PriorityGroupConfig(uint32_t NVIC_PriorityGroup)
{/* Check the parameters */assert_param(IS_NVIC_PRIORITY_GROUP(NVIC_PriorityGroup));/* Set the PRIGROUP[10:8] bits according to NVIC_PriorityGroup value */SCB->AIRCR = AIRCR_VECTKEY_MASK | NVIC_PriorityGroup;
}

2.NVIC_Init

void NVIC_Init(NVIC_InitTypeDef* NVIC_InitStruct)
{uint32_t tmppriority = 0x00, tmppre = 0x00, tmpsub = 0x0F;/* Check the parameters */assert_param(IS_FUNCTIONAL_STATE(NVIC_InitStruct->NVIC_IRQChannelCmd));assert_param(IS_NVIC_PREEMPTION_PRIORITY(NVIC_InitStruct->NVIC_IRQChannelPreemptionPriority));  assert_param(IS_NVIC_SUB_PRIORITY(NVIC_InitStruct->NVIC_IRQChannelSubPriority));if (NVIC_InitStruct->NVIC_IRQChannelCmd != DISABLE){/* Compute the Corresponding IRQ Priority --------------------------------*/    tmppriority = (0x700 - ((SCB->AIRCR) & (uint32_t)0x700))>> 0x08;tmppre = (0x4 - tmppriority);tmpsub = tmpsub >> tmppriority;tmppriority = (uint32_t)NVIC_InitStruct->NVIC_IRQChannelPreemptionPriority << tmppre;tmppriority |=  NVIC_InitStruct->NVIC_IRQChannelSubPriority & tmpsub;tmppriority = tmppriority << 0x04;NVIC->IP[NVIC_InitStruct->NVIC_IRQChannel] = tmppriority;/* Enable the Selected IRQ Channels --------------------------------------*/NVIC->ISER[NVIC_InitStruct->NVIC_IRQChannel >> 0x05] =(uint32_t)0x01 << (NVIC_InitStruct->NVIC_IRQChannel & (uint8_t)0x1F);}else{/* Disable the Selected IRQ Channels -------------------------------------*/NVIC->ICER[NVIC_InitStruct->NVIC_IRQChannel >> 0x05] =(uint32_t)0x01 << (NVIC_InitStruct->NVIC_IRQChannel & (uint8_t)0x1F);}
}

3.NVIC_SetVectorTable

设置中断向量表,看要设置到RAM还是FLASH

void NVIC_SetVectorTable(uint32_t NVIC_VectTab, uint32_t Offset)
{ /* Check the parameters */assert_param(IS_NVIC_VECTTAB(NVIC_VectTab));assert_param(IS_NVIC_OFFSET(Offset));  SCB->VTOR = NVIC_VectTab | (Offset & (uint32_t)0x1FFFFF80);
}

四、标准库中外部中断模块分析

1.EXTI_DeInit

 //完全去始化
void EXTI_DeInit(void)
{EXTI->IMR = 0x00000000;EXTI->EMR = 0x00000000;EXTI->RTSR = 0x00000000; EXTI->FTSR = 0x00000000; EXTI->PR = 0x000FFFFF;
}

2.EXTI_Init

将我们设置好的结构体变量写入到寄存器中

/*** @brief  Initializes the EXTI peripheral according to the specified*         parameters in the EXTI_InitStruct.* @param  EXTI_InitStruct: pointer to a EXTI_InitTypeDef structure*         that contains the configuration information for the EXTI peripheral.* @retval None*/
void EXTI_Init(EXTI_InitTypeDef* EXTI_InitStruct)
{uint32_t tmp = 0;/* Check the parameters */assert_param(IS_EXTI_MODE(EXTI_InitStruct->EXTI_Mode));assert_param(IS_EXTI_TRIGGER(EXTI_InitStruct->EXTI_Trigger));assert_param(IS_EXTI_LINE(EXTI_InitStruct->EXTI_Line));  assert_param(IS_FUNCTIONAL_STATE(EXTI_InitStruct->EXTI_LineCmd));tmp = (uint32_t)EXTI_BASE;if (EXTI_InitStruct->EXTI_LineCmd != DISABLE)//表示要使能{/* Clear EXTI line configuration */EXTI->IMR &= ~EXTI_InitStruct->EXTI_Line;EXTI->EMR &= ~EXTI_InitStruct->EXTI_Line;tmp += EXTI_InitStruct->EXTI_Mode;*(__IO uint32_t *) tmp |= EXTI_InitStruct->EXTI_Line;/* Clear Rising Falling edge configuration */EXTI->RTSR &= ~EXTI_InitStruct->EXTI_Line;EXTI->FTSR &= ~EXTI_InitStruct->EXTI_Line;/* Select the trigger for the selected external interrupts */if (EXTI_InitStruct->EXTI_Trigger == EXTI_Trigger_Rising_Falling){/* Rising Falling edge */EXTI->RTSR |= EXTI_InitStruct->EXTI_Line;EXTI->FTSR |= EXTI_InitStruct->EXTI_Line;}else{tmp = (uint32_t)EXTI_BASE;tmp += EXTI_InitStruct->EXTI_Trigger;*(__IO uint32_t *) tmp |= EXTI_InitStruct->EXTI_Line;}}else{tmp += EXTI_InitStruct->EXTI_Mode;/* Disable the selected external lines */*(__IO uint32_t *) tmp &= ~EXTI_InitStruct->EXTI_Line;}
}

3.EXTI_StructInit

如果用户不想自己设置中断值,则可以调用这个函数,这个函数中有默认值可以使用

void EXTI_StructInit(EXTI_InitTypeDef* EXTI_InitStruct)
{EXTI_InitStruct->EXTI_Line = EXTI_LINENONE;EXTI_InitStruct->EXTI_Mode = EXTI_Mode_Interrupt;EXTI_InitStruct->EXTI_Trigger = EXTI_Trigger_Falling;EXTI_InitStruct->EXTI_LineCmd = DISABLE;
}

4.EXTI_GenerateSWInterrupt

软件中断,可以对寄存器中其中一位进行中断操作

void EXTI_GenerateSWInterrupt(uint32_t EXTI_Line)
{/* Check the parameters */assert_param(IS_EXTI_LINE(EXTI_Line));EXTI->SWIER |= EXTI_Line;
}

5.EXTI_GetFlagStatus

共享中断:判断中断标志位是否真的置1了(判断是哪一个标志进行中断的)

/*** @brief  Checks whether the specified EXTI line flag is set or not.* @param  EXTI_Line: specifies the EXTI line flag to check.*   This parameter can be:*     @arg EXTI_Linex: External interrupt line x where x(0..19)* @retval The new state of EXTI_Line (SET or RESET).*/
FlagStatus EXTI_GetFlagStatus(uint32_t EXTI_Line)
{FlagStatus bitstatus = RESET;/* Check the parameters */assert_param(IS_GET_EXTI_LINE(EXTI_Line));if ((EXTI->PR & EXTI_Line) != (uint32_t)RESET){bitstatus = SET;}else{bitstatus = RESET;}return bitstatus;
}

6.EXTI_ClearITPendingBit(中断挂起)

中断进入后,就会有一个中断挂起

/*** @brief  Clears the EXTI's line pending bits.* @param  EXTI_Line: specifies the EXTI lines to clear.*   This parameter can be any combination of EXTI_Linex where x can be (0..19).* @retval None*/
void EXTI_ClearITPendingBit(uint32_t EXTI_Line)
{/* Check the parameters */assert_param(IS_EXTI_LINE(EXTI_Line));EXTI->PR = EXTI_Line;
}

6.EXTI_ClearFlag

清除中断

void EXTI_ClearFlag(uint32_t EXTI_Line)
{/* Check the parameters */assert_param(IS_EXTI_LINE(EXTI_Line));EXTI->PR = EXTI_Line;
}

五、GPIO外部中断程序的移植和调试

0.GPIO外部中断的配置步骤

使用HAL_GPIO_Init一步到位(步骤2-步骤5)

1.EXTI的HAL库设置步骤(GPIO外部中断)

2.通用外设驱动模型

3.HAL库中断回调处理机制介绍

1.建立工程模板

STM32项目工程的搭建-CSDN博客

2.查看官方示例代码

以ARM3.0的按键示例程序作为参考,移植到PZ6806L开发板上。

stm32f10x_it.c

将我们在初始化文件(STM32F10x_md.c)中的中断函数进行覆盖重写。

startup_stm32f10x_md.s

这个文件中存放是有中断处理函数的定义

我们如果想要执行(使用)这个中断,则将在md文件中将函数名字复制出来,然后再stm32f10x_it.c文件中使用

stm32f10x_it.h

我们上面再stm32f10x_it.c中重写了一个函数,则要再这个.h文件中进行声明

main.c

RCC_Configuragtion

作用:将时钟设置为72MHZ,将相关的开关打开。

GPIO_Configuration

NVIC_Configuration

NVIC中断优先级的初始化

3.整个main函数的流程

1)初始化RCC

2)初始化GPIO

3)初始化NVIC

4)设置外部中断(将中断线和GPIO线连接起来)

5)外部中断线的模式选择(我们一般选择外部中断,不使用外部事件中断)

6)产生软件中断触发事件

4.开始移植

1.按键的接线问题

这个程序的执行结果是:按下按键一(KEY1),使得LED16(也就是4*4矩阵显示屏上最后一排灯亮起)

独立按键的JP1接到PB0-PB7

LED8-LED16的J34接到PA0-PA7

因为操作库函数的时候只能一位一位操作,所以我们只能选择其中一个引脚进行操作。

我们选择KEY1和LED16进行操作,分别对应PB0和PA7

2.关于中断几的选择

由上面可知我们KEY1对应的是PB0,由0可知应该选择EXIT0

确定好后,再stm32f10x.c和stm32f10x.h文件中进行重写和声明【我们可以再stm32f10x_md.c文件中查看应该调用哪一个函数】

3.EXTI0_IRQHandler的移植

注意点:本来我们应该再stm32f10x_it.c文件中去查找这个中断函数的初始化,但是普中科技的AMR3.0的官方代码将这个中断函数的初始化写再了exit.c文件中。

stm32f10x_it.c
  */
void EXTI0_IRQHandler(void)
{//检测制定的EXTI线路触发if(EXTI_GetITStatus(EXTI_Line0)==1){/*delay_ms(10);if(KEY1==0){led2=0;}*/}//清除EXTI线路挂起位EXTI_ClearITPendingBit(EXTI_Line0);
}
stm32f10x_it.h
//声明自己写的EXIT0
void EXTI0_IRQHandler(void);

4.RCC_Configuration的移植

1.RCC的使能
//RCC的配置
void RCC_Configuration(void){//因为起始代码中已经调用SystemInit将主时钟设置为72MHZ//所以我们这里RCC直接使能时钟就可以//使能GPIO端口//因为我们使用到的是PB0和PB8,所以只使用到GPIOBRCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB|RCC_APB2Periph_AFIO,ENABLE);}
2.GPIO_Configuration的移植
//GPIO初始化
void CPIO_Configuration(void){GPIO_InitTypeDef GPIO_InitStructure;//PB0 -- Key1 -- EXIT2		PA7 ---LED16//PB0 -- Key1 -- EXIT2【按键是输入获取】GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0;GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;	  //配置浮空输入GPIO_Init(GPIOB, &GPIO_InitStructure);//PA7 ---LED16【LED的显示输出】GPIO_InitStructure.GPIO_Pin = GPIO_Pin_7;GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;       //推挽输出GPIO_Init(GPIOA, &GPIO_InitStructure);GPIO_WriteBit(GPIOA, GPIO_Pin_7, Bit_RESET);			// 默认输出0让LED亮}
3.NVIC优先级的移植

NVIC_IRQChannel:在misc.h中定义

void NVIC_Configuration(void)
{NVIC_InitTypeDef NVIC_InitStructure;#ifdef  VECT_TAB_RAM  /* Set the Vector Table base location at 0x20000000 */ NVIC_SetVectorTable(NVIC_VectTab_RAM, 0x0);   //分配中断向量表
#else  /* VECT_TAB_FLASH  *///表示从FLASH中启动/* Set the Vector Table base location at 0x08000000 */ NVIC_SetVectorTable(NVIC_VectTab_FLASH, 0x0);   
#endif/* Configure one bit for preemption priority */// NVIC_PriorityGroup_1:2个抢占优先级,8个次优先级NVIC_PriorityGroupConfig(NVIC_PriorityGroup_1);  //设置中断优先级/* Enable the EXTI2 Interrupt */NVIC_InitStructure.NVIC_IRQChannel = EXTI0_IRQn; //中断通道NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority =  0;  //强占优先级NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;//次优先级NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;  //通道中断使能NVIC_Init(&NVIC_InitStructure);//初始化中断
}
4.main函数
//函数声明
//RCC的配置
void RCC_Configuration(void);
//GPIO初始化
void GPIO_Configuration(void);
void NVIC_Configuration(void);//全局变量定义
EXTI_InitTypeDef EXTI_InitStructure;
ErrorStatus HSEStatartUpStatus;int main(){//系统时钟配置RCC_Configuration();//NVIC配置NVIC_Configuration();//配置GPIOGPIO_Configuration();//将EXTI线0连接到PB0【处理按键中断】GPIO_EXTILineConfig(GPIO_PortSourceGPIOB,GPIO_PinSource0);/* Configure Key Button EXTI Line to generate an interrupt on falling edge */  //配置按钮中断线触发方式EXTI_InitStructure.EXTI_Line = EXTI_Line0;EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt;EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Falling; //下降沿触发EXTI_InitStructure.EXTI_LineCmd = ENABLE; //中断线使能EXTI_Init(&EXTI_InitStructure); //初始化中断/* Generate software interrupt: simulate a falling edge applied on Key Button EXTI line */// 	EXTI_GenerateSWInterrupt(EXTI_Line0); //EXTI_Line2中断允许 到此中断配置完成,可以写中断处理函数。while (1);return 0;
}
5.中断函数的处理(stm32f10x_it.c)

因为我们要在中断函数中对LED进行点亮/熄灭,所以需要对LED进行读取和写入。

所以要使用到我们的【GPIO_ReadInputDataBit】和【GPIO_WriteBit】

void EXTI0_IRQHandler(void)
{//检测制定的EXTI线路触发if(EXTI_GetITStatus(EXTI_Line0)==1){//此时控制的是LED,LED对应的是PA0//我们想要对LED进行点亮/熄灭//则应该先将此时LED的状态位读取出来,然后在取反写进去GPIO_WriteBit(GPIOA,GPIO_Pin_0,(BitAction)((1-GPIO_ReadInputDataBit(GPIOA,GPIO_Pin_0))));}//清除EXTI线路挂起位EXTI_ClearITPendingBit(EXTI_Line0);
}
6.对LED的初始化

在对GPIO初始化的时候一起将lED一起点亮

	// 默认输出1让LED亮GPIO_WriteBit(GPIOA, GPIO_Pin_7, Bit_SET);	

3.完整代码

main.c

#include "stm32f10x.h"                  // Device header/**使用库函数对STM32进行GPIO的外部中断按下KEY1对LED16进行点亮/熄灭
*///函数声明
//RCC的配置
void RCC_Configuration(void);
//GPIO初始化
void GPIO_Configuration(void);
void NVIC_Configuration(void);//全局变量定义
EXTI_InitTypeDef EXTI_InitStructure;
ErrorStatus HSEStatartUpStatus;int main(){//系统时钟配置RCC_Configuration();//NVIC配置NVIC_Configuration();//配置GPIOGPIO_Configuration();//将EXTI线0连接到PB0【处理按键中断】GPIO_EXTILineConfig(GPIO_PortSourceGPIOB,GPIO_PinSource0);/* Configure Key Button EXTI Line to generate an interrupt on falling edge */  //配置按钮中断线触发方式EXTI_InitStructure.EXTI_Line = EXTI_Line0;EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt;EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Falling; //下降沿触发EXTI_InitStructure.EXTI_LineCmd = ENABLE; //中断线使能EXTI_Init(&EXTI_InitStructure); //初始化中断/* Generate software interrupt: simulate a falling edge applied on Key Button EXTI line *///人为产生中断//如果不想要一进来就产生中断,则应该注释掉//EXTI_Line0中断允许 到此中断配置完成,可以写中断处理函数。EXTI_GenerateSWInterrupt(EXTI_Line0); while (1);return 0;
}//RCC的配置
void RCC_Configuration(void){//因为起始代码中已经调用SystemInit将主时钟设置为72MHZ//所以我们这里RCC直接使能时钟就可以//使能GPIO端口//因为我们使用到的是PB0和PB8,所以只使用到GPIOBRCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB|RCC_APB2Periph_GPIOA | RCC_APB2Periph_AFIO,ENABLE);}//GPIO初始化
void CPIO_Gonfiguration(void){GPIO_InitTypeDef GPIO_InitStructure;//PB0 -- Key1 -- EXIT2		PA7 ---LED16//PB0 -- Key1 -- EXIT2【按键是输入获取】GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0;GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;	  //配置浮空输入GPIO_Init(GPIOB, &GPIO_InitStructure);//PA7 ---LED16【LED的显示输出】GPIO_InitStructure.GPIO_Pin = GPIO_Pin_7;GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;       //推挽输出GPIO_Init(GPIOA, &GPIO_InitStructure);// 默认输出1让LED亮GPIO_WriteBit(GPIOA, GPIO_Pin_7, Bit_SET);			}void NVIC_Configuration(void)
{NVIC_InitTypeDef NVIC_InitStructure;#ifdef  VECT_TAB_RAM  /* Set the Vector Table base location at 0x20000000 */ NVIC_SetVectorTable(NVIC_VectTab_RAM, 0x0);   //分配中断向量表
#else  /* VECT_TAB_FLASH  *///表示从FLASH中启动/* Set the Vector Table base location at 0x08000000 */ NVIC_SetVectorTable(NVIC_VectTab_FLASH, 0x0);   
#endif/* Configure one bit for preemption priority */// NVIC_PriorityGroup_1:2个抢占优先级,8个次优先级NVIC_PriorityGroupConfig(NVIC_PriorityGroup_1);  //设置中断优先级/* Enable the EXTI2 Interrupt */NVIC_InitStructure.NVIC_IRQChannel = EXTI0_IRQn; //中断通道NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority =  0;  //强占优先级NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;//次优先级NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;  //通道中断使能NVIC_Init(&NVIC_InitStructure);//初始化中断
}
stm32f10x_it.c
void EXTI0_IRQHandler(void)
{//检测制定的EXTI线路触发if(EXTI_GetITStatus(EXTI_Line0)==1){//此时控制的是LED,LED对应的是PA0//我们想要对LED进行点亮/熄灭//则应该先将此时LED的状态位读取出来,然后在取反写进去GPIO_WriteBit(GPIOA,GPIO_Pin_0,(BitAction)((1-GPIO_ReadInputDataBit(GPIOA,GPIO_Pin_0))));}//清除EXTI线路挂起位EXTI_ClearITPendingBit(EXTI_Line0);
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/151202.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Java练习题2020-2

"统计1到N的整数中,除了1和自身之外&#xff0c;至少还能被两个数整除的数的个数 输入说明&#xff1a;整数 N(N<10000)&#xff1b; 输出说明&#xff1a;符合条件的数的个数 输入样例&#xff1a;10 输出样例&#xff1a;3 (说明&#xff1a;样例中符合条件的3个数是…

【2024秋招】2023-9-16 贝壳后端开发二面

1 自我介绍 2 秒杀系统 2.1 超卖怎么解决 3 redis 3.1 过期策略 3.2 过期算法 4 kafka 4.1 说一说你对kafka的了解 4.2 如何保证事务性消息 4.3 如何保证消息不丢失 4.4 消息队列的两种通信方式 点对点模式 如上图所示&#xff0c;点对点模式通常是基于拉取或者轮询…

【算法练习Day30】无重叠区间 划分字母区间合并区间

​&#x1f4dd;个人主页&#xff1a;Sherry的成长之路 &#x1f3e0;学习社区&#xff1a;Sherry的成长之路&#xff08;个人社区&#xff09; &#x1f4d6;专栏链接&#xff1a;练题 &#x1f3af;长路漫漫浩浩&#xff0c;万事皆有期待 文章目录 无重叠区间划分字母区间合并…

docker应用部署---nginx部署的配置

1. 搜索nginx镜像 docker search nginx2. 拉取nginx镜像 docker pull nginx3. 创建容器&#xff0c;设置端口映射、目录映射 # 在/root目录下创建nginx目录用于存储nginx数据信息 mkdir ~/nginx cd ~/nginx mkdir conf cd conf# 在~/nginx/conf/下创建nginx.conf文件,粘贴下…

yum--centos 和apt --ubuntu

centos安装软件 搜索语法&#xff1a;yum -y search 软件名称 安装软件前可以先去搜一下看看能用yum中有这个软件吗 安装语法&#xff1a;yum -y install 软件名称 写上 -y 意思是不用手动确认&#xff0c;直接安装 卸载语法&#xff1a;yum -y remove 软件名称 注…

推荐一个高效测试用例工具:XMind2TestCase..

一、背景 软件测试的核心是什么&#xff1f;毫无疑问是测试分析和测试用例设计&#xff0c;也是日常测试投入最多时间的工作内容之一。 然而&#xff0c;传统的测试用例设计过程有很多痛点&#xff1a; 1、使用Excel表格进行测试用例设计&#xff0c;虽然成本低&#xff0c;但…

3.加载天地图

愿你出走半生,归来仍是少年&#xff01; 上一篇文章构建出来基础的白球&#xff0c;现在需要给它添加底图啦。先上最常用的天地图。 1.天地图 天地图做过Gis开发的应该都知道&#xff0c;需要先申请key然后才能使用。然后天地图是基于XYZ的标准进行切片的&#xff0c;所以直接…

浏览器事件循环 (event loop)

进程与线程 进程 进程的概念 进程是操作系统中的一个程序或者一个程序的一次执行过程&#xff0c;是一个动态的概念&#xff0c;是程序在执行过程中分配和管理资源的基本单位&#xff0c;是操作系统结构的基础。 简单的来说&#xff0c;就是一个程序运行开辟的一块内存空间&a…

win10 + VS2017 编译libjpeg(jpeg-9b)--更新

刚刚写了一篇“win10 VS2017 编译libjpeg&#xff08;jpeg-9b&#xff09;”&#xff0c; 然后就发现&#xff0c;还有一个更好的方法。因此&#xff0c;重新更新了一篇&#xff0c;作为对比与参考。 需要用到的文件&#xff1a; jpeg-9b.zip win32.mak 下载链接链接…

数据挖掘神器Orange初步使用

文章目录 安装示例项目展示鸢尾花数据 安装 可以在官网下载&#xff0c;地址为Orange&#xff0c;如果已经装了Anaconda&#xff0c;则可在Anaconda Navigator中找到一个非常猥琐的图标&#xff0c;下面写着Orange3&#xff0c;可以点击Install&#xff0c;装完之后点Launch就…

【鸿蒙软件开发】ArkTS基础组件之Gauge(环形图表)、LoadingProgress(动态加载)

文章目录 前言一、Gauge环形图表1.1 子组件1.2 接口参数介绍 1.2 属性1.3 示例代码二、LoadingProgress2.1 子组件2.2 接口2.3 属性2.4 示例代码 总结 前言 Gauge&#xff1a;数据量规图表组件&#xff0c;用于将数据展示为环形图表。 LoadingProgress&#xff1a;用于显示加载…

CDR和AI哪个软件更好用?

设计软件市场中&#xff0c;CorelDRAW和Adobe Illustrator&#xff08;简称AI&#xff09;无疑是两大重量级选手。它们各自拥有庞大的用户群和丰富的功能&#xff0c;但究竟哪一个更好用&#xff1f;本文将从多个角度出发&#xff0c;对这两款软件进行全面而深入的比较&#xf…