STM32学习笔记一外部中断

发布者:美好回忆最新更新时间:2024-07-26 来源: elecfans关键字:STM32  学习笔记  外部中断 手机看文章 扫描二维码
随时随地手机看文章

1. STM32 外部中断简介

STM32 的每个 IO 都可以作为外部中断的中断输入口。STM32F103中断控制器支持 19 个外部中断/事件请求。每个中断设有状态位,每个中断/事件都有独立的触发和屏蔽设置。代码主要分布在固件库的 stm32f10x_exti.h 和 stm32f10x_exti.c 文件。

STM32F103的 19 个外部中断为:

1.jpg

触发方式:STM32 的外部中断是通过边沿来触发的,不支持电平触发。

2. 外部中断分组

STM32 的每一个 GPIO 都能配置成一个外部中断触发源,STM32 通过根据引脚的序号不同将众多中断触发源分成不同的组。

比如:PA0,PB0,PC0,PD0,PE0,PF0,PG0 为第一组。

依此类推,我们能得出一共有16 组,STM32 规定,每一组中同时只能有一个中断触发源工作,那么,最多工作的也就是16个外部中断。

图片

3. 使用 IO 口外部中断的配置步骤

3.1 初始化 IO 口为输入

设置作为外部中断输入的 IO 口的状态,可以设置为上拉 / 下拉输入 / 浮空输入,但浮空的时候外部一定要带上拉,或者下拉电阻。否则可能导致中断不停的触发。在干扰较大的地方,就算使用了内部上拉/下拉,也建议使用外部上拉/下拉电阻,这样可以一定程度防止外部干扰带来的影响。

3.2 开启 IO 口复用时钟,设置 IO 口与中断线的映射关系

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

3.3 开启与该IO口相对的线上中断/事件,设置触发条件

配置中断产生的条件,STM32 可以配置成上升沿触发,下降沿触发,或者任意电平变化触发,但是不能配置成高电平触发和低电平触发。同时要开启中断线上的中断。

注意:

如果使用外部中断,并设置该中断的 EMR 位的话,会引起软件仿真不能跳到中断,而硬件上是可以的。而不设置 EMR,软件仿真就可以进入中断服务函数,并且硬件上也是可以的。建议不要配置 EMR 位。

3.4 配置中断分组NVIC

配置中断的分组,以及使能,对 STM32 的中断来说,只有配置了 NVIC 的设置,并开启才能被执行,否则是不会执行到中断服务函数里面去的。

3.5 编写中断服务函数

这是中断设置的最后一步,中断服务函数,是必不可少的,如果在代码里面开启了中断,但是没编写中断服务函数,就可能引起硬件错误,从而导致程序崩溃!所以在开启了某个中断后,一定要记得为该中断编写服务函数。在中断服务函数里面编写你要执行的中断后的操作。


4. 例程分析

4.1 配置外部中断对应IO

//---------------------------------------------------------------------------------------------------------------------------------------------

//    函 数 名: exti_gpio_config

//    功能说明: 外部中断GPIO参数配置

//    形    参: 无

//    返 回 值: 无

//    日    期: 2020-04-25

//    备    注: 

//    作    者: by 霁风AI

//---------------------------------------------------------------------------------------------------------------------------------------------

static void exti_gpio_config(void)

{

    GPIO_InitTypeDef gpio_init_config;


     RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);//使能PORTA时钟


    gpio_init_config.GPIO_Pin       = GPIO_Pin_0;//PA0

    gpio_init_config.GPIO_Mode      = GPIO_Mode_IPD; //PA0设置成输入,默认下拉      

    GPIO_Init(GPIOA, &gpio_init_config);//初始化GPIOA.0

}

4.2 配置外部中断参数

//---------------------------------------------------------------------------------------------------------------------------------------------

//    函 数 名: exti_config

//    功能说明: 外部中断参数配置

//    形    参: 无

//    返 回 值: 无

//    日    期: 2020-04-25

//    备    注: 

//    作    者: by 霁风AI

//---------------------------------------------------------------------------------------------------------------------------------------------

static void exti_config(void)

{

    EXTI_InitTypeDef exti_init_config;


    RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO, ENABLE);    //外部中断,需要使能AFIO时钟


    GPIO_EXTILineConfig(GPIO_PortSourceGPIOA, GPIO_PinSource0); //PA0设置为外部中断


      exti_init_config.EXTI_Line      = EXTI_Line0;

      exti_init_config.EXTI_Mode      = EXTI_Mode_Interrupt;  

      exti_init_config.EXTI_Trigger   = EXTI_Trigger_Rising;//上升沿触发

      exti_init_config.EXTI_LineCmd   = ENABLE;


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

}

4.3 配置中断向量

//---------------------------------------------------------------------------------------------------------------------------------------------

//    函 数 名: exit_nvic_config

//    功能说明: 中断向量参数配置

//    形    参: 无

//    返 回 值: 无

//    日    期: 2020-04-25

//    备    注: 

//    作    者: by 霁风AI

//---------------------------------------------------------------------------------------------------------------------------------------------

static void exti_nvic_config(void)

{

    NVIC_InitTypeDef nvic_init_config;


    nvic_init_config.NVIC_IRQChannel                    = EXTI0_IRQn;//使能按键所在的外部中断通道

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

    nvic_init_config.NVIC_IRQChannelSubPriority         = 0x02;//子优先级1

    nvic_init_config.NVIC_IRQChannelCmd                 = ENABLE;


    NVIC_Init(&nvic_init_config);

}

4.4 统一外部中断调用接口

//---------------------------------------------------------------------------------------------------------------------------------------------

//    函 数 名: exti_init

//    功能说明: 外部中断初始化

//    形    参:     exti_no:中断号

//    返 回 值: 无

//    日    期: 2020-04-25

//    备    注: 外部调用此函数,实现EXTI的初始化配置

//    作    者: by 霁风AI

//---------------------------------------------------------------------------------------------------------------------------------------------

void exti_init(uint8_t exti_no)

{

    if (exti_no == 0)

    {

        exti_gpio_config();

        exti_config();

        exti_nvic_config();

    }

}

4.5 编写中断服务函数

//---------------------------------------------------------------------------------------------------------------------------------------------

//    函 数 名: EXTI0_IRQHandler

//    功能说明: 外部中断0服务函数

//    形    参: 无

//    返 回 值: 无

//    日    期: 2020-04-25

//    备    注: 

//    作    者: by 霁风AI

//---------------------------------------------------------------------------------------------------------------------------------------------

void EXTI0_IRQHandler(void)

{

    if (EXTI_GetITStatus(EXTI_Line0) != RESET)  

    {

        g_exti_cnt++;


        if (g_exti_cnt % 2)

        {

            Bsp_LedOn(0);   //点亮OLED0

        }

        else 

        {

            Bsp_LedOff(0);  //熄灭OLED0

        }


        if (g_exti_cnt > 200)

        {

            g_exti_cnt = 0;

        }


        EXTI_ClearITPendingBit(EXTI_Line0); //清除EXTI0线路挂起

    }

}

补充:


在编写中断服务函数的时候会经常使用到两个函数。


(1)第一个函数是判断某个中断线上的中断是否发生(标志位是否置位):


ITStatus EXTI_GetITStatus(uint32_t EXTI_Line);

这个函数一般使用在中断服务函数的开头判断中断是否发生。


(2)第二个是清除某个中断线上的中断标志位:


复制

void EXTI_ClearITPendingBit(uint32_t EXTI_Line);

这个函数一般应用在中断服务函数结束之前,清除中断标志位。


关键字:STM32  学习笔记  外部中断 引用地址:STM32学习笔记一外部中断

上一篇:STM32单片机简介
下一篇:STM32WB55_NUCLEO开发(6)----手机与STM32WB通过配对后进行数值比较

推荐阅读最新更新时间:2024-11-11 10:27

MSP430F5438 ADC12学习笔记
1.前言 这几天实践了MSP430的ADC12功能,虽然片内AD功能比较简单但是还学出了点“门道”来,这个“门道”便是MSP430F5438A和MSP430F5438的区别。这里通过一个例子说明片内ADC的使用,首先实现UART和定时器1S溢出的功能,在上述功能的基础上每1S打印一次AD转换结果,转换通道定向到通道11,该通道对应AVCC和AVSS插值的一半,由于AVCC和LDO的输出之间只有一个电感连接,可以理解转换的结果为LDO输出电压的一般,若扩大两倍便是LDO的实际输出结果,在本文所用的开发板LDO输出为3.3V,所有打印的结果越接近3.3V越好。 2.代码实现和输出结果 代码实现 // 时钟默认情况 // FLL时钟
[单片机]
MSP430F5438 ADC12<font color='red'>学习</font><font color='red'>笔记</font>
MSP430学习笔记-IO端口
端口控制寄存器 PxDIR 输入/输出方向寄存器 PxIN 输入寄存器 PxOUT 输出寄存器 PxSEL 引脚功能选择寄存器 PxIFG 中断标志寄存器 PxIE 中断允许寄存器 PxIES 中断触发沿控制寄存器 1 5、6、7为P1、P2特有
[单片机]
STM32之限位开关
一、简介 本文介绍如何在STM32上使用限位开关。 二、实验平台 库版本:STM32F10x_StdPeriph_Lib_V3.5.0 编译软件:MDK4.53 硬件平台:STM32开发板(主芯片stm32f103c8t6) 仿真器:JLINK 三、版权声明 四、实验前提 在进行本文步骤前,请先阅读并实现以下博文: 1、《STM32之NVIC》:http://blog.csdn.net/feilusia/article/details/52819709 五、基础知识 1、限位开关是什么? 答:限位开关其实就是会复原开关的开关按键。 也就是说按下限位开关的开关能触发STM32的IO
[单片机]
<font color='red'>STM32</font>之限位开关
51单片机学习笔记———12.1模拟法用于串口通信
通信无非就是两种 加上两种方式: 发送 接收 单片机与电脑通讯原理图: 当我们的单片机向电脑发送数据时,并不是一下子全部发完,而是根据字节数一位一位的发送,每发送一位数据就需要一定的时间,发送两位数据相隔的时间就是通讯的波特率倒数,而一般波特率都非常高,所以发送的时间非常短,所以当单片机要发送数据时,肯定要用到P3.1引脚的TXD。 所以一开始TXD 为高电平 然后变为低电平 并且延时一小段时间 然后开始按位发送数据 每发送一次延时相应时间 然后开始发送下一位 直到八位全部发送完毕 直观图如下: 代码如下: void main() { while(1) { UART_Send_Char(&
[单片机]
51单片机<font color='red'>学习</font><font color='red'>笔记</font>———12.1模拟法用于串口通信
外部中断的理解
使用 IO 口外部中断的一般步骤: 1)初始化 IO 口为输入。 2)开启 IO 口复用时钟,设置 IO 口与中断线的映射关系。 3)初始化线上中断,设置触发条件等。 4)配置中断分组(NVIC),并使能中断。 5)编写中断服务函数。 //初始化 EXTI_InitTypeDef EXTI_InitStructure; NVIC_InitTypeDef NVIC_InitStructure; //开启复用时钟 RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO,ENABLE); //外部中断,需要使能 AFIO 时钟 KEY_Init();//初始化按键对应 io 模式 //初始化线上
[单片机]
<font color='red'>外部中断</font>的理解
STM32 ADC应用中信号源特性对转换结果的影响
STM32家族中的所有芯片都内置了逐次逼近寄存器型ADC模块.内部大致框架如下: 每次ADC转换先进行采样保持,然后分多步执行比较输出,步数等于ADC的位数,每个ADC时钟产生一个数据位。说到这里,用过STM32 ADC的人是不是想到了参考手册中关于12位ADC转换时间的公式: ST官方就如何保障或改善ADC精度写了一篇应用笔记AN2834。该应用笔记旨在帮助用户了解ADC误差的产生以及如何提高ADC的精度。主要介绍了与ADC设计的相关内容,比如外部硬件设计参数,不同类型的ADC误差来源分析等,并提出了一些如何减小误差的设计上建议。 这里我摘取部分内容,结合个人的理解加以整理与大家分享。更多细节可以去www.s
[单片机]
<font color='red'>STM32</font> ADC应用中信号源特性对转换结果的影响
基于STM32F407的FreeRTOS学习笔记(4)
CPU工作的时候,各个任务运行会占用CPU的资源,在Windows系统中我们可以通过任务管理器来看各任务(进程)占用系统资源的情况。 那么,FreeRTOS怎么实现这个功能呢? 我们翻阅FreeRTOS官网,查询API文档,在内核控制函数部分找到了相关的函数。 文档指出实现运行时间功能需要配置外设定时器,即32板载定时器,计时器频率应为滴答计时器(1ms)的至少10倍。 传入参数为pcWriteBUffer,其实是一个char类型的数组用以存储相关信息。 我们现在工程上调用这个函数。 char informationbuff ; void Get_info(void * pvParameters) {
[单片机]
基于STM32F407的FreeRTOS<font color='red'>学习</font><font color='red'>笔记</font>(4)
stm32之DMA研究
在做实验之前,首先必须明白什么是DMA,DMA的作用又体现在哪里。 DMA,即直接内存存储,在一些数据的传输中,采用DMA方式,从而将CPU解放出来。让CPU有足够的时间处理其他的事情。 stm32使用DMA的相关操作: 1、DMA的配置 要配置的有DMA传输通道选择,传输的成员和方向、普通模式还是循环模式等等。 void DMA_Configuration(void) { DMA_InitTypeDef DMA_InitStructure; //DMA设置: //设置DMA源:内存地址&串口数据寄存器地址 //方向:内存-- 外设 //每次传输位:8bit //传输大小DMA_BufferSize=SEN
[单片机]
小广播
设计资源 培训 开发板 精华推荐

最新单片机文章
何立民专栏 单片机及嵌入式宝典

北京航空航天大学教授,20余年来致力于单片机与嵌入式系统推广工作。

 
EEWorld订阅号

 
EEWorld服务号

 
汽车开发圈

电子工程世界版权所有 京ICP证060456号 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2024 EEWORLD.com.cn, Inc. All rights reserved