STM32中断

来源:互联网 发布:后藤基次 知乎 编辑:程序博客网 时间:2024/05/12 17:42

一、 用程序来解释STM32中断系统

             使用外部中断的步骤:

1,、设置好相应的时钟(打开相应GPIO的端口时钟,而且要打开复用功能)

2、设置好相应的中断(实质就是设置中断控制器NVIC,包括中断分组,通道,优先级)

3、I/O初始化(GPIO设置,包括模式,输出、输入,相应引脚)

4,、将相应的IO口设置成中断线路(要在设置外部中断之前)并初始化;(因为GPIO不是专用的中断引脚,所以在用GPIO来触发外部中断的时候需要设置将GPIO相应的引脚和中断线连接起来,具体代码如下,)

5、在选择的 中断通道的响应函数来写中断函数;(void EXTI9_5_IRQHandler(void)例如在这个中断函数里面写用户自己中断程序,比如我们要实现的功能就是要在进入中断函数的时候讲某个引脚置位

     假设有三个按键,用按键来触发相应的中断。K1/K2/K3连接的是PC5/PC2/PC3,因此我将用EXTI5/EXTI2/EXTI3三个外部中断。PB5/PD6/PD3分别连接了三个LED灯。中断的效果是按下按键,相应的LED灯将会被点亮。

1.       设置相应的时钟
     首先需要打开GPIOB、GPIOC和GPIOE(因为按键另外一端连接的是PE口)。然后由于是要用于触发中断,所以还需要打开GPIO复用的时钟。相应的函数在GPIO的学习笔记中有了详细了解释。详细代码如下:
void RCC_cfg()
{
       //打开PE PD PC PB端口时钟,并且打开复用时钟
       RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOE | RCC_APB2Periph_GPIOC | RCC_APB2Periph_GPIOD | RCC_APB2Periph_GPIOB | RCC_APB2Periph_AFIO, ENABLE);
}
    设置相应的时钟所需要的RCC函数在stm32f10x_rcc.c中,所以要在工程中添加此文件。
 
2.       设置好相应的中断
设置相应的中断实际上就是设置NVIC,在STM32的固件库中有一个结构体NVIC_InitTypeDef,里面有相应的标志位设置,然后再用NVIC_Init()函数进行初始化。详细代码如下:
void NVIC_cfg()
{
        NVIC_InitTypeDef NVIC_InitStructure;                                              //第一结构体
        NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);                          //选择中断分组2
        
        
NVIC_InitStructure.NVIC_IRQChannel = EXTI2_IRQChannel;     //选择中断通道2
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0; //抢占式中断优先级设置为0
        NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;        //响应式中断优先级设置为0
        NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;                                   //使能中断
        NVIC_Init(&NVIC_InitStructure);
 
        
        NVIC_InitStructure.NVIC_IRQChannel = EXTI3_IRQChannel;            //选择中断通道3
        NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1; //抢占式中断优先级设置为1
        NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;  //响应式中断优先级设置为1
        NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;                                   //使能中断
        NVIC_Init(&NVIC_InitStructure);
 
        
        NVIC_InitStructure.NVIC_IRQChannel = EXTI9_5_IRQChannel;  //选择中断通道5
        NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 2; //抢占式中断优先级设置为2
        NVIC_InitStructure.NVIC_IRQChannelSubPriority = 2;  //响应式中断优先级设置为2
        NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;                                   //使能中断
        NVIC_Init(&NVIC_InitStructure);
}
 
由于有3个中断,因此根据前文所述,需要有3个bit来指定抢占优先级,所以选择第2组。又由于EXTI5-9共用一个中断响应函数,所以EXTI5选择的中断通道是EXTI9_5_IRQChannel,详细信息可以在头文件中查询得到。用到的NVIC相关的库函数在stm32f10x_nivc.c中,需要将此文件复制并添加到工程中。具体位置可以查看关于GPIO的笔记。这段代码编译起来没有任何问题,但是在链接的时候就会报错,需要把STM32F10xR.LIB加入工程中,具体位置在…KeilARMRV31LIBSTSTM32F10xR.LIB。
 
3.       IO口初始化
void IO_cfg()
{
       GPIO_InitTypeDef GPIO_InitStructure;
 
      
       GPIO_InitStructure.GPIO_Pin = GPIO_Pin_2;                                             //选择引脚2
       GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;           //输出频率最大50MHz
      GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;                  //带上拉电阻输出
       GPIO_Init(GPIOE,&GPIO_InitStructure);
       GPIO_ResetBits(GPIOE,GPIO_Pin_2);                              //将PE.2引脚设置为低电平输出
 
      
       GPIO_InitStructure.GPIO_Pin = GPIO_Pin_2 | GPIO_Pin_3 | GPIO_Pin_5; //选择引脚2 3 5
       GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING; //选择输入模式为浮空输入
       GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;          //输出频率最大50MHz
       GPIO_Init(GPIOC,&GPIO_InitStructure);                                 //设置PC.2/PC.3/PC.5
      
      
       GPIO_InitStructure.GPIO_Pin = GPIO_Pin_3 | GPIO_Pin_6;                  //选择引脚3 6
       GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;           //输出频率最大50MHz
      GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;                  //带上拉电阻输出
       GPIO_Init(GPIOD,&GPIO_InitStructure);
      
      
       GPIO_InitStructure.GPIO_Pin = GPIO_Pin_5;                                         //选择引脚5
       GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;          //输出频率最大50MHz
      GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;                  //带上拉电阻输出
       GPIO_Init(GPIOB,&GPIO_InitStructure);        
}
其中连接外部中断的引脚需要设置为输入状态,而连接LED的引脚需要设置为输出状态,初始化PE.2是为了使得按键的另外一端输出低电平。GPIO中的函数在stm32f10x_gpio.c中。
 
4.       把相应的IO口设置为中断线路
由于GPIO并不是专用的中断引脚,因此在用GPIO来触发外部中断的时候需要设置将GPIO相应的引脚和中断线连接起来,具体代码如下:
void EXTI_cfg()
{
       EXTI_InitTypeDef EXTI_InitStructure;
       //清空中断标志
       EXTI_ClearITPendingBit(EXTI_Line2);
       EXTI_ClearITPendingBit(EXTI_Line3);
       EXTI_ClearITPendingBit(EXTI_Line5);
 
       //选择中断管脚PC.2 PC.3 PC.5
       GPIO_EXTILineConfig(GPIO_PortSourceGPIOC, GPIO_PinSource2);
       GPIO_EXTILineConfig(GPIO_PortSourceGPIOC, GPIO_PinSource3);
       GPIO_EXTILineConfig(GPIO_PortSourceGPIOC, GPIO_PinSource5);
 
       EXTI_InitStructure.EXTI_Line = EXTI_Line2 | EXTI_Line3 | EXTI_Line5; //选择中断线路2 3 5
       EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt; //设置为中断请求,非事件请求
       EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Rising_Falling; //设置中断触发方式为上下降沿触发
       EXTI_InitStructure.EXTI_LineCmd = ENABLE;                                          //外部中断使能
      EXTI_Init(&EXTI_InitStructure);
}
EXTI_cfg中需要调用到的函数都在stm32f10x_exti.c。
 
5.       写中断响应函数
STM32不像C51单片机那样,可以用过interrupt关键字来定义中断响应函数,STM32的中断响应函数接口存在中断向量表中,是由启动代码给出的。默认的中断响应函数在stm32f10x_it.c中。因此我们需要把这个文件加入到工程中来。
在这个文件中,我们发现,很多函数都是只有一个函数名,并没有函数体。我们找到EXTI2_IRQHandler()这个函数,这就是EXTI2中断响应的函数。我的目标是将LED灯点亮,所以函数体其实很简单:
void EXTI2_IRQHandler(void)
{
       //点亮LED灯
       GPIO_SetBits(GPIOD,GPIO_Pin_6);
       //清空中断标志位,防止持续进入中断
       EXTI_ClearITPendingBit(EXTI_Line2);
}
 
void EXTI3_IRQHandler(void)
{
       GPIO_SetBits(GPIOD,GPIO_Pin_3);
       EXTI_ClearITPendingBit(EXTI_Line3);
}
 
void EXTI9_5_IRQHandler(void)
{
       GPIO_SetBits(GPIOB,GPIO_Pin_5);
 
       EXTI_ClearITPendingBit(EXTI_Line5);
}
由于EXTI5-9是共用一个中断响应函数,因此所有的EXTI5 – EXTI9的响应函数都写在这个里面。
 
6.       写主函数
#include "stm32f10x_lib.h"
 
void RCC_cfg();
void IO_cfg();
void EXTI_cfg();
void NVIC_cfg();
 
int main()
{
          RCC_cfg();
          IO_cfg();
          NVIC_cfg();
          EXTI_cfg();
 
          while(1);            
}
 

 

 

阅读(15243)| 评论(3)
推荐转载
 
深入理解指针函数
 
单片机常用函数(滤波、字符处理等)
关闭
玩LOFTER,免费冲印20张照片,人人有奖!     我要抢>

评论

  登录后你可以发表评论,请先登录。登录>>
2014-01-06 20:41
路过
想问下STM32对外部中断滤波等级能设置吗

2014-11-08 18:42
路过 回复 路过

没有所谓的滤波的,ti的cm3系列就有。

2014-05-01 09:51
凡星
外部中断里面可不可以嵌套串口接收中断呢?
 
 
我的照片书 - 博客风格 - 手机博客 - 下载LOFTER APP - 订阅此博客

网易公司版权所有 ©1997-2016


0 0
原创粉丝点击