您的位置:首页 > 其它

外部中断实验

2017-10-09 15:19 423 查看
外部中断实验
STM32F103 的中断控制器支持 19 个外部中断/事件请求。每个中断设有状态位,每个中断/事件都有独立的触发和屏蔽设置。 STM32F103 的19 个外部中断为:
线 0~15:对应外部 IO 口的输入中断。
线 16:连接到 PVD 输出。
线 17:连接到 RTC 闹钟事件。
线 18:连接到 USB 唤醒事件。
STM32 供 IO 口使用的中断线只有 16 个,GPIO口不止16个。 于是 STM32 就这样设计, GPIO 的管脚GPIOx.0~GPIOx.15(x=A,B,C,D,E, F,G)分别对应中断线 15~0。这样每个中断线对应了最多 7 个 IO 口,形成映射关系。以线 0 为例:它对应了
GPIOA.0、 GPIOB.0、 GPIOC.0、 GPIOD.0、
GPIOE.0、 GPIOF.0、 GPIOG.0。而中断线每次只能连接到 1 个 IO 口上,这样就需要通过配置来
决定对应的中断线配置到哪个 GPIO 上了。
决定对应的中断线配置到哪个 GPIO 上了。 下面我们看看 GPIO 跟中断线的映射关系图:

根据映射关系,就开始配置按键对应GPIO口和中断的映射了:

外部中断的步骤:
1:初始化 IO 口为输入。
2:开启 IO 口复用时钟,设置 IO 口与中断线的映射关系。
 函数为void GPIO_EXTILineConfig(uint8_t GPIO_PortSource, uint8_t GPIO_PinSource)
3:IO与中断线映射,中断线上中断的初始化,设置触发条件等。
 函数为:void EXTI_Init(EXTI_InitTypeDef* EXTI_InitStruct);
 EXTI_InitTypeDef 的成员变量:
 typedef struct
 { uint32_t  EXTI_Line; (中断线的标号,取值范围为EXTI_Line0~EXTI_Line15)

EXTIMode_TypeDef  EXTI_Mode;(中断模式 EXTI_Mode_Interrupt,EXTI_Mode_Event)

EXTITrigger_TypeDef  EXTI_Trigger;触发方式EXTI_Trigger_Falling,EXTI_Trigger_Rising

FunctionalState  EXTI_LineCmd;(使能中断线)
 }EXTI_InitTypeDef
4:配置中断分组(NVIC),并使能中断。

typedef struct

{uint8_t NVIC_IRQChannel;//定义初始化的是哪个中断

uint8_t NVIC_IRQChannelPreemptionPriority;//定义这个中断的抢占优先级别

uint8_t NVIC_IRQChannelSubPriority;//定义这个中断的子优先级别。

FunctionalState NVIC_IRQChannelCmd;//该中断是否使能。

} NVIC_InitTypeDef;

5:编写中断服务函数,STM32 的 IO 口外部中断函数只有 6 个,分别为:

EXPORT EXTI0_IRQHandler

EXPORT EXTI1_IRQHandler

EXPORT EXTI2_IRQHandler

EXPORT EXTI3_IRQHandler

EXPORT EXTI4_IRQHandler

EXPORT EXTI9_5_IRQHandler

EXPORT EXTI15_10_IRQHandler
 中断线 0-4 每个中断线对应一个中断函数, 中断线 5-9 共用中断函数 EXTI9_5_IRQHandler,中
 断线 10-15 共用中断函数 EXTI15_10_IRQHandler。
判断某个中断线上的中断是否发生:ITStatus EXTI_GetITStatus(uint32_t EXTI_Line);
清除某个中断线上的中断标志位:void EXTI_ClearITPendingBit(uint32_t EXTI_Line);
中断服务函数格式:
void EXTI2_IRQHandler(void)
{
if(EXTI_GetITStatus(EXTI_Line3)!=RESET)//判断某个线上的中断是否发生
{

中断逻辑…

EXTI_ClearITPendingBit(EXTI_Line3); //清除 LINE 上的中断标志位
}}

exit.c

<pre name="code" class="csharp"><pre name="code" class="html">void EXTIX_Init(void)  

{  

   

    EXTI_InitTypeDef EXTI_InitStructure;  

    NVIC_InitTypeDef NVIC_InitStructure;  

  

    KEY_Init();  // 按键端口初始化 IO设置为输入 

  

    RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO,ENABLE); //使能复用功能时钟  
  

  //GPIOE.2 中断线以及中断初始化配置   下降沿触发  

    GPIO_EXTILineConfig(GPIO_PortSourceGPIOE,GPIO_PinSource2);//GPIO端口与中断线映射起来    

    EXTI_InitStructure.EXTI_Line=EXTI_Line2;    //KEY2  

    EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt;   

    EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Falling;  

    EXTI_InitStructure.EXTI_LineCmd = ENABLE;  

    EXTI_Init(&EXTI_InitStructure);//根据EXTI_InitStruct中指定的参数初始化外设EXTI寄存器  

  

 //GPIOE.3    中断线以及中断初始化配置 下降沿触发 //KEY1  

    GPIO_EXTILineConfig(GPIO_PortSourceGPIOE,GPIO_PinSource3);  

    EXTI_InitStructure.EXTI_Line=EXTI_Line3;  

    EXTI_Init(&EXTI_InitStructure);//根据EXTI_InitStruct中指定的参数初始化外设EXTI寄存器  

  

 //GPIOE.4    中断线以及中断初始化配置  下降沿触发   //KEY0  

    GPIO_EXTILineConfig(GPIO_PortSourceGPIOE,GPIO_PinSource4);  

    EXTI_InitStructure.EXTI_Line=EXTI_Line4;  

    EXTI_Init(&EXTI_InitStructure);//根据EXTI_InitStruct中指定的参数初始化外设EXTI寄存器  

  

  

  //GPIOA.0   中断线以及中断初始化配置 上升沿触发 PA0  WK_UP  

    GPIO_EXTILineConfig(GPIO_PortSourceGPIOA,GPIO_PinSource0);   

  

    EXTI_InitStructure.EXTI_Line=EXTI_Line0;  

    EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Rising;  

    EXTI_Init(&EXTI_InitStructure);//根据EXTI_InitStruct中指定的参数初始化外设EXTI寄存器  

  

  

    NVIC_InitStructure.NVIC_IRQChannel = EXTI0_IRQn;//使能按键WK_UP的外部中断通道  

    NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0x02; //抢占优先级2,  

    NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0x03;    //子优先级3  

    NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;   //使能外部中断通道  

    NVIC_Init(&NVIC_InitStructure);   

  

    NVIC_InitStructure.NVIC_IRQChannel = EXTI2_IRQn;//使能按键KEY2在的外部中断通道  

    NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0x02;//抢占优先级2,   

    NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0x02;  //子优先级2  

    NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;  //使能外部中断通道  

    NVIC_Init(&NVIC_InitStructure);  

  

  

    NVIC_InitStructure.NVIC_IRQChannel = EXTI3_IRQn;//使能按键KEY1在的外部中断通道  

    NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0x02;//抢占优先级2   

    NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0x01;  //子优先级1   

    NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;     //使能外部中断通道  

    NVIC_Init(&NVIC_InitStructure);//根据NVIC_InitStruct中指定的参数初始化外设NVIC寄存器  

    NVIC_InitStructure.NVIC_IRQChannel = EXTI4_IRQn;//使能按键KEY0在的外部中断通道  

    NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0x02;//抢占优先级2   

    NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0x00;  //子优先级0   

    NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;  //使能外部中断通道  

    NVIC_Init(&NVIC_InitStructure);//根据NVIC_InitStruct中指定的参数初始化外设NVIC寄存器     

}  

  

//外部中断0服务程序   

void EXTI0_IRQHandler(void)  

{  

    delay_ms(10);//消抖  

    if(KEY3==1)  //WK_UP按键  

    {                  

        BEEP=!BEEP;   

    }  

    EXTI_ClearITPendingBit(EXTI_Line0); //清除LINE0上的中断标志位    

}  

   

//外部中断2服务程序  

void EXTI2_IRQHandler(void)  

{  

    delay_ms(10);//消抖  

    if(KEY2==0)   //按键KEY2  

    {  

        LED0=!LED0;  

    }          

    EXTI_ClearITPendingBit(EXTI_Line2);  //清除LINE2上的中断标志位    

}  

//外部中断3服务程序  

void EXTI3_IRQHandler(void)  

{  

    delay_ms(10);//消抖  

    if(KEY1==0)  //按键KEY1  

    {                  

        LED1=!LED1;  

    }          

    EXTI_ClearITPendingBit(EXTI_Line3);  //清除LINE3上的中断标志位    

}  

  

void EXTI4_IRQHandler(void)  

{  

    delay_ms(10);//消抖  

    if(KEY0==0)  //按键KEY0  

    {  

        LED0=!LED0;  

        LED1=!LED1;   

    }          

    EXTI_ClearITPendingBit(EXTI_Line4);  //清除LINE4上的中断标志位    

}  
exit.h

#ifndef __EXTI_H

#define __EXIT_H

#include "sys.h"   

void EXTIX_Init(void);//外部中断初始化

#endif  

main.c 

#include "led.h"

#include "delay.h"

#include "key.h"

#include "sys.h"

#include "usart.h"

#include "exti.h"

#include "beep.h" 

#include "led.h"

#include "delay.h"

#include "key.h"

#include "sys.h"

#include "usart.h"

#include "exti.h"

#include "beep.h"  

int main(void)

{

delay_init(); //延时函数初始化

NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2); //设置NVIC中断分组2:2位抢占优先级,2位响应优先级

uart_init(115200); //串口初始化为115200

LED_Init(); //初始化与LED连接的硬件接口

BEEP_Init(); //初始化蜂鸣器端口

KEY_Init(); //初始化与按键连接的硬件接口

EXTIX_Init(); //外部中断初始化

LED0=0; //点亮LED0

while(1)

{

printf("OK\r\n");

delay_ms(1000);

}

}   
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: