历史上的今天
返回首页

历史上的今天

今天是:2024年10月20日(星期日)

正在发生

2021年10月20日 | stm32专题六:中断 NVIC

2021-10-20 来源:eefocus

stm32的中断分为 1.抢占优先级。 2.子优先级。


1.抢占优先级。抢占优先级高的中断,可以打断抢占优先级低的中断。


2.子优先级。抢占优先级相同的中断,子优先级高的可以优先执行。


其实,子优先级主要给出了一种响应的优先队列。假设中断的抢占优先级都相同。如果有多个相同抢占优先级的中断来了 ,那么他们不会互相打断,但是他们后续的排队会按照子优先级排队。也就是说,在第一个中断没有执行完的期间内,后续的最高级的子优先级是被安排到最高等待位处理的。


NVIC设置流程:


定义NVIC初始化结构体;

配置优先级分组;

往NVIC初始化结构体中填充,如中断源,抢占优先级,子优先级,使能等;

调用NVIC初始化函数;

编写中断服务函数;

static void EXTI_NVIC_Config(void)

{

    NVIC_InitTypeDef NVIC_InitStruct;

 

    // 先设置中断优先级分组

NVIC_PriorityGroupConfig(NVIC_PriorityGroup_1);

NVIC_InitStruct.NVIC_IRQChannel = EXTI0_IRQn;

NVIC_InitStruct.NVIC_IRQChannelPreemptionPriority = 1;

NVIC_InitStruct.NVIC_IRQChannelSubPriority = 1;

NVIC_InitStruct.NVIC_IRQChannelCmd = ENABLE;

    NVIC_Init(&NVIC_InitStruct);

}

 

void EXTI0_IRQHandler(void)

{

// 判断是否发生中断

// 与函数FlagStatus EXTI_GetFlagStatus(uint32_t EXTI_Line);功能相同

if (EXTI_GetITStatus(EXTI_Line0) != RESET)

{

LED_R_TOGGLE;

}

// 清除标志位,往EXTI_PR寄存器写1,与函数void EXTI_ClearFlag(uint32_t EXTI_Line)功能相同

// 之所有一个功能有两个一样的函数,是为了兼容旧的固件库

EXTI_ClearITPendingBit(EXTI_Line0);

}


stm32的中断可以分为系统异常10个(内核)和外部中断60个(外设)。NVIC是内核的外设,管理包括内核和片上外设所有的中断功能,在core_cm3.h和misc.h中。


NVIC的寄存器描述:

ISER:中断使能寄存器,对应60个外设的不可屏蔽中断,其中NVIC_ISER0的0~31位对应着中断向量表中的编号0~31,NVIC_ISER1对应着32~63,ISER2对应剩余位,其中还存在一些保留位,要想开启特定的中断,设置特定的位就可以。


ICER:中断清除寄存器,对应60个外设的不可屏蔽中断。与ISER类似,要想清除特定的中断,设置特定的位就可以。


ISPR:中断挂起寄存器,可挂起正在执行的中断,设置特定位。当置位此寄存器时,这个中断不会立即执行,而是等待可执行的时候再执行;比如高低级别的中断同时产生,CPU会自然的将低级别的中断挂起,当高优先级中断执行完毕后,再去处理低优先级中断,这个时候需要清除挂起位(使用ICPR),然后执行低级别中断。


ICPR:中断解除挂起寄存器,可以解除被挂起的中断。


IABR:中断激活标志寄存器(只读),可读取该寄存器判断当前执行的中断是哪个,中断执行完硬件清零。


IPR:中断优先级寄存器,用于中断分组。


STIR:软件触发中断寄存器,用于系统任务调度,编写SDK(不让别人看到代码)。


core_cm3.h中的NVIC结构体:


typedef struct

{

    __IO uint32_t ISER[8];                      /*!< Offset: 0x000  Interrupt Set Enable Register           */

    uint32_t RESERVED0[24];

    __IO uint32_t ICER[8];                      /*!< Offset: 0x080  Interrupt Clear Enable Register         */

    uint32_t RSERVED1[24];

    __IO uint32_t ISPR[8];                      /*!< Offset: 0x100  Interrupt Set Pending Register          */

    uint32_t RESERVED2[24];

    __IO uint32_t ICPR[8];                      /*!< Offset: 0x180  Interrupt Clear Pending Register        */

    uint32_t RESERVED3[24];

    __IO uint32_t IABR[8];                      /*!< Offset: 0x200  Interrupt Active bit Register           */

    uint32_t RESERVED4[56];

    __IO uint8_t  IP[240];                      /*!< Offset: 0x300  Interrupt Priority Register (8Bit wide) */

    uint32_t RESERVED5[644];

    __O  uint32_t STIR;                         /*!< Offset: 0xE00  Software Trigger Interrupt Register     */

}  NVIC_Type;


stm32设计了8个ISER寄存器,实际上只用到其中的3个,之所以设计这么多组,是为了后续内核和外设资源的升级来考虑的,中间有24个保留地址,总共是32个32位地址,所以ICER的偏移地址为0X80(每4个地址增加0X10),以此类推。

值得注意的是,设置中断优先级的寄存器是8位有效(ARM规定),实际上stm32只使用了高4位,忽略低4位。但是中断优先级寄存器IPR是32位的,因此,每8位寄存器为一个优先级数组IP,每个IPR寄存器表示4个IP优先级分组,如下图:

misc.h中实现了NVIC所有的功能函数:


// 优先级分组

void NVIC_PriorityGroupConfig(uint32_t NVIC_PriorityGroup);

// NVIC初始化

void NVIC_Init(NVIC_InitTypeDef* NVIC_InitStruct);

// 设置中断向量表

void NVIC_SetVectorTable(uint32_t NVIC_VectTab, uint32_t Offset);

// 设置系统进入低功耗模式

void NVIC_SystemLPConfig(uint8_t LowPowerMode, FunctionalState NewState);

// 设置内核时钟来源,72M或72M/8=9M(8分频)

void SysTick_CLKSourceConfig(uint32_t SysTick_CLKSource);

NVIC初始化结构体


/** 

  * @brief  NVIC Init Structure definition  

  */

 

typedef struct

{

  uint8_t NVIC_IRQChannel;                    /*!< Specifies the IRQ channel to be enabled or disabled.

                                                   This parameter can be a value of @ref IRQn_Type 

                                                   (For the complete STM32 Devices IRQ Channels list, please

                                                    refer to stm32f10x.h file) */

 

  uint8_t NVIC_IRQChannelPreemptionPriority;  /*!< Specifies the pre-emption priority for the IRQ channel

                                                   specified in NVIC_IRQChannel. This parameter can be a value

                                                   between 0 and 15 as described in the table @ref NVIC_Priority_Table */

 

  uint8_t NVIC_IRQChannelSubPriority;         /*!< Specifies the subpriority level for the IRQ channel specified

                                                   in NVIC_IRQChannel. This parameter can be a value

                                                   between 0 and 15 as described in the table @ref NVIC_Priority_Table */

 

  FunctionalState NVIC_IRQChannelCmd;         /*!< Specifies whether the IRQ channel defined in NVIC_IRQChannel

                                                   will be enabled or disabled. 

                                                   This parameter can be set either to ENABLE or DISABLE */   

} NVIC_InitTypeDef;

 

/**

  * @}

  */

 

/** @defgroup NVIC_Priority_Table 

  * @{

  */

 

/**

@code  

 The table below gives the allowed values of the pre-emption priority and subpriority according

 to the Priority Grouping configuration performed by NVIC_PriorityGroupConfig function

  ============================================================================================================================

    NVIC_PriorityGroup   | NVIC_IRQChannelPreemptionPriority | NVIC_IRQChannelSubPriority  | Description

  ============================================================================================================================

   NVIC_PriorityGroup_0  |                0                  |            0-15             |   0 bits for pre-emption priority

                         |                                   |                             |   4 bits for subpriority

  ----------------------------------------------------------------------------------------------------------------------------

   NVIC_PriorityGroup_1  |                0-1                |            0-7              |   1 bits for pre-emption priority

                         |                                   |                             |   3 bits for subpriority

  ----------------------------------------------------------------------------------------------------------------------------    

   NVIC_PriorityGroup_2  |                0-3                |            0-3              |   2 bits for pre-emption priority

                         |                                   |                             |   2 bits for subpriority

  ----------------------------------------------------------------------------------------------------------------------------    

   NVIC_PriorityGroup_3  |                0-7                |            0-1              |   3 bits for pre-emption priority

推荐阅读

史海拾趣

ALCOA公司的发展小趣事

ALCOA,全称美国铝业公司,其发展历程可追溯至19世纪末。当时,铝在地球上蕴藏丰富,但提炼单质的铝却十分困难。年轻的查尔斯·霍尔(Charles Hall)发明了用电解方式生产单质铝的方法,并于1889年获得专利。随后,他与艾尔弗雷德·亨特(Alfred E. Hunt)船长合作,投资建厂,开始批量生产铝。这一技术创新不仅推动了铝产量的快速上升,还使得铝这种曾经比金子还贵的金属逐渐走进了人们的日常生活。

DURATOOL公司的发展小趣事

随着全球经济的不断发展,DURATOOL公司意识到单一市场已无法满足其长远发展需求。因此,公司制定了一系列国际化战略,积极开拓海外市场。通过与国外知名企业的合作,DURATOOL公司成功将其产品线扩展到全球多个国家和地区。同时,公司还积极参加国际展会和技术交流活动,提升品牌知名度和影响力。这些举措不仅为DURATOOL公司带来了丰厚的经济回报,也为其在国际市场上树立了良好的企业形象。

HTC Korea(TAEJIN Technology )公司的发展小趣事

HTC Korea自成立以来,一直致力于国际化布局,与全球各地的合作伙伴建立了良好的关系。目前,HTC的产品已在欧美、亚泰地区大量销售,与各地的电信运营商、芯片制造商等保持了紧密的合作关系。这种广泛的合作伙伴网络为HTC提供了强大的市场支持和技术保障,推动了其在全球范围内的快速发展。同时,HTC还通过了ISO9001及ISO14001质量体系认证,以系统、人性化的管理努力成为行业的佼佼者。

飞虹(FeiHong)公司的发展小趣事

2013年8月26日,苏州锋驰微电子有限公司在江苏省苏州市张家港市正式成立,法定代表人为Fang Gang Feng。公司初期便明确了以集成电路IP、物联网、计算机软硬件、电子产品、集成电路及应用电路方案技术的设计、研发为核心业务的发展方向。在成立之初,面对激烈的市场竞争,苏州锋驰凭借对技术的执着追求和敏锐的市场洞察力,逐步在行业内站稳脚跟。

FILTRONETICS Inc公司的发展小趣事

FILTRONETICS Inc成立于1970年代,初期专注于滤波器技术的研发与生产。在那个时代,随着通信技术的快速发展,对高质量滤波器的需求日益增长。公司研发团队通过不懈努力,成功研发出了一种新型LC滤波器,该滤波器在频率选择性和插入损耗方面表现出色,迅速获得了市场的认可。这一技术突破不仅巩固了FILTRONETICS在滤波器领域的地位,也为公司的后续发展奠定了坚实的基础。

Grand Halo Technology Co Ltd公司的发展小趣事

随着业务的不断增长,FILTRONETICS意识到单一产品线的局限性,开始着手拓展多元化产品线。公司加大了对新产品研发的投入,陆续推出了单片滤波器、声表滤波器、腔体滤波器、带线滤波器等多种类型的产品,广泛应用于通讯、仪器仪表、商业、工业等多个领域。这些新产品的推出不仅丰富了公司的产品线,也进一步提升了公司的市场竞争力。

问答坊 | AI 解惑

单片机初学者,请进

本人是一毕业就去了深圳创业,算算时间也有差不多5年了吧,期间一直在做单片机方面的项目开发工作,现在在做嵌入式ARM的相关开发,单片机带给人的乐趣是无穷的。我个人感觉这个行业还是很有前景的。希望在校的大学生们好好利用宝贵时间多学点知识, ...…

查看全部问答>

汽车电子资料大放送~资料、文章、方案...敬请下载~

1.大众车系元件功能与检测资料下载>>https://bbs.eeworld.com.cn/thread-281-1-52.html 2.DS2705主控制器数据资料>> https://bbs.eeworld.com.cn/thread-25994-1-16.html 3.CAN总线在混和动力汽车电机控制系统中的应用>> https://bbs.eeworld ...…

查看全部问答>

SPI核怎么用啊

sopc中的spi和仿真无波形,郁闷~~~~~~~…

查看全部问答>

mc39i tcp只能收发不了

使用外置协议栈,UDP,收发正常, TCP 3次握手过后 tcp只能接收.发送到 服务端的数据,收不到包, 发收的整个包 协议解析正常…

查看全部问答>

如何定制支持MFC的SDK

现在想把原来在WINCE5.0开发的MFC程序移植到WINCE6.0上面, 但一直不能成功.特来请教下: 我现在的环境是VS2005+WINCE6.0  之前在网上找了下, 说是WINCE6.0默认是不支持MFC的.要手动添加几个DLL文件. 现在我也把 MFC80ENU.DLL加进去了, ...…

查看全部问答>

passthru发送原始帧,NdisFreeBuffer蓝屏

改写的passthru 在ndis5.1下实现发送原始帧,出现一个奇怪的问题。 PtDispatch中调用发送函数SendRawData,里面给自己的包做了一个标记, 完了以后在PtSendComplete里释放自己申请的内存。结果在调用NdisFreeBuffer的时候蓝屏。 具体描述如下: ...…

查看全部问答>

急,Microsoft SQL Server CE 2.0安装问题

请问各位大哥,如题,提示错误信息:SQL Server CE Server Tools is compatible only with SQL Server 2000 Service Pack 1 and higher.When you install SQL Server CE Server Tools on a computer running both IIS and SQL Server 2000, ensure the ...…

查看全部问答>

STM32I2C加电后一直是BUSY

我用万利的板子(STM32F103),和我自己做的板子(STM32F101C6T6)!测试 I2C 读写铁电FM24CL64。只要硬件连上 FM24,程序执行完 RCC 时钟初始化后,STM32 的 I2C 就一直处在 BUSY 状态下 ...…

查看全部问答>

串口调试工具发送文件和字符串的区别,香水看看

                                 我用串口调试工具来调试STM107的虚拟串口例程,发送同样字节的数据,使用串口调试工具下面的字符串输入就正常,而 ...…

查看全部问答>

单片机测量电流电压

用单片机做一个电压,电流检测装置。 (1)电压的范围:DC10-36V,要求精度1%以内。 (2)电流DC 0.1-3A,要求精度1%以内。         怎么控制这个精度问题?请各位大侠给点意见!…

查看全部问答>