STM32外部中断

我是研究僧i 提交于 2020-01-12 21:30:46

STM32外部中断

  • STM32有19个外部中断:线0-15对应外部IO口的输入中断;线16连接PVD输出;线17连接RTC闹钟事件;线18连接USB唤醒事件。
  • GPIO与中断线的映射关系:GPIOx.0映射到EXTI0,GPIOx.1映射到EXTI1;以此类推。
  • 使用外部中断需要使能AFIO时钟:RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO,ENABLE);
  • 还要设置IO口与中断线的映射关系:(例)GPIO_EXTILineConfig(GPIO_PortSourceGPIOC,GPIO_PinSource5);
  • 然后设置中断的触发模式等初始参数
  • 然后设置NVIC中断优先级
  • 设置完中断优先级后就是编写中断服务函数,STM32的IO口外部中断函数只有6个,中断线0-4分别对应一个中断服务函数,中断线5-9共用一个,10-15公用一个,如图:
  • 注意:设置中断优先级分组需要在主函数中调用相关函数设置,一定要记住初始化函数(初始化延时、按键、LED)
  • 在这里插入图片描述
  • 在编写完中断服务函数之后要清楚中断标志位,如图:在这里插入图片描述

外部中断函数

#include "exti.h"//exti.c文件
#include "led.h"
#include "key.h"
#include "delay.h"
#include "usart.h"
 
//外部中断初始化函数
void EXTIX_Init(void)
{
    EXTI_InitTypeDef EXTI_InitStructure1;//中断初始化结构体
    NVIC_InitTypeDef NVIC_InitStructure1;//中断优先级初始化结构体
	KEY_Init();//初始化按键
  	RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO,ENABLE);//使能AFIO时钟
  	GPIO_EXTILineConfig(GPIO_PortSourceGPIOC,GPIO_PinSource5);//设置I口与中断线的映射关系

  	EXTI_InitStructure1.EXTI_Line = EXTI_Line5;//设置5号中断线
  	EXTI_InitStructure1.EXTI_Mode = EXTI_Mode_Interrupt;//设置中断模式
  	EXTI_InitStructure1.EXTI_Trigger = EXTI_Trigger_Falling;//设置为下降沿触发
  	EXTI_InitStructure1.EXTI_LineCmd = ENABLE;//使能
  	EXTI_Init(&EXTI_InitStructure1);//初始化中断
	
	NVIC_InitStructure1.NVIC_IRQChannel = EXTI9_5_IRQn;//使能按键外部中断通道
  	NVIC_InitStructure1.NVIC_IRQChannelPreemptionPriority = 0x02;	//抢占优先级2
  	NVIC_InitStructure1.NVIC_IRQChannelSubPriority = 0x01;//子优先级1
  	NVIC_InitStructure1.NVIC_IRQChannelCmd = ENABLE;
  	NVIC_Init(&NVIC_InitStructure1);//初始化中断优先级
}
void EXTI9_5_IRQHandler(void)//中断服务函数
{			
		delay_ms(10);//消按键抖动
		if(KEY0 == 0){
			LED1 = !LED1;
			LED0 = !LED0;
		}
 	  EXTI_ClearITPendingBit(EXTI_Line5);//清楚中断标置位
}

#ifndef __EXTI_H//exti.h文件
#define __EXTI_H	 
#include "sys.h"

void EXTIX_Init(void);//IO³õʼ»¯

#endif


LED初始化

#include "led2.h"//led.c文件
#include "stm32f10x.h"
void Init_LED(void)
{
	GPIO_InitTypeDef str;
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE);//使能GPIOA
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOD,ENABLE);//使能GPIOD
	
    str.GPIO_Mode = GPIO_Mode_Out_PP;//设置输出模式
  	str.GPIO_Pin = GPIO_Pin_2;//设置引脚编号
  	str.GPIO_Speed = GPIO_Speed_50MHz;//设置翻转速度
	GPIO_Init(GPIOD,&str);//初始化PD2引脚
	GPIO_SetBits(GPIOD,GPIO_Pin_2);//将PD2引脚设置为高电平
	
	str.GPIO_Mode = GPIO_Mode_Out_PP;
  	str.GPIO_Pin = GPIO_Pin_8;
  	str.GPIO_Speed = GPIO_Speed_50MHz;
	GPIO_Init(GPIOA,&str);
    GPIO_SetBits(GPIOA,GPIO_Pin_8);
}


#ifndef __LED_H//led.h文件
#define __LED_H
#include "sys.h"
#define LED0 PAout(8)	// PA8,设置PA8引脚的电平状态0和1
#define LED1 PDout(2)	// PD2
void Init_LED(void);
#endif


按键初始化

#include "key.h"//key.c文件
#include "delay.h"

void KEY_Init(void)
{
	
	GPIO_InitTypeDef GPIO_InitStructure;

 	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA|RCC_APB2Periph_GPIOC,ENABLE);//使能GPIOA和GPIOC

	GPIO_PinRemapConfig(GPIO_Remap_SWJ_JTAGDisable, ENABLE);//
	
	GPIO_InitStructure.GPIO_Pin  = GPIO_Pin_15;
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;
 	GPIO_Init(GPIOA, &GPIO_InitStructure);
	
	GPIO_InitStructure.GPIO_Pin  = GPIO_Pin_5;
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;
 	GPIO_Init(GPIOC, &GPIO_InitStructure);
 
	GPIO_InitStructure.GPIO_Pin  = GPIO_Pin_0;
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPD;
	GPIO_Init(GPIOA, &GPIO_InitStructure);
	
}
u8 KEY_Scan(u8 mode)
{	 
	static u8 key_up=1;
	if(mode)key_up=1;  
	if(key_up&&(KEY0==0||KEY1==0||WK_UP==1))
	{
		delay_ms(10);
		key_up=0;
		if(KEY0==0)return KEY0_PRES;
		else if(KEY1==0)return KEY1_PRES;
		else if(WK_UP==1)return WKUP_PRES; 
	}else if(KEY0==1&&KEY1==1&&WK_UP==0)key_up=1; 	     
	return 0;
}

#ifndef __KEY_H//key/h文件
#define __KEY_H	 
#include "sys.h"

#define KEY0 PCin(5)   	
#define KEY1 PAin(15)	 
#define WK_UP  PAin(0)	 
 

//#define KEY0  GPIO_ReadInputDataBit(GPIOC,GPIO_Pin_5)//
//#define KEY1  GPIO_ReadInputDataBit(GPIOA,GPIO_Pin_15)//
//#define WK_UP GPIO_ReadInputDataBit(GPIOA,GPIO_Pin_0)//
 

#define KEY0_PRES	1		//KEY0  
#define KEY1_PRES	2		//KEY1 
#define WKUP_PRES	3		//WK_UP  

void KEY_Init(void);
u8 KEY_Scan(u8 mode);			    
#endif

主函数

#include "led.h"//main.c文件
#include "delay.h"
#include "sys.h"
#include "key.h"
#include "usart.h"
#include "exti.h" 
int main(void)
{	
	NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);//设置中断优先级分组位2组
	LED_Init();
	KEY_Init();
	delay_init();
	EXTIX_Init();
    LED0=LED1=0;
	while(1)//死循环让程序一直能检测到中断
	{
		
	} 
}



易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!