STM32指南者外部中断编程总结!

没有特殊说明的话,中断即异常,异常即中断!

一、来自野火官方中断框图

1、蓝色部分:输入线,即选择哪一个中断,例如:外部中断EXIT0-EXIT15

2、红色部分:外部中断配置请求

3、绿色部分:配置总中断

 二、确定编程顺序

其顺序和框图差不多:

1-初始化要连接到EXTI的GPIO(确定哪一个GPIO产生中断)
2-初始化EXTI用于产生中断/事件(配置外部中断)
3-初始化NVIC ,用于处理中断(配置总中断处理)
4-编写中断服务函数
5-main函数

三、功能

使用指南者开发板的KEY1和KEY2按键控制LED_G的亮灭,其接口分别为

key1:PA0; 

 key2:PC13

绿色LED:PB0

 四、编程要点

1、根基第二部编程顺序可知,首先初始化PA0端口,

引脚配置浮空输入GPIO_Mode_IN_FLOATING(即端口什么都不接)

c文件:

	GPIO_InitTypeDef GPIO_InitStruct;

	//初始化GPIO  PA0
	GPIO_InitStruct.GPIO_Mode=GPIO_Mode_IN_FLOATING;
	GPIO_InitStruct.GPIO_Pin=KEY_GPIO_PIN;
	RCC_APB2PeriphClockCmd(KEY_GPIOA_RCC,ENABLE);
	GPIO_Init(KEY_GPIO_PORT, &GPIO_InitStruct);

h文件:

#define KEY_GPIO_PIN    GPIO_Pin_0
#define KEY_GPIO_PORT   GPIOA
#define KEY_GPIOA_RCC   RCC_APB2Periph_GPIOA

2、初始化外部中断EXIT

看框图和代码:(相关函数和结构体在stm32f10x_exti.h文件里面)

1:打开输入线时钟,选择输入线,函数:GPIO_EXTILineConfig(去到函数原型查看参数选择对应参数)

2:配置EXIT_InitStruct结构体,具体配置看代码注解


EXTI_InitTypeDef EXIT_InitStruct;//在stm32f10x_exti.h文件里面
	
//初始化EXIT :根据框图,1、先选择输入线(即选择哪一个EXIT)
	               //  2、再初始化EXIT结构体

RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO,ENABLE);//输入线操作寄存器AFIO,因此需要打开其对应时钟
GPIO_EXTILineConfig(GPIO_PortSourceGPIOA,GPIO_PinSource0);//输入线选择,端口A,线0,参数在stm32f10x_gpio.c里面
	
EXIT_InitStruct.EXTI_Line=EXTI_Line0;//表示第几位的意思(并不是选择哪一个EXIT的意思),这个需要选择寄存器之后,才能确定操作哪一个寄存器的第几位
EXIT_InitStruct.EXTI_Mode=EXTI_Mode_Interrupt;//模式有两种,分别是中断和事件,参数在stm32f10x_exti.h里面
EXIT_InitStruct.EXTI_Trigger=EXTI_Trigger_Rising;//选择上升沿还是下降沿,参数在stm32f10x_exti.h里面
EXIT_InitStruct.EXTI_LineCmd=ENABLE;//使能该线
EXTI_Init(&EXIT_InitStruct);

3、配置中断管理NVIC

具体函数和结构体在misc.h里面

1、配置分组

2、配置结构体NVIC_InitTypeDef 

3、结构体的NVIC_InitStruct.NVIC_IRQChannel在stm32f10x.h里面找

static void EXIT_NVIC_Config(void)
{
	NVIC_InitTypeDef NVIC_InitStruct;
	
	NVIC_PriorityGroupConfig(NVIC_PriorityGroup_1);//中断优先级分组,可以查看misc.h
	
	//配置管理的通道:即选择哪一个中断处理,在stmf10x.h第200行作用,指南者的EXTI5-5通道为STM32F10X_HD,在300行作用
	NVIC_InitStruct.NVIC_IRQChannel=EXTI0_IRQn;
	
	//主优先级(抢占优先级),优先级顺序根据可以查看misc.h和stmf10x.h里面中断管理顺序
	NVIC_InitStruct.NVIC_IRQChannelPreemptionPriority=1;
	
	//子优先级(中断优先级比较的话,先比较主优先级,主优先级相同再比较子优先级,数字越小优先级越高,子优先级还相同比较stmf10x.h里面中断管理顺序)
	NVIC_InitStruct.NVIC_IRQChannelSubPriority=1;
	
	NVIC_InitStruct.NVIC_IRQChannelCmd=ENABLE;//使能中断
	
	NVIC_Init(&NVIC_InitStruct);//让前面所有的参数联系起来放入对应寄存器
}

4、配置中断函数

1、在配置好GPIO、EXIT和NVIC之后需要整合在一起,如下代码

static void EXIT_NVIC_Config(void)
{
	NVIC_InitTypeDef NVIC_InitStruct;
	
	NVIC_PriorityGroupConfig(NVIC_PriorityGroup_1);//中断优先级分组,可以查看misc.h
	
	//配置管理的通道:即选择哪一个中断处理,在stmf10x.h第200行作用,指南者的EXTI5-5通道为STM32F10X_HD,在300行作用
	NVIC_InitStruct.NVIC_IRQChannel=EXTI0_IRQn;
	
	//主优先级(抢占优先级),优先级顺序根据可以查看misc.h和stmf10x.h里面中断管理顺序
	NVIC_InitStruct.NVIC_IRQChannelPreemptionPriority=1;
	
	//子优先级(中断优先级比较的话,先比较主优先级,主优先级相同再比较子优先级,数字越小优先级越高,子优先级还相同比较stmf10x.h里面中断管理顺序)
	NVIC_InitStruct.NVIC_IRQChannelSubPriority=1;
	
	NVIC_InitStruct.NVIC_IRQChannelCmd=ENABLE;//使能中断
	
	NVIC_Init(&NVIC_InitStruct);//让前面所有的参数联系起来放入对应寄存器
}

void EXIT0_GPIO_Config(void)//PA0
{
	GPIO_InitTypeDef GPIO_InitStruct;
	EXTI_InitTypeDef EXIT_InitStruct;//在stm32f10x_exti.h文件里面
	
	//配置中断优先级
	EXIT_NVIC_Config();
	
	//初始化GPIO  PA0
	GPIO_InitStruct.GPIO_Mode=GPIO_Mode_IN_FLOATING;
	GPIO_InitStruct.GPIO_Pin=KEY_GPIO_PIN;
	RCC_APB2PeriphClockCmd(KEY_GPIOA_RCC,ENABLE);
	GPIO_Init(KEY_GPIO_PORT, &GPIO_InitStruct);
	
	//初始化EXIT :根据框图,1、先选择输入线(即选择哪一个EXIT)
	                    //  2、再初始化EXIT结构体

	RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO,ENABLE);//输入线操作寄存器AFIO,因此需要打开其对应时钟
	GPIO_EXTILineConfig(GPIO_PortSourceGPIOA,GPIO_PinSource0);//输入线选择,端口A,线0,参数在stm32f10x_gpio.c里面
	
	EXIT_InitStruct.EXTI_Line=EXTI_Line0;//表示第几位的意思(并不是选择哪一个EXIT的意思),这个需要选择寄存器之后,才能确定操作哪一个寄存器的第几位
	EXIT_InitStruct.EXTI_Mode=EXTI_Mode_Interrupt;//模式有两种,分别是中断和事件,参数在stm32f10x_exti.h里面
	EXIT_InitStruct.EXTI_Trigger=EXTI_Trigger_Rising;//选择上升沿还是下降沿,参数在stm32f10x_exti.h里面
	EXIT_InitStruct.EXTI_LineCmd=ENABLE;//使能该线
	EXTI_Init(&EXIT_InitStruct);
}

2、将这些函数在头文件和主函数声明好之后,就可以写中断函数

3、中断函数写在stm32f10x_it.c里面,其命名规则在启动文件里面starup_stm32f10x.hs.s

void EXTI0_IRQHandler(void)
{
	if(EXTI_GetITStatus(EXTI_Line0)!=RESET)//中断
	{
		LED_G_TOGGLE;
	}
	EXTI_ClearITPendingBit(EXTI_Line0);//清除中断标志,套路都这样
}

五、完整程序

exit的c文件:

#include "bsp_exit.h"


static void EXIT_NVIC_Config(void)
{
	NVIC_InitTypeDef NVIC_InitStruct;
	
	NVIC_PriorityGroupConfig(NVIC_PriorityGroup_1);//中断优先级分组,可以查看misc.h
	
	//配置管理的通道:即选择哪一个中断处理,在stmf10x.h第200行作用,指南者的EXTI5-5通道为STM32F10X_HD,在300行作用
	NVIC_InitStruct.NVIC_IRQChannel=EXTI0_IRQn;
	
	//主优先级(抢占优先级),优先级顺序根据可以查看misc.h和stmf10x.h里面中断管理顺序
	NVIC_InitStruct.NVIC_IRQChannelPreemptionPriority=1;
	
	//子优先级(中断优先级比较的话,先比较主优先级,主优先级相同再比较子优先级,数字越小优先级越高,子优先级还相同比较stmf10x.h里面中断管理顺序)
	NVIC_InitStruct.NVIC_IRQChannelSubPriority=1;
	
	NVIC_InitStruct.NVIC_IRQChannelCmd=ENABLE;//使能中断
	
	NVIC_Init(&NVIC_InitStruct);//让前面所有的参数联系起来放入对应寄存器
}

void EXIT0_GPIO_Config(void)//PA0
{
	GPIO_InitTypeDef GPIO_InitStruct;
	EXTI_InitTypeDef EXIT_InitStruct;//在stm32f10x_exti.h文件里面
	
	//配置中断优先级
	EXIT_NVIC_Config();
	
	//初始化GPIO  PA0
	GPIO_InitStruct.GPIO_Mode=GPIO_Mode_IN_FLOATING;
	GPIO_InitStruct.GPIO_Pin=KEY_GPIO_PIN;
	RCC_APB2PeriphClockCmd(KEY_GPIOA_RCC,ENABLE);
	GPIO_Init(KEY_GPIO_PORT, &GPIO_InitStruct);
	
	//初始化EXIT :根据框图,1、先选择输入线(即选择哪一个EXIT)
	                    //  2、再初始化EXIT结构体

	RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO,ENABLE);//输入线操作寄存器AFIO,因此需要打开其对应时钟
	GPIO_EXTILineConfig(GPIO_PortSourceGPIOA,GPIO_PinSource0);//输入线选择,端口A,线0,参数在stm32f10x_gpio.c里面
	
	EXIT_InitStruct.EXTI_Line=EXTI_Line0;//表示第几位的意思(并不是选择哪一个EXIT的意思),这个需要选择寄存器之后,才能确定操作哪一个寄存器的第几位
	EXIT_InitStruct.EXTI_Mode=EXTI_Mode_Interrupt;//模式有两种,分别是中断和事件,参数在stm32f10x_exti.h里面
	EXIT_InitStruct.EXTI_Trigger=EXTI_Trigger_Rising;//选择上升沿还是下降沿,参数在stm32f10x_exti.h里面
	EXIT_InitStruct.EXTI_LineCmd=ENABLE;//使能该线
	EXTI_Init(&EXIT_InitStruct);
}

exit的h文件:

#ifndef BSP_EXIT_H
#define BSP_EXIT_H

#include "stm32f10x.h"

#define KEY_GPIO_PIN    GPIO_Pin_0
#define KEY_GPIO_PORT   GPIOA
#define KEY_GPIOA_RCC   RCC_APB2Periph_GPIOA

#define KEY2_GPIO_PIN    GPIO_Pin_13
#define KEY2_GPIO_PORT   GPIOC
#define KEY2_GPIOC_RCC   RCC_APB2Periph_GPIOC

void EXIT0_GPIO_Config(void);
void EXIT13_GPIO_Config(void);

#endif /*BSP_EXIT_H*/

led函数和头文件

#include "bsp_led.h"

void LED_GPIO_Config(void)
{
	GPIO_InitTypeDef GPIO_InitStruct;
	
	GPIO_InitStruct.GPIO_Mode=GPIO_Mode_Out_PP;
	GPIO_InitStruct.GPIO_Pin=LED_GPIO_PIN;
	GPIO_InitStruct.GPIO_Speed=GPIO_Speed_50MHz;
	RCC_APB2PeriphClockCmd(LED_GPIOB_RCC,ENABLE);
	
	GPIO_Init(GPIOB, &GPIO_InitStruct);

}


h:
#ifndef _BSP_LED
#define _BSP_LED

#include "stm32f10x.h"

#define LED_GPIO_PIN    GPIO_Pin_0
#define LED_GPIO_PORT   GPIOB
#define LED_GPIOB_RCC   RCC_APB2Periph_GPIOB

#define ON  1
#define OFF 0

#define LED_G(a) if(a) GPIO_ResetBits(GPIOB,LED_GPIO_PIN);\
                 else GPIO_SetBits(GPIOB,LED_GPIO_PIN);
								 
#define LED_G_TOGGLE   {LED_GPIO_PORT->ODR^=GPIO_Pin_0;}

void LED_GPIO_Config(void);


#endif

主函数main

#include "stm32f10x.h"   //相当于51中的<reg52.h>
#include "bsp_led.h"
#include "bsp_exit.h"


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

int main(void)
{
	LED_GPIO_Config();
	EXIT0_GPIO_Config();
	EXIT13_GPIO_Config();
	while(1)
	{

	}

  
}

中断函数:

void EXTI0_IRQHandler(void)
{
	if(EXTI_GetITStatus(EXTI_Line0)!=RESET)//进入中断
	{
		LED_G_TOGGLE;
	}
	EXTI_ClearITPendingBit(EXTI_Line0);//清除中断标志,套路都这样
}

这样就可以按一下按键绿灯亮,再按一下就灭

 六、结束语

指南者中断的编程需要查看多个文件,不过其主要顺序还得看中断框图,然后根据框图顺序编程.

  • 0
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值