STM32 中断初识

发布者:神光骑士最新更新时间:2018-05-30 来源: eefocus关键字:STM32  中断初识 手机看文章 扫描二维码
随时随地手机看文章

前段时间经常用stm32f4 discovery,但是因为对NVIC , EXTI不是很了解,所以使用的过程中一直都在避免使用中断,这两天没什么事决定来学习一下stm32 的中断,写一下自己的心得,如有谬误之处,欢迎指正。 

我把用到的几份文档寄存器的文档(RM0090)、《Cortex-M技术参考手册》、《Cortex™-M4 Devices Generic User Guide》、《ARMv7-M Architecture Reference Manual》放在百度云,需要的自取http://pan.baidu.com/s/1hq4L328 密码:4g91


关于与NVIC和EXTI有关的寄存器


先说EXTI吧, 

EXTI 控制器的主要特性如下: 

● 每个中断/事件线上都具有独立的触发和屏蔽 

● 每个中断线都具有专用的状态位 

● 支持多达 23 个软件事件/中断请求 

● 检测脉冲宽度低于 APB2 时钟宽度的外部信号。 

(摘自介绍寄存器的文档(RM0090)) 

在RM0090的241页有这样的介绍:


这里写图片描述

从图中看出和外部中断有关的寄存器有:上升沿触发选择、下降沿触发选择、软件中断事件寄存器、中断屏蔽寄存器、挂起请求寄存器、事件屏蔽寄存器和NVIC中断控制寄存器等。此外就是对输入线的理解了。 

在243页有对输入线如下描述:


这里写图片描述

也就是说对于一个外部中断线可以和多个stm32的GPIO相连,当你要使用哪一个IO的时候只要对SYSCFG_EXTICR对应的位设置就好了,在中断屏蔽寄存器或事件屏蔽寄存器对应位可以设置使用哪一个中断线。这三个寄存器截图如下:(分别在页码:196~198、244、244)

这里写图片描述


其中SYSCFG_EXTICR有SYSCFG_EXTICR1~SYSCFG_EXTICR4共4组设置16个线。 

在以上2个寄存器都设置好后可以设置时钟的触发沿了,配置下面两个寄存器:(在246页)

这里写图片描述


在上面的EXTI寄存器都设置好后就可以设置NVIC了,关于NVIC的描述在RM0090中描述较少,但是说了“更多关于异常和 NVIC 编程的说明, 请参考《ARM Cortex™-M4F 技术参考手册》中的第 5 章:异常和第 8 章:嵌套向量中断控 制器。”在网上搜了一下,没找到《ARM Cortex™-M4F 技术参考手册》名字一模一样的资料。但是我找到了个这样的资料《Cortex-M技术参考手册》,在64页找到了一个这样的寄存器描述:

这里写图片描述 

图片下面说其他寄存器在ARMv7-M Architecture Reference Manual中有描述,实际上我去官网也下了,但是没找到什么有用信息(也许有但我这英语渣是没找到)。但是在官网找到了一份这个文档DUI0553A_cortex_m4_dgug.pdf,打开一看,它就是Cortex™-M4 Devices Generic User Guide。在4.2节找到了描述NVIC的部分。在这部分分别描述了ISER(中断使能寄存器)、ICER(中断除能寄存器)、ISPR(中断挂起寄存器)、ICPR(中断解挂寄存器)、IABR(中断激活标志寄存器)、IPR(中断优先级分组寄存器)、STIR(软件触发中断寄存器)的描述。这些寄存器除了STIR外都是7个一组,共有240个位可设置,这些寄存器每一位都对应于一个中断向量表中的一个位置,中断向量表可以在RM0090的234页找到。在IAR里测试的时候没有IPR这个寄存器,查看NVIC的结构体发现寄存器名字是IP。看了下网上有些人写IPR,有些人写IP,不过可以自己看一下自己的NVIC结构体。 

此外就是关于优先级分组设置,在System control block的AIRCR寄存器中设置

这里写图片描述


AIRCR寄存器为异常模式提供优先级分组的控制。在最下面还说了,如果你想要写这个寄存器,你就要在VECTKEY区域写入0x5fa,用的时候可别忘了,下面是AIRCR的位说明。


这里写图片描述


寄存器查的差不多了,总结一下设置的步骤: 

1.设置优先级分组,使用寄存器:SCB->AIRCR 。 

2.设置中断优先级(抢占优先级和响应优先级),设置中断使能,使用寄存器:NVIC->IP[0]~IP[7]和NVIC->ISER[0]~ISER[7]。到这里NVIC设置好了。 

3.配置外部中断的源输入,使用寄存器SYSCFG->EXTICR[1]-EXTICR[4]。 

4.使能外部中断输入线,使用寄存器EXTI->IMR。 

5.配置外部中断触发方式,使用寄存器EXTI->RTSR或FTSR。


下面是我用stm32f4-discovery的测试程序:


/******************************

*       NVIC寄存器了解

*       2015\9\12

*       code by:dancetorhythm

******************************/

#include "stm32f4xx.h"

#include "misc.h"

#include "stm32f4xx_exti.h"

unsigned int timingdelay=0;

void delay(unsigned int );

void ledInit();

void EXTI1Config();//寄存器设置

void EXTI2Config();//使用固件库接口设置

void main(){

  //SysTick_Config(SystemCoreClock/1000);

  ledInit();

  EXTI1Config();

  //EXTI2Config();

  GPIOA->MODER&=0xfffffffc;     //PA0输入模式,无上拉下拉

  GPIOA->PUPDR&=0xfffffffc;  

  while(1){

    //add your code   

  }

}

void delay(unsigned int ntime){

  timingdelay=ntime;

  while(timingdelay);

}

void EXTI1Config(){

  SCB->AIRCR=0x05af0000|0x4000;//抢占优先级3位,响应优先级1位

  NVIC->IP[6]=0xe0;           //抢占优先级8,响应优先级0

  NVIC->ISER[0]|=(1<<6);      //中断使能


  EXTI->IMR|=(1<<0);    //开放来自0线的中断请求

  EXTI->FTSR|=(1<<0);   //设置0线下降沿触发


  SYSCFG->EXTICR[1]&=0xffffff00;//配置中断线0到PA0


}

void EXTI2Config(){

  NVIC_InitTypeDef NVIC_InitStruct;

  NVIC_PriorityGroupConfig(NVIC_PriorityGroup_3); //3位抢占优先级

  NVIC_InitStruct.NVIC_IRQChannel=EXTI0_IRQn;//选择EXTI0通道

  NVIC_InitStruct.NVIC_IRQChannelPreemptionPriority=8;//抢占优先级为8

  NVIC_InitStruct.NVIC_IRQChannelSubPriority=0;//响应优先级0

  NVIC_InitStruct.NVIC_IRQChannelCmd=ENABLE;

  NVIC_Init(&NVIC_InitStruct);


  EXTI_InitTypeDef EXTI_InitStruct;

  EXTI_InitStruct.EXTI_Line=EXTI_Line0;//选择输入线0

  EXTI_InitStruct.EXTI_Mode=EXTI_Mode_Interrupt;//选择中断模式

  EXTI_InitStruct.EXTI_Trigger=EXTI_Trigger_Rising;//选择上升沿

  EXTI_InitStruct.EXTI_LineCmd=ENABLE;

  EXTI_Init(&EXTI_InitStruct);


}

void ledInit(){

  RCC->AHB1ENR|=0x00000009;//使能GPIOD和GPIOA时钟,此外ABCDEFGHI端口对应AHB1最低位

  RCC->APB2ENR|=(1<<14);  //SYSCFG EN


  GPIOD->MODER&=0x00ffffff;

  GPIOD->MODER|=0X55000000;//设置D15、14,D13、12为通用输出模式


  GPIOD->OTYPER&=0xffff0fff;//设置D15,14,13,12为推挽输出


  GPIOD->OSPEEDR&=0x00ffffff;

  GPIOD->OSPEEDR|=0xff000000;//设置IO速率为100MHz


  SYSCFG->CMPCR=0x00000001;


  GPIOD->PUPDR&=0x00ffffff;//无上拉无下拉

  GPIOD->BSRRH=0xf000;


}

void EXTI0_IRQHandler(void){

  uint32_t tmp;

  if(EXTI->PR&0x00000001!=0){

    tmp=(~GPIOD->ODR)&0x0000f000;

    GPIOD->ODR&=0xffff0fff;

    GPIOD->ODR|=tmp;


    EXTI->PR=(1<<0);

  }

}

void SysTick_Handler(void){

  if(timingdelay){

    timingdelay--;

  }

}


关键字:STM32  中断初识 引用地址:STM32 中断初识

上一篇:STM32F USB中断分析
下一篇:STM32事件 中断事件 中断的详解

推荐阅读最新更新时间:2024-03-16 16:03

STM32 的内部温度传感器
STM32 有一个内部的温度传感器,可以用来测量 CPU 及周围的温度(TA)。该温度传感器在内部和 ADCx_IN16 输入通道相连接,此通道把传感器输出的电压转换成数字值。温度传感器模拟输入推荐采样时间是 17.1 s。 STM32 的内部温度传感器支持的温度范围为:-40~125度。精度比较差,为 1.5℃左右。 STM32 内部温度传感器的使用很简单,只要设置一下内部 ADC,并激活其内部通道就差不多了。 STM32 内部温度传感器使用的步骤了,如下: 1)设置 ADC,开启内部温度传感器。 ADC_TempSensorVrefintCmd(ENABLE); //开启内部温度传感器功能: 2)读取通道 16 的 AD
[单片机]
滴答时钟开刀了解STM32库操作
STM32的库函数操作给设计开发人员带来了诸多的便利,开发人员不必十分了解STM32的内部寄存器及硬件机制,只要有C语言基础,即可完成单片机的开发,缩短了开发周期,降低了开发难度,因而备受工程师喜爱。 基于库函数的开发模式,与基于API(ApplicationProgrammingInterface)的软件开发有着异曲同工之处,程序员通过调用 API 函数对应用程序进行开发,而又无需访问源码,或理解内部工作机制的细节,可以减轻编程任务。STM32的基于函数库的开发模式也是一样的道理,因此对于有单片机开发经验的工程师来说,学习STM32,很容易就可以上手。 虽然可以不考虑库函数内部的细节,不考虑如何实现硬件寄存器的配置,但是
[单片机]
管理STM32 MCU中的内存保护单元
1前言 本应用笔记介绍如何管理 STM32 产品中的内存保护单元(MPU)。MPU 是用于存储器保护的可选组件。STM32 微控制器(MCU)中嵌入 MPU 之后变得更稳健可靠。在使用 MPU 之前,必须对其进行编程并加以启用。如果 MPU 没有启用,则存储系统的行为不会变化。 2概述 MPU 可以使嵌入式系统更加稳健和安全:• 禁止用户应用程序破坏关键任务(例如操作系统核心)使用的数据• 将 SRAM 存储区域定义为非可执行(禁止执行 XN),以防止代码注入攻击• 修改存储访问属性MPU可最多保护16个内存区域。在 Armv6、Armv7 架构(Cortex-M0+、M3、M4、M7)下,这些区域可以依次拥有 8 个子区域(
[单片机]
管理<font color='red'>STM32</font> MCU中的内存保护单元
STM32中按键中断分析
在按键学习中,我们有用到查询的方法来判断按键事件是否发生,这种查询按键事件适用于程序工作量较少的情况下,一旦程序中工作量较大较多,则势必影响程序运行的效率,为了简化程序中控制的功能模块的执行时间,引入中断控制就很有必要,,一旦有中断时间发生,则程序立马跳转到中断向量的执行程序中,执行完成后就恢复到正常的程序状态。 在STM32F中采用中断控制器NVIC来设定中断。按照中断初始化配置的结构体文件,我们需要在NVIC初始化结构体配置如下: void EXti_PB12_Config(void) { //定义结构体 GPIO_InitTypeDef GPIO_InitStructure; EXTI_InitTypeD
[单片机]
发现STM32的SPI2有问题(invalid)
最近需要用到SPI1和SPI2协同工作,想弄个2位的SPI通信: 硬件的接线如下: SPI1.SCK - DEV.SCK SPI1.SCK - SPI2.SCK SPI1.MOSI - DEV.MOSI SPI1.MISO - DEV.MISO SPI2.MISO - DEV.MOSI SPI2.MOSI - DEV.MISO 将SPI1设置为Master方式,将SPI2设置为Slave。 设置为CPOL=0,CPHA=0(就是不传输的时候时钟是低电平,上升沿采样,下降沿更新数据)。 具体的配置就不贴了,在stm32fwlib的例子里面有。 注意:官方和网上能用的配置都是SPI1是Slave、SPI2为Master!接下来会说。
[单片机]
发现<font color='red'>STM32</font>的SPI2有问题(invalid)
OLED驱动 0.96寸 硬件SPI驱动(STM32
一、前期准备 单片机:STM32F103ZET6 开发环境:MDK5.14 库函数:标准库V3.5 0.96 OLED模块:淘宝有售 二、实验效果 三、驱动原理 此OLED模块采用SPI通信,也可转成IIC通信,不过要焊接背面的电阻,不建议改IIC,要改请参考具体数据手册。驱动芯片SSD1306,具体命令字详解请见网友SSD1306详解。 需要完整工程或者有问题的请加QQ:1002521871,验证:呵呵。 软件模拟SPI驱动 四、驱动代码 oled.h #ifndef __OLED_H__ #define __OLED_H__ #include stm32f10x.h #include stdlib.h #
[单片机]
OLED驱动 0.96寸 硬件SPI驱动(<font color='red'>STM32</font>)
STM32—进入STOP模式后功耗下不去问题
背景: 最近调试板子进入STOP模式后发现电流为mA级别,功耗降不下去,最终发现是ADC开启后,忘记关闭了,导致有1.45mA的电流消耗。 内容: 利用HAL_PWR_EnterSTOPMode(PWR_MAINREGULATOR_ON, PWR_STOPENTRY_WFI)函数使板子进入STOP模式后,电流一直降不下去。之后调了好久,才发现调用ADC采集后,忘记把ADC关掉了,真是蛋疼啊。代码如下: HAL_ADC_Start(&hadc); //开启ADC HAL_ADC_PollForConversion(&hadc,10);//进行ADC 转换,然后对转换后数据进行换算。关键的一步
[单片机]
<font color='red'>STM32</font>—进入STOP模式后功耗下不去问题
STM32裸机编程的基础知识(5)
闪烁 LED 现在我们已经搭建好了完整的构建、烧写的基础设施,是时候让固件做点儿有用的事情了。什么是有用的事情?当然是闪烁 LED 了!Nucleo-F429ZI 开发板有 3 颗 LED,在开发板数据手册的 6.5 节,我们可以看到板载 LED 连接的引脚: PB0: green LED PB7: blue LED PB14: red LED 再次修改 main.c 文件,添加上引脚定义,然后把蓝色 LED 引脚设为输出模式,开始无限循环。首先,把我们之前讨论过的 GPIO 定义和模式设置拷贝过来,注意,现在又新加了一个 BIT(position) 工具宏: #include inttypes.h #include
[单片机]
小广播
添点儿料...
无论热点新闻、行业分析、技术干货……
设计资源 培训 开发板 精华推荐

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

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

换一换 更多 相关热搜器件
电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2024 EEWORLD.com.cn, Inc. All rights reserved