stm32学习笔记4(外部中断实验)

stm32的每个IO口都可以作为中断输入。要把IO口作为外部中断输入,有以下几个步骤:

1、初始化IO口为输入。(KEY_Init())

这一步设置要作为外部中断输入的IO口状态,可以设置为上拉/下拉输入,也可以设置为浮空输入,但浮空的时候外部一定要带上拉或下拉电阻。

2、开启IO口复用时钟,设置IO口与中断线的映射关系。(系统时钟设置:Stm32_Clock_Init(9))

需要配置外部中断配置寄存器EXTICR,先开启复用时钟,然后配置IO口与中断线的对应关系,才能把外部中断与中断线连接起来。

3、开启与该IO口相对的线上中断/事件,设置触发条件。(例:Ex_NVIC_Config(GPIO_A,0,RTIR))

注意:如果使用外部中断,并设置该中断的EMR位的话,会引起软件仿真不能跳到中断,而硬件上是可以的。建议不要配置EMR位。

4、配置中断分组(NVIC),并使能中断。(例:MY_NVIC_Init(2,2,EXTI0_IRQn,2))

5、编写中断服务函数。(外部中断为5~9的中断服务函数:void EXTI9_5_IRQHandler(void))

代码如下:

寄存器版本:

exit.h:                                         

#ifndef __EXITI_H

#define __EXITI_H

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

#endif

exit.c:

#include "exit.h"

#include "led.h"

#include "key.h"

#include "delay.h"

#include "usart.h"

void EXTI0_IRQHandler(void)                        //外部中断0服务程序

{    delay_ms(10) ;            //消抖

     if(WK_UP==1)

{       LED0=!LED0;    LED1=!LED1;}

EXTI->PR=1<<0;   //清除LINE0上的中断标志位

}

void EXTI9_5_IRQHandler(void)                        //外部中断9-5服务程序

{    delay_ms(10) ;            //消抖

     if(KEY0==0)

{       LED0=!LED0;  }

EXTI->PR=1<<5;   //清除LINE5上的中断标志位

}

void EXT15_10_IRQHandler(void)                        //外部中断15-10服务程序

{    delay_ms(10) ;            //消抖

     if(KEY1==0)

{       LED1=!LED1;}

EXTI->PR=1<<15   //清除LINE15的中断标志位

}

void EXTI_Init(void)        //外部中断初始化程序,初始化PA0,PC5,PA15为中断输入

{  KEY_Init();     //按键初始化

  Ex_NVIC_Config(GPIO_A,0,RTIR);       //上升沿触发

  Ex_NVIC_Config(GPIO_C,5,FTIR);       //下降沿触发

 Ex_NVIC_Config(GPIO_A,15,FTIR);

 MY_NVIC_Init(2,2,EXTI0_IRQn,2);              //抢占2,子优先级2,组2

MY_NVIC_Init(2,1,EXTI9_5_IRQn,2);          //抢占2,子优先级1,组2

MY_NVIC_Init(2,0,EXTI15_10_IRQn,2);     //抢占2,子优先级0,组2

}

main.c:

#include "sys.h"

#include "usart.h"

#include "delay.h"

#include "led.h"

#include "key.h"

#include "exti.h"

int main(void)

{   Stm32_Clock_Init(9);      //系统时钟设置

    delay_init(72);           // 延时初始化

    uart_init(729600);         // 串口初始化

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

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

  LED0=0;               //点亮LED

 while(1)

{   printf("OK\r\n");

    delay_ms(1000);

}

}

库函数版本:

exti.h:

#ifndef __EXTI_H
#define __EXIT_H     
#include "sys.h"
void EXTIX_Init(void);//IO口初始化                               
#endif

exti.c:

#include "exti.h"
#include "led.h"
#include "key.h"
#include "delay.h"
#include "usart.h"
void EXTIX_Init(void)
{
    EXTI_InitTypeDef EXTI_InitStrue;
NVIC_InitTypeDef  NVIC_InitStrue;
    KEY_Init();//按键初始化

  RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO,ENABLE);//时钟使能
    
    //GPIOC.5
    GPIO_EXTILineConfig(GPIO_PortSourceGPIOC,GPIO_PinSource5);//设置IO口与中断线的映射关系
    
    EXTI_InitStrue.EXTI_Line=EXTI_Line5;
    EXTI_InitStrue.EXTI_LineCmd=ENABLE;
    EXTI_InitStrue.EXTI_Mode=EXTI_Mode_Interrupt;
    EXTI_InitStrue.EXTI_Trigger=EXTI_Trigger_Falling;
    EXTI_Init(&EXTI_InitStrue);//初始化线上中断
    
    NVIC_InitStrue.NVIC_IRQChannel=EXTI9_5_IRQn;
    NVIC_InitStrue.NVIC_IRQChannelCmd=ENABLE;
    NVIC_InitStrue.NVIC_IRQChannelPreemptionPriority=2;
    NVIC_InitStrue.NVIC_IRQChannelSubPriority=1;
    NVIC_Init(&NVIC_InitStrue);//配置中断分组,并使能中断
    
//GPIOA.15    
    GPIO_EXTILineConfig(GPIO_PortSourceGPIOA,GPIO_PinSource15);    
    EXTI_InitStrue.EXTI_Line=EXTI_Line15;
    EXTI_InitStrue.EXTI_LineCmd=ENABLE;
    EXTI_InitStrue.EXTI_Mode=EXTI_Mode_Interrupt;
    EXTI_InitStrue.EXTI_Trigger=EXTI_Trigger_Falling;
    EXTI_Init(&EXTI_InitStrue);
    
    NVIC_InitStrue.NVIC_IRQChannel=EXTI15_10_IRQn;
    NVIC_InitStrue.NVIC_IRQChannelCmd=ENABLE;
    NVIC_InitStrue.NVIC_IRQChannelPreemptionPriority=2;
    NVIC_InitStrue.NVIC_IRQChannelSubPriority=1;
    NVIC_Init(&NVIC_InitStrue);
    
//GPIOA.0
  GPIO_EXTILineConfig(GPIO_PortSourceGPIOA,GPIO_PinSource0);
    
    EXTI_InitStrue.EXTI_Line=EXTI_Line0;
    EXTI_InitStrue.EXTI_LineCmd=ENABLE;
    EXTI_InitStrue.EXTI_Mode=EXTI_Mode_Interrupt;
    EXTI_InitStrue.EXTI_Trigger=EXTI_Trigger_Rising;
    EXTI_Init(&EXTI_InitStrue);
    
    NVIC_InitStrue.NVIC_IRQChannel=EXTI0_IRQn;
    NVIC_InitStrue.NVIC_IRQChannelCmd=ENABLE;
    NVIC_InitStrue.NVIC_IRQChannelPreemptionPriority=2;
    NVIC_InitStrue.NVIC_IRQChannelSubPriority=1;
    NVIC_Init(&NVIC_InitStrue);
}
void EXTI0_IRQHandler(void)//编写中断服务函数
{
  delay_ms(10);//消抖
    if(WK_UP==1)
    {
      LED0=!LED0;
      LED1=!LED1;
    }
  EXTI_ClearITPendingBit(EXTI_Line0);//清除标志位

}

void EXTI9_5_IRQHandler(void)
{
  delay_ms(10);
    if(KEY0==0)
    {
      LED0=!LED0;
    }
  EXTI_ClearITPendingBit(EXTI_Line0);

}

void EXTI15_10_IRQHandler(void)
{
  delay_ms(10);
    if(KEY1==0)
    {
      LED1=!LED1;
    }
  EXTI_ClearITPendingBit(EXTI_Line0);

}

main.c:

#include "led.h"
#include "delay.h"
#include "sys.h"
#include "key.h"
#include "usart.h"
#include "exti.h" 
 int main(void)
 {    
    delay_init();             //延时函数初始化 
    NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);// 设置中断优先级分组2
    uart_init(9600);     //串口波特率
    LED_Init();               //初始化与LED连接的硬件接口
     EXTIX_Init();        //外部中断初始化
  LED0=LED1=0;                //点亮LED
    while(1)
    {        
        printf("OK\n");    
        delay_ms(1000);      
    } 
}


 

你可能感兴趣的:(stm32)