EXTI中断开关点亮LED源码
阅读原文时间:2023年07月10日阅读:1

在KEY点亮LED源码的基础上

USER下新建EXIT文件夹,新建bsp_exit.c和bsp_exit.h,添加到工程中(魔术棒添加头文件所在文件夹)

bsp_exit.h内容

#ifndef BSP_EIXT_H_
#define BSP_EIXT_H_

#include "stm32f10x.h"

void GPIOA_EXTI_Config(void);
void EXTI_NVIC_config(void);
#endif

bsp_exit.c内容

#include "bsp_exit.h"

void GPIOA_EXTI_Config(){

 GPIO\_InitTypeDef GPIO\_InitStruct;  
 EXTI\_InitTypeDef EXTI\_InitStruct; //变量声明不允许在语句执行之后

 EXTI\_NVIC\_config();  
 //初始化GPIOC  

RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);
GPIO_InitStruct.GPIO_Mode=GPIO_Mode_IN_FLOATING;
GPIO_InitStruct.GPIO_Pin=GPIO_Pin_0;
GPIO_Init(GPIOA, &GPIO_InitStruct);

 //初始化GPIOC\_13做为EXTI的输入线  
 GPIO\_EXTILineConfig(GPIO\_PortSourceGPIOA, GPIO\_PinSource0);  

RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO, ENABLE);

 EXTI\_InitStruct.EXTI\_Line=EXTI\_Line0;  
 EXTI\_InitStruct.EXTI\_LineCmd=ENABLE;  
 EXTI\_InitStruct.EXTI\_Mode=EXTI\_Mode\_Interrupt;  
 EXTI\_InitStruct.EXTI\_Trigger=EXTI\_Trigger\_Rising;  

EXTI_Init(&EXTI_InitStruct);
}

static void EXTI_NVIC_config(){ //只能被本文将内的调用
NVIC_InitTypeDef NVIC_InitStruct;
NVIC_PriorityGroupConfig( NVIC_PriorityGroup_1);

NVIC\_InitStruct.NVIC\_IRQChannel= EXTI0\_IRQn; //设置中断源注意(就是EXTI输入线)  
NVIC\_InitStruct.NVIC\_IRQChannelCmd=  ENABLE  ;  //打开  
NVIC\_InitStruct.NVIC\_IRQChannelPreemptionPriority= 1 ;  
NVIC\_InitStruct.NVIC\_IRQChannelSubPriority= 1  ;

NVIC\_Init(&NVIC\_InitStruct);  

}

sstm32f10x_it.c(引入LED和EXTI的相应头文件)

void EXTI0_IRQHandler(void){
if(EXTI_GetITStatus(EXTI_Line0)!=RESET){ //判断中断源是否为点亮LED的中断源
LED_TOGGLE;
}
EXTI_ClearITPendingBit(EXTI_Line0);//清除中断

}

main函数内容

#include "stm32f10x.h" // 相当于51单片机中的 #include
#include "bsp_led.h"
#include "bsp_exit.h"

int main(void)
{
// 来到这里的时候,系统的时钟已经被配置成72M。
LED_GPIO_Config();
GPIOA_EXTI_Config();
LED_OFF;
while(){

}  

}

bsp_led.c内容

#include "bsp_led.h"

void LED_GPIO_Config(){
GPIO_InitTypeDef GPIO_InitStruct;

RCC_APB2PeriphClockCmd(LED_GPIOC_CLOCK, ENABLE);
GPIO_InitStruct.GPIO_Mode=GPIO_Mode_Out_PP;
GPIO_InitStruct.GPIO_Pin=LED_GPIO_PIN;
GPIO_InitStruct.GPIO_Speed=GPIO_Speed_50MHz;

 GPIO\_Init(LED\_GPIO\_PORT, &GPIO\_InitStruct);  

}

void Delay( uint32_t count){
for( ;count!=;count--);

}

bsp_led.h内容

#ifndef BSP_LED_H_
#define BSP_LED_H_

#include "stm32f10x.h"

#define LED_GPIO_PIN GPIO_Pin_2
#define LED_GPIO_PORT GPIOC
#define LED_GPIOC_CLOCK RCC_APB2Periph_GPIOC

#define digitalHi(p,i) {p->BSRR=i;}
#define digitalToggle(p,i) {p->ODR ^=i;}
#define digitalLo(p,i) {p->BRR=i;}

#define LED_OFF digitalHi(LED_GPIO_PORT,LED_GPIO_PIN)
#define LED_ON digitalLo(LED_GPIO_PORT,LED_GPIO_PIN)
#define LED_TOGGLE digitalToggle(LED_GPIO_PORT,LED_GPIO_PIN)
void LED_GPIO_Config(void);
void Delay( uint32_t count);

#endif

总结

1-初始化要连接到EXTI的GPIO

初始化GPIO(配置为浮空输入,无速度),调用GPIO_EXTILineConfig( , ),将该GPIO作为输入线连接到EXTI输入线上;

开启相应的时钟.(外设都要有时钟)

2-初始化EXTI用于产生中断/事件

EXTI_Linex  x为0-19

开启相应的时钟RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO, ENABLE)

3-初始化NVIC,用于处理中断

初始化EXTI 和NVIC(NVIC_PriorityGroupConfig( )设置其优先级不在结构体中)结构体, (并在EXIT中调用NVIC的初始化函数).

初始化NVIC结构体时候,特别注意NVIC_IRQChannel的值不是递增的规律, EXTI15_10_IRQn ,EXTI9_5_IRQn  EXTIx_IRQn x为0-4

(内核外设没有时钟)

4-编写中断服务函数

中断服务函数的名字要在启动文件(startup_stm32f10x_hd.s)中需要,一定要对照好,否则即便是错误的也不会报错. 同NVIC的中断源一样也不是递增的.

步骤一般为先判断是否有中断,然后执行中断内容,最后清除中断.
5-main函数

调用LED和EXTI初始化函数,while无限循环空操作.