中断管理函数
C语言的中断服务函数

C语言的中断服务函数中断服务函数是一种特殊的函数,用于处理系统或外设发生的中断事件。
在C语言中,中断服务函数常用于嵌入式系统的开发中,用于实现硬件的响应和处理。
下面是关于C语言中断服务函数的详细介绍,包括定义、注册、实现和应用等方面。
一、中断服务函数的定义中断服务函数(Interrupt Service Routine,ISR)是一段特殊的代码,用于响应和处理中断事件。
它与普通的函数不同,不是由程序主动调用的,而是由系统或硬件触发的。
中断事件一般包括硬件的输入、定时器的溢出、软件触发等。
在C语言中,中断服务函数的定义方式与普通的函数类似,但需要使用特殊的关键字和参数。
如下是一个C语言中断服务函数的定义示例:```void interrupt_service_functio//中断处理代码```在上述示例中,`void`表示中断服务函数不返回值,`interrupt_service_function`是函数的名称。
根据不同的开发平台和编译器,中断服务函数的定义可能有所不同。
二、中断服务函数的注册要使用一个中断服务函数,需要将其注册到相应的中断源中。
中断源可以是系统的中断控制器,也可以是外设的中断引脚。
注册中断服务函数的目的是告诉系统,在相应中断事件发生时调用该函数。
以8051单片机为例,注册中断服务函数的方式如下所示:```void mairegister_interrupt_service_function(interrupt_service_functi on);//其他代码```在上述示例中,`register_interrupt_service_function`是用于将中断服务函数`interrupt_service_function`注册到系统中断控制器的函数。
在实际开发中,不同平台和配置会有不同的注册方式。
三、中断服务函数的实现中断服务函数的实现主要包括对中断事件的处理和相应操作。
中断服务函数的实现需要了解特定硬件的中断机制和相关的寄存器操作。
freertos的中断管理及其他用法

FreeRTOS 是一个用于嵌入式系统的实时操作系统(RTOS),它提供了丰富的功能和API,方便开发者进行任务管理、中断管理和其他实时操作系统的相关操作。
以下是FreeRTOS 中断管理和其他用法的概述:1. 中断管理:- FreeRTOS 提供了`vPortEnterCritical()` 和`vPortExitCritical()` 函数来实现中断的临界区保护。
在进入临界区前调用`vPortEnterCritical()`,在离开临界区时调用`vPortExitCritical()`。
这样可以避免多个中断同时访问共享资源的竞态条件。
- FreeRTOS 还支持软件自动优先级调度(Priority Inheritance Protocol, PIP),这可以确保高优先级任务可以及时响应中断。
2. 任务管理:- 使用FreeRTOS,您可以使用`xTaskCreate()` 函数来创建任务。
每个任务都有自己的优先级和堆栈空间。
- FreeRTOS 提供了任务管理的API,例如:`vTaskDelay()` 用于延迟任务的执行,`vTaskDelete()` 用于删除任务,`vTaskSuspend()` 和`vTaskResume()` 用于暂停和恢复任务的执行等。
- 您可以使用`xTaskCreateStatic()` 函数创建静态任务,从而节省动态分配内存的开销。
3. 信号量和互斥量:- FreeRTOS 提供了两种同步机制:二进制信号量和计数信号量。
您可以使用`xSemaphoreCreateBinary()` 和`xSemaphoreCreateCounting()` 函数创建信号量。
- 使用`xSemaphoreTake()` 和`xSemaphoreGive()` 函数获取和释放信号量,以控制任务和中断之间的访问权。
- 互斥量是一种特殊的信号量,用于实现任务对共享资源的互斥访问。
您可以使用`xSemaphoreCreateMutex()` 函数创建互斥量。
中断处理函数中关中断

中断处理函数中关中断
【实用版】
目录
1.中断处理函数的概述
2.中关中断的含义
3.中断处理函数中关中断的具体操作
4.中断处理函数中关中断的应用实例
5.中断处理函数中关中断的重要性
正文
【中断处理函数的概述】
中断处理函数是计算机程序设计中的一种函数,主要用于处理程序运行过程中出现的各种中断事件。
中断事件是指程序在执行过程中,由于某种原因而暂停当前正在执行的任务,转去处理其他任务的过程。
中断处理函数就是在程序中定义的一段代码,用于响应和处理这些中断事件。
【中关中断的含义】
中关中断是指在程序运行过程中,由于某种原因导致程序暂停当前正在执行的任务,转而执行中断处理函数的过程。
中关中断通常是由硬件设备或软件程序产生的,比如:外部中断、内部中断、软件中断等。
【中断处理函数中关中断的具体操作】
当中关中断发生时,程序会立即停止当前正在执行的任务,转而跳转到中断处理函数的入口处。
中断处理函数会根据中断的类型和原因,执行相应的操作,完成中断处理。
处理完毕后,程序会返回原点,继续执行被中断的任务。
【中断处理函数中关中断的应用实例】
中断处理函数中关中断在实际应用中具有重要意义。
例如,在实时操作系统中,中断处理函数用于处理硬件设备或软件程序产生的中断事件,确保系统能够及时响应外部事件,保证系统的实时性。
【中断处理函数中关中断的重要性】
中断处理函数中关中断对于程序的稳定运行具有重要意义。
它能够使程序在执行过程中,及时响应外部事件,保证程序能够快速处理各种中断事件,避免程序因为无法及时响应中断事件而导致的系统崩溃等问题。
单片机C语言函数中断函数(中断服务程序)

单片机_C语言函数_中断函数(中断服务程序)在开始写中断函数之前,我们来一起回顾一下,单片机的中断系统。
中断的意思(学习过微机原理与接口技术的同学,没学过单片机,也应该知道),我们在这里就不讲了,首先来回忆下中断系统涉及到哪些问题。
(1)中断源:中断请求信号的来源。
(8051有3个内部中断源T0,T1,串行口,2个外部中断源INT0,INT1(这两个低电平有效,上面的那个横杠不知道怎么加上去))(2)中断响应与返回:CPU采集到中断请求信号,怎样转向特定的中断服务子程序,并在执行完之后返回被中断程序继续执行。
期间涉及到C PU响应中断的条件,现场保护,现场恢复。
(3)优先级控制:中断优先级的控制就形成了中断嵌套(8051允许有两级的中断嵌套,优先权顺序为INT0,T0,INT1,T1,串行口),同一个优先级的中断,还存在优先权的高低。
优先级是可以编程的,而优先权是固定的。
80C51的原则是①同优先级,先响应高优先权②低优先级能被高优先级中断③正在进行的中断不能被同一级的中断请求或低优先级的中断请求中断。
80C51的中断系统涉及到的中断控制有中断请求,中断允许,中断优先级控制(1)3个内部中断源T0,T1,串行口,2个外部中断源INT0,INT1(2)中断控制寄存器:定时和外中断控制寄存器TCON(包括T0、T1,INT0、INT1),串行控制寄存器SCON,中断允许寄存器IE,中断优先级寄存器IP具体的是什么,包括哪些标志位,在这里不讲了,所有书上面都会讲。
在这里我们讲下注意的事项(1)CPU响应中断后,TF0(T0中断标志位)和TF1由硬件自动清0。
(2)CPU响应中断后,在边沿触发方式下,IE0(外部中断IN T0请求标志位)和IE1由硬件自动清零;在电平触发方式下,不能自动清楚IE0和I E1。
中断管理函数

CM325616240 256STM32CM3STM32761660 166060MDK NVIC MDKtypedef struct{vu32 ISER[2];u32 RESERVED0[30];vu32 ICER[2];u32 RSERVED1[30];vu32 ISPR[2];u32 RESERVED2[30];vu32 ICPR[2];u32 RESERVED3[30];vu32 IABR[2];u32 RESERVED4[62];vu32 IPR[15];} NVIC_TypeDef;STM32STM32ISER[2]ISER Interrupt Set-Enable RegistersSTM326023264STM3260ISER[0]bit0~bit310~31ISER[1]bit0~2732~5960ISER1 (IO)stm32f10x_nvic..h36ICER[2]Interrupt Clear-Enable RegistersISERICER ICERISER0NVIC10CM3125NVICISPR[2]Interrupt Set-Pending RegistersISER1ICPR[2]Interrupt Clear-Pending RegistersISPR ISER1IABR[2]Active Bit RegistersISER1IPR[15]Interrupt Priority RegistersSTM32IPR1532bit8bit15*4=60STM32IPR[0][31~24][23~16][15~8][7~0]3~0608bit44SCB->AIRCRSTM32STM3250~4SCB->AIRCR bit10~82.7.2.1 AIRCR0~4360310~71023(RTC) 31604 0713037>3>6237673STM32NVIC MY_NVIC_PriorityGroupConfig NVIC_Group0~45MY_NVIC_PriorityGroupConfig //NVIC//NVIC_Group:NVIC 0~4 5void MY_NVIC_PriorityGroupConfig(u8 NVIC_Group){u32 temp temp1;temp1=(~NVIC_Group)&0x07;//temp1<<=8;temp=SCB->AIRCR; //temp&=0X0000F8FF; //temp|=0X05FA0000; //temp|=temp1;SCB->AIRCR=temp; //}STM325SCB->AIRCR BIT[10:8]7.2.3SCB->AIRCR160X05FA AIRCR16AIRCR AIRCR->->AIRCRMY_NVIC_PriorityGroupConfigNVIC MY_NVIC_Init4NVIC_PreemptionPriority NVIC_SubPriority NVIC_Channel NVIC_Group NVIC_PreemptionPriorityNVIC_SubPriorityNVIC_Channel0~59NVIC_Group0~4//NVIC//NVIC_PreemptionPriority://NVIC_SubPriority ://NVIC_Channel ://NVIC_Group : 0~4//!//://0:04//1:13//2:22//3:31//4:40//NVIC_SubPriority NVIC_PreemptionPriorityvoid MY_NVIC_Init(u8 NVIC_PreemptionPriority u8 NVIC_SubPriority u8 NVIC_Channel u8 NVIC_Group){u32 temp;u8 IPRADDR=NVIC_Channel/4; //4u8 IPROFFSET=NVIC_Channel%4;//IPROFFSET=IPROFFSET*8+4; //MY_NVIC_PriorityGroupConfig(NVIC_Group);//temp=NVIC_PreemptionPriority<<(4-NVIC_Group);temp|=NVIC_SubPriority&(0x0f>>NVIC_Group);temp&=0xf;//if(NVIC_Channel<32)NVIC->ISER[0]|=1<<NVIC_Channel;// (OK)else NVIC->ISER[1]|=1<<(NVIC_Channel-32);NVIC->IPR[IPRADDR]|=temp<<IPROFFSET;//}IPR844MY_NVIC_PriorityGroupConfigISER1NVICSTM32EXTI19//STM32190~15IO16PVD17RTC18USBEXTI MDKtypedef struct{vu32 IMR;vu32 EMR;vu32 RTSR;vu32 FTSR;vu32 SWIER;vu32 PR;} EXTI_TypeDef;IMR3219x 1EMR IMRRTSR IMR3219x x1/FTSR PTSRSWIER x1IMR EMR PR IMR EMRSWIER PRPR1011STM32 958.3EXTIIOIO EXTICRSTM32IO IO16STM32GPIOA~GPIOG[15:0]15~07IO0GPIOA.0 PIOB.0GPIOC.0GPIOD.0GPIOE.0GPIOF.0GPIOG.01IO EXTICR GPIO EXTICR AFIOtypedef struct{vu32 EVCR;vu32 MAPR;vu32 EXTICR[4];} AFIO_TypeDef;EXTICR4EXTICR16EXTICR[0]2.7.2.4 EXTICR[0]GPIOB.11EXTICR[0]bit7:60001 0000GPIOA EXTICRSTM3286~87Ex_NVIC_Config3GPIOx GPIOA~G0~6sys.hIO BITx IO TRIM 20x010x020x03////GPIOA~G;PVD RTC USB//:GPIOx:0~6GPIOA~G;BITx:;TRIM:1 ;2;3//1IO IO//void Ex_NVIC_Config(u8 GPIOx u8 BITx u8 TRIM){u8 EXTADDR;u8 EXTOFFSET;EXTADDR=BITx/4;//EXTOFFSET=(BITx%4)*4;RCC->APB2ENR|=0x01;//ioAFIO->EXTICR[EXTADDR]|=GPIOx<<EXTOFFSET;//EXTI.BITx GPIOx.BITx//EXTI->IMR|=1<<BITx;// line BITxEXTI->EMR|=1<<BITx;//line BITxif(TRIM&0x01)EXTI->FTSR|=1<<BITx;//line BITxif(TRIM&0x02)EXTI->RTSR|=1<<BITx;//line BITx}Ex_NVIC_Config GPIOxEXTICR EXTICRGPIOxIO IOSTM32。
keil5中关中断函数

keil5中关中断函数关于Keil5中的中断函数Keil5是一款嵌入式开发工具,广泛应用于单片机的开发过程中。
其中一个重要的功能就是中断函数的使用。
中断函数是一种特殊的函数,能够在程序执行过程中被硬件或软件中断请求触发,从而及时响应并处理相应的事件。
在Keil5中,中断函数的应用非常广泛,可以用于各种外设的驱动或其他需要实时响应的场景。
在Keil5中,编写中断函数需要遵循一定的规范和步骤。
首先,在代码中需要声明中断函数的原型,以告诉编译器这是一个中断函数。
例如,如果要编写一个外部中断的中断函数,可以使用如下的声明方式:```cvoid EXTI_IRQHandler(void) __interrupt 0;```其中,`__interrupt`是一个关键字,用来告诉编译器这是一个中断函数。
数字0表示中断向量号,不同的外设有不同的中断向量号。
在声明中断函数的时候,需要根据具体的中断向量号进行设置。
在编写中断函数的实现代码时,需要注意几点。
首先,中断函数不能有返回值,因为中断函数是被中断请求触发的,没有返回值的概念。
其次,中断函数需要尽快地完成处理,并通过特定的方式清除中断标志位,以便下一次中断请求能够被触发。
最后,中断函数中一般不建议使用延时函数或者其他可能引起较长时间阻塞的操作,以免影响整个系统的实时性。
在编写中断函数的过程中,还需要注意中断优先级的设置。
Keil5提供了一套灵活的中断优先级管理机制,可以根据具体的需求进行设置。
通过合理设置中断优先级,可以确保不同中断之间的相对优先级,从而保证系统能够按照预期的方式响应中断请求。
除了编写中断函数外,还需要在主函数中进行中断的使能和配置。
在Keil5中,可以通过相关的寄存器设置或者使用库函数来完成中断的使能和配置。
例如,如果要使能外部中断,可以使用如下的代码:```cIE |= 0x01; // 使能外部中断```其中,`IE`是一个寄存器,用来控制中断的使能。
开关中断函数

开关中断函数开关中断函数是一种用来控制中断的函数。
在计算机系统中,中断是一种非常重要的机制。
它可以使处理器暂停正在执行的程序,并转而执行另一段代码(中断服务程序)。
中断可以是外部中断,比如硬件中断,也可以是内部中断,比如软件中断。
在日常的编程工作中,我们经常需要在程序中开关某个中断,这时就可以使用开关中断函数来实现。
开关中断函数一般包括两个函数:开中断函数和关中断函数。
下面我们来分别介绍这两个函数。
开中断函数是用来打开中断的函数。
在开中断函数执行后,将会使系统接受外部中断信号,并执行中断服务程序。
下面是一个比较常见的开中断函数的实现:void open_interrupt(){__asm__("sti"); //开中断指令}这个函数实现比较简单,它只是执行了一个汇编指令。
__asm__ 是 GCC 中的内联汇编语句,用来嵌入汇编代码。
sti 是打开中断的汇编指令,它会将中断标志位设置为1,表示系统可以接受中断信号了。
需要注意的是,由于该指令涉及到硬件操作,因此需要使用内联汇编的方式来执行。
使用开关中断函数的方法非常简单,只需要在需要开关中断的地方调用相应的函数即可。
下面是一个示例,演示了如何在 Linux 系统中使用开关中断函数:#include <signal.h>#include <stdio.h>#include <unistd.h>void open_interrupt();void close_interrupt();在这个示例程序中,我们注册了一个信号处理函数 handler,用来处理 SIGINT 信号。
然后使用 open_interrupt 函数打开了中断,接着进入一个循环,在循环中输出一些信息。
在输出信息的过程中,如果接收到了 SIGINT 信号,就会调用 handler 函数。
最后使用close_interrupt 函数关闭了中断。
中断管理函数(详细)

中断管理函数CM3内核支持256个中断,其中包含了16个内核中断和240个外部中断,并且具有256级的可编程中断设置。
但STM32并没有使用CM3内核的全部东西,而是只用了它的一部分。
STM32有76个中断,包括16个内核中断和60个可屏蔽中断,具有16级可编程的中断优先级。
而我们常用的就是这60个可屏蔽中断,所以我们就只针对这60个可屏蔽中断进行介绍。
在MDK内,与NVIC相关的寄存器,MDK为其定义了如下的结构体:typedef struct{vu32 ISER[2];u32 RESERVED0[30];vu32 ICER[2];u32 RSERVED1[30];vu32 ISPR[2];u32 RESERVED2[30];vu32 ICPR[2];u32 RESERVED3[30];vu32 IABR[2];u32 RESERVED4[62];vu32 IPR[15];} NVIC_TypeDef;STM32的中断在这些寄存器的控制下有序的执行的。
了解这些中断寄存器,你才能方便的使用STM32的中断。
下面重点介绍这几个寄存器:ISER[2]:ISER全称是:Interrupt Set-Enable Registers,这是一个中断使能寄存器组。
上面说了STM32的可屏蔽中断只有60个,这里用了2个32位的寄存器,总共可以表示64个中断。
而STM32只用了其中的前60位。
ISER[0]的bit0~bit31分别对应中断0~31。
ISER[1]的bit0~27对应中断32~59;这样总共60个中断就分别对应上了。
你要使能某个中断,必须设置相应的ISER位为1,使该中断被使能(这里仅仅是使能,还要配合中断分组、屏蔽、IO口映射等设置才算是一个完整的中断设置)。
具体每一位对应哪个中断,请参考stm32f10x_nvic..h里面的第36行处。
ICER[2]:全称是:Interrupt Clear-Enable Registers,是一个中断除能寄存器组。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
中断管理函数CM3内核支持256个中断,其中包含了16个内核中断和240个外部中断,并且具有256级的可编程中断设置。
但STM32并没有使用CM3内核的全部东西,而是只用了它的一部分。
STM32有76个中断,包括16个内核中断和60个可屏蔽中断,具有16级可编程的中断优先级。
而我们常用的就是这60个可屏蔽中断,所以我们就只针对这60个可屏蔽中断进行介绍。
在MDK内,与NVIC相关的寄存器,MDK为其定义了如下的结构体:typedef struct{vu32 ISER[2];u32 RESERVED0[30];vu32 ICER[2];u32 RSERVED1[30];vu32 ISPR[2];u32 RESERVED2[30];vu32 ICPR[2];u32 RESERVED3[30];vu32 IABR[2];u32 RESERVED4[62];vu32 IPR[15];} NVIC_TypeDef;STM32的中断在这些寄存器的控制下有序的执行的。
了解这些中断寄存器,你才能方便的使用STM32的中断。
下面重点介绍这几个寄存器:ISER[2]:ISER全称是:Interrupt Set-Enable Registers,这是一个中断使能寄存器组。
上面说了STM32的可屏蔽中断只有60个,这里用了2个32位的寄存器,总共可以表示64个中断。
而STM32只用了其中的前60位。
ISER[0]的bit0~bit31分别对应中断0~31。
ISER[1]的bit0~27对应中断32~59;这样总共60个中断就分别对应上了。
你要使能某个中断,必须设置相应的ISER位为1,使该中断被使能(这里仅仅是使能,还要配合中断分组、屏蔽、IO口映射等设置才算是一个完整的中断设置)。
具体每一位对应哪个中断,请参考stm32f10x_nvic..h里面的第36行处。
ICER[2]:全称是:Interrupt Clear-Enable Registers,是一个中断除能寄存器组。
该寄存器组与ISER的作用恰好相反,是用来清除某个中断的使能的。
其对应位的功能,也和ICER一样。
这里要专门设置一个ICER来清除中断位,而不是向ISER写0来清除,是因为NVIC的这些寄存器都是写1有效的,写0是无效的。
具体为什么这么设计,请看《CM3权威指南》第125页,NVIC概览一章。
ISPR[2]:全称是:Interrupt Set-Pending Registers,是一个中断挂起控制寄存器组。
每个位对应的中断和ISER是一样的。
通过置1,可以将正在进行的中断挂起,而执行同级或更高级别的中断。
写0是无效的。
ICPR[2]:全称是:Interrupt Clear-Pending Registers,是一个中断解挂控制寄存器组。
其作用与ISPR相反,对应位也和ISER是一样的。
通过设置1,可以将挂起的中断接挂。
写0无效。
IABR[2]:全称是:Active Bit Registers,是一个中断激活标志位寄存器组。
对应位所代表的中断和ISER一样,如果为1,则表示该位所对应的中断正在被执行。
这是一个只读寄存器,通过它可以知道当前在执行的中断是哪一个。
在中断执行完了由硬件自动清零。
IPR[15]:全称是:Interrupt Priority Registers,是一个中断优先级控制的寄存器组。
这个寄存器组相当重要!STM32的中断分组与这个寄存器组密切相关。
IPR寄存器组由15个32bit的寄存器组成,每个可屏蔽中断占用8bit,这样总共可以表示15*4=60个可屏蔽中断。
刚好和STM32的可屏蔽中断数相等。
IPR[0]的[31~24],[23~16],[15~8],[7~0]分别对应中中断3~0,依次类推,总共对应60个外部中断。
而每个可屏蔽中断占用的8bit并没有全部使用,而是只用了高4位。
这4位,又分为抢占优先级和子优先级。
抢占优先级在前,子优先级在后。
而这两个优先级各占几个位又要根据SCB->AIRCR中中断分组的设置来决定。
这里简单介绍一下STM32的中断分组:STM32将中断分为5个组,组0~4。
该分组的设置是由SCB->AIRCR寄存器的bit10~8来定义的。
具体的分配关系如下表所示:表2.7.2.1 AIRCR中断分组设置表通过这个表,我们就可以清楚的看到组0~4对应的配置关系,例如组设置为3,那么此时所有的60个中断,每个中断的中断优先寄存器的高四位中的最高3位是抢占优先级,低1位是响应优先级。
每个中断,你可以设置抢占优先级为0~7,响应优先级为1或0。
抢占优先级的级别高于响应优先级。
而数值越小所代表的优先级就越高。
结合实例说明一下:假定设置中断优先级组为2,然后设置中断3(RTC中断)的抢占优先级为3,响应优先级为1。
中断6(外部中断0)的抢占优先级为4,响应优先级为0。
中断7(外部中断1)的抢占优先级为3,响应优先级为0。
那么这3个中断的优先级顺序为:中断7>3>中断6。
这里需要注意2点:如果两个中断的响应优先级和响应优先级都是一样的话,则看哪个中断先发生就先执行。
高优先级的抢占优先级是可以打断正在进行的低抢占优先级中断的。
而抢占优先级相同的中断,上面例子中的中断3和中断7都可以打断中断6的中断。
而中断7和中断3却不可以相互打断!通过以上介绍,我们熟悉了STM32中断设置的大致过程。
接下来我们介绍如何使用函数实现以上中断设置,使得我们以后的中断设置简单化。
第一个介绍的是NVIC的分组函数MY_NVIC_PriorityGroupConfig,该函数的参数NVIC_Group0~4,总共5组。
如果参数非法,将可能导致不可预料的结果。
MY_NVIC_PriorityGroupConfig函数代码如下://设置NVIC分组//NVIC_Group:NVIC分组 0~4 总共5组void MY_NVIC_PriorityGroupConfig(u8 NVIC_Group){u32 temp,temp1;temp1=(~NVIC_Group)&0x07;//取后三位temp1<<=8;temp=SCB->AIRCR; //读取先前的设置temp&=0X0000F8FF; //清空先前分组temp|=0X05FA0000; //写入钥匙temp|=temp1;SCB->AIRCR=temp; //设置分组}通过前面的介绍,我们知道STM32的5个分组是通过设置SCB->AIRCR的BIT[10:8]来实现的,而通过7.2.3的介绍我们知道SCB->AIRCR的修改需要通过在高16位写入0X05FA这个密钥才能修改的,故在设置AIRCR之前,应该把密钥加入到要写入的内容的高16位,以保证能正常的写入AIRCR。
在修改AIRCR的时候,我们一般采用读->改->写的步骤,来实现不改变AIRCR原来的其他设置。
以上就是MY_NVIC_PriorityGroupConfig函数设置中断优先级分组的思路。
第二个函数是NVIC设置函数MY_NVIC_Init,该函数有4个参数,分别为:NVIC_PreemptionPriority、NVIC_SubPriority、NVIC_Channel、NVIC_Group。
第一个参数NVIC_PreemptionPriority为中断抢占优先级数值,第二个参数NVIC_SubPriority为中断子优先级数值,前两个参数的值必须在规定范围内,否则也可能产生意想不到的错误。
第三个参数NVIC_Channel为中断的编号(范围为0~59),最后一个参数NVIC_Group为中断分组设置(范围为0~4)。
该函数代码如下://设置NVIC//NVIC_PreemptionPriority:抢占优先级//NVIC_SubPriority :响应优先级//NVIC_Channel :中断编号//NVIC_Group :中断分组 0~4//注意优先级不能超过设定的组的范围!否则会有意想不到的错误//组划分://组0:0位抢占优先级,4位响应优先级//组1:1位抢占优先级,3位响应优先级//组2:2位抢占优先级,2位响应优先级//组3:3位抢占优先级,1位响应优先级//组4:4位抢占优先级,0位响应优先级//NVIC_SubPriority和NVIC_PreemptionPriority的原则是,数值越小,越优先void MY_NVIC_Init(u8 NVIC_PreemptionPriority,u8 NVIC_SubPriority,u8 NVIC_Channel,u8 NVIC_Group){u32 temp;u8 IPRADDR=NVIC_Channel/4; //每组只能存4个,得到组地址u8 IPROFFSET=NVIC_Channel%4;//在组内的偏移IPROFFSET=IPROFFSET*8+4; //得到偏移的确切位置MY_NVIC_PriorityGroupConfig(NVIC_Group);//设置分组temp=NVIC_PreemptionPriority<<(4-NVIC_Group);temp|=NVIC_SubPriority&(0x0f>>NVIC_Group);temp&=0xf;//取低四位if(NVIC_Channel<32)NVIC->ISER[0]|=1<<NVIC_Channel;//使能中断位(要清除的话,相反操作就OK)else NVIC->ISER[1]|=1<<(NVIC_Channel-32);NVIC->IPR[IPRADDR]|=temp<<IPROFFSET;//设置响应优先级和抢断优先级}通过前面的介绍,我们知道每个可屏蔽中断的优先级的设置是在IPR寄存器组里面的,每个中断占8位,但只用了其中的4个位,以上代码就是根据中断分组情况,来设置每个中断对应的高4位的数值的。
当然在该函数里面还引用了MY_NVIC_PriorityGroupConfig这个函数来设置分组。
其实这个分组函数在每个系统里面只要设置一次就够了,设置多次,则是以最后的那一次为准。
但是只要多次设置的组号都是一样,就没事。
否则前面设置的中断会因为后面组的变化优先级会发生改变,这点在使用的时候要特别注意!一个系统代码里面,所有的中断分组都要统一!!,以上代码对要配置的中断号默认是开启中断的。
也就是ISER中的值设置为1了。
通过以上两个函数就实现了对NVIC的管理和配置。