0 卖盘信息
BOM询价
您现在的位置: 首页 > 电子资讯 >技术信息 > ARM的外部中断配置

ARM的外部中断配置

来源: elecfans
2020-09-02
类别:技术信息
eye 86
文章创建人 拍明

原标题:ARM的外部中断配置

  很多情况下,要实现一个嵌入式程序,用到某一功能或者某一个硬件资源时,我经常拿厂家或者是其他人给提供的代码,参考其中的配置代码段部分,只去修改实现成我需要的功能就好。相信大家也和我有相似的经历吧!?从工程的角度来说,这没问题。但是理论上总感觉少了点什么,今天以外部中断的寄存器配置为例,进一步讲解中断源是如何进入CPU中,CPU又如何处理中断信号的,这一过程。单纯学术的角度,具体涉及到哪些寄存器、填写什么值,就不细述了。这里用的单片机是FS4412多核ARM芯片

  中断的实现过程(程序的角度)

  中断发生后,硬件自动跳转到异常向量表中对应异常类型的位置,然后进行处理。处理过程,先进行现场保护(数据进栈操作),然后根据处理中断函数,根据中断号进行特定的中断处理,等中断程序处理完后,还要恢复中断前的现场(数据出栈操作)。

  

  对中断源的处理过程(硬件的角度)这个过程涉及到我们要讲的中断初始化配置,从图中可以看到,一个外部中断信号需要经过这么多步骤才能到达ARM内核。

  首先,外部中断信号需经过GPIO管脚进入CPU内部,然后再内部经使能-->分发-->分发使能-->cpu接口-->接口使能和优先级-->ARM内核 过五关 斩六将 终于到达ARM内核,然后产生中断标志位,再执行之前讲到的中断实现(程序实现)。

  

  中断初始化配置单片机有内置外设,GPIO属于外围功能模块,中断控制器GIC属于内部外设。由于中断源从IO口进入到中断控制器GIC,才能进入ARM内核。我们需要同时配置这两块资源。

  #define GPX1CON (*(volatile unsigned int *)0x11000c20)

  #define EXT_INT41CON (*(volatile int *)0x11000E04)

  #define EXT_INT41_MASK (*(volatile int *)0x11000F04)

  #define ICDISER1_CPU0 (*(volatile int *)0x10490104)

  #define ICDIPTR14_CPU0 (*(volatile int *)0x10490838)

  #define ICDDCR (*(volatile int *)0x10490000)

  #define ICCICR_CPU0 (*(volatile int *)0x10480000)

  #define ICCPMR_CPU0 (*(volatile int *)0x10480004)

  #define EXT_INT41_PEND (*(volatile int *)0x11000f44)

  #define ICCIAR_CPU0 (*(volatile int *)0x1048000C)

  #define ICCEOIR_CPU0 (*(volatile int *)0x10480010)

  #define ICDICPR1_CPU0 (*(volatile int *)0x10490284)

  void interrupt_init(void)

  {

  //-----外: 配置管脚的工作模式

  GPX1CON = (GPX1CON & ~(0xF<<4))|(0xF<<4); //配置 GPX1_1为中断模式

  EXT_INT41CON = (EXT_INT41CON & ~(0x7<<4))|(0x2<<4); //设置GPX1_1的触发方式为 下降沿触

  EXT_INT41_MASK = EXT_INT41_MASK & (~0x02); //GPX1_1 中断使能

  //-----内: 功能块设置

  ICDISER1_CPU0 = ICDISER1_CPU0 | (1<<25); //EINT9 (GPX1_1) GIC中断使能

  ICDIPTR14_CPU0 = 0x01010101; //参考例子背景,用默认设置

  ICDDCR = ICDDCR|1; //GIC 分发总使能

  ICCICR_CPU0 = 1; // CPU0 中断使能

  ICCPMR_CPU0 = 0XFF; //设置CPU0的优先级门槛为最低

  }

  复制代码

  注:外部中断配置过程:

  1配置中断

  1、 分配中断向量表:

  /* Set the Vector Table base location at 0x20000000 */

  NVIC_SetVectorTable(NVIC_VectTab_RAM, 0x0);

  2、 设置中断优先级:

  NVIC_PriorityGroupConfig(NVIC_PriorityGroup_0); //设置中断优先级

  3、 初始化外部中断:

  /*允许EXTI4中断 */

  NVIC_InitStructure.NVIC_IRQChannel = EXTI4_IRQChannel; //中断通道

  NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = PreemptionPriorityValue;//强占优先级

  NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0; //次优先级

  NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; //通道中断使能

  NVIC_Init(&NVIC_InitStructure); //初始化中断

  注意:如果我们配置的外部针脚为PA4,或PB4,或PC4,PD4等,那么采用的外部中断也必须是EXTI4,同样,如果外部中断针脚是PA1,PB1,PC1,PD1 那么中断就要用EXTI1,其他类推。

  2配置GPIO针脚作为外部中断的触发事件

  1、 选择IO针脚

  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_4;

  注意,如果的针脚是端口的4号针脚,配置的中断一定是EXTI4

  2、 配置针脚为输入

  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;

  3、 初始化针脚

  GPIO_Init(GPIOD,&GPIO_InitStructure);

  3配置EXTI线,使中断线和IO针脚线连接上

  1、 将EXTI线连接到IO端口上

  将EXTI线4连接到端口GPIOD的第4个针脚上

  GPIO_EXTILineConfig(GPIO_PortSourceGPIOD,GPIO_PinSource4);

  注意:如果配置的针脚是4号,那么参数必须是GPIO_PinSource4

  如果配置的针脚是3号,那么参数必须是GPIO_PinSource3

  2、配置中断边沿

  /*配置EXTI线0上出现下降沿,则产生中断*/

  EXTI_InitStructure.EXTI_Line = EXTI_Line4;

  注意:如果配置的4号针脚,那么EXTI_Line4是必须的

  EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt;

  EXTI_InitStructure.EXTI_trigger = EXTI_Trigger_Falling; //下降沿触发

  EXTI_InitStructure.EXTI_LineCmd = ENABLE; //中断线使能

  EXTI_Init(&EXTI_InitStructure); //初始化中断

  EXTI_GenerateSWInterrupt(EXTI_Line4); //EXTI_Line4中断允许

  到此中断配置完成,可以写中断处理函数。

  举例:

  配置函数

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

  * 函数名 NVIC_Configration

  * 描述 配置各个中断寄存器

  * 输入 无

  * 输出 无

  * 返回值 无

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

  void NVIC_Configration(void)

  {

  NVIC_InitTypeDef NVIC_InitStructure;

  //#IFdef VECT_TAB_RAM

  /* Set the Vector Table base location at 0x20000000 */

  NVIC_SetVectorTable(NVIC_VectTab_RAM, 0x0);

  //#else /* VECT_TAB_FLASH */

  /* Set the Vector Table base location at 0x08000000 */

  //NVIC_SetVectorTable(NVIC_VectTab_FLASH, 0x0);

  //#endif

  NVIC_PriorityGroupConfig(NVIC_PriorityGroup_0); //设置中断优先级

  /*允许EXTI4中断 */

  NVIC_InitStructure.NVIC_IRQChannel = EXTI4_IRQChannel;

  NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = PreemptionPriorityValue;

  NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;

  NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;

  NVIC_Init(&NVIC_InitStructure);

  /*允许EXTI9中断*/

  NVIC_InitStructure.NVIC_IRQChannel = EXTI9_5_IRQChannel;

  NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;

  NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;

  NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;

  NVIC_Init(&NVIC_InitStructure);

  /*配置SysTick处理优先级:优先级以及子优先级*/

  }

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

  * 函数名 :GPIO_Configuration(void)

  * 描述 :配置TIM2阵脚

  * 输入 :无

  * 输出 :无

  * 返回 :无

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

  void GPIO_Configuration(void){

  /* GPIO_InitTypeDef GPIO_InitStructure;

  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0|GPIO_Pin_1|GPIO_Pin_2|GPIO_Pin_3;

  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;

  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;

  GPIO_Init(GPIOA,&GPIO_InitStructure); */

  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_All;

  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;

  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_2MHz;

  GPIO_Init(GPIOC,&GPIO_InitStructure);

  /*配置GPIOD的第一个管角为浮动输入*/

  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_4;

  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;

  GPIO_Init(GPIOD,&GPIO_InitStructure);

  /*配置GPIOB的第9个管脚为浮动输入*/

  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9;

  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;

  GPIO_Init(GPIOB,&GPIO_InitStructure);

  }

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

  * 函数 SysTick_Configuration

  * 描述 设置SysTick

  * 输入 无

  * 输出 无

  * 返回值 无

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

  void SysTick_Configuration(void)

  {

  /*配置 HCLK 时钟做为SysTick 时钟源*/

  SysTick_CLKSourceConfig(SysTick_CLKSource_HCLK_Div8); //系统时钟8分频 72MHz

  NVIC_SystemHandlerPriorityConfig(SystemHandler_SysTick, 8,2);

  /*SysTick Interrupt each 1000Hz with HCLK equal to 72MHz*/

  SysTick_SetReload(9000);//中断周期1ms

  /*Enable the SysTick Interrupt */

  SysTick_ITConfig(ENABLE);//打开中断

  SysTick_CounterCmd(SysTick_Counter_Enable);

  SysTick_CounterCmd(SysTick_Counter_Clear);

  }

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

  * 函数名 EXTI_Configuration

  * 描述 配置EXTI线

  * 输入 无

  * 输出 无

  * 返回值 无

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

  void EXTI_Configuration(void){

  /*将EXTI线0连接到PA0*/

  GPIO_EXTILineConfig(GPIO_PortSourceGPIOD,GPIO_PinSource4);

  /*配置EXTI线0上出现下降沿,则产生中断*/

  EXTI_InitStructure.EXTI_Line = EXTI_Line4;

  EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt;

  EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Falling;

  EXTI_InitStructure.EXTI_LineCmd = ENABLE;

  EXTI_Init(&EXTI_InitStructure);

  EXTI_GenerateSWInterrupt(EXTI_Line4);

  /*将EXTI线9连接到PB9上*/

  GPIO_EXTILineConfig(GPIO_PortSourceGPIOB,GPIO_PinSource9);

  /*将EXTI线9上出现下降沿产生中断*/

  EXTI_InitStructure.EXTI_Line = EXTI_Line9;

  EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt;

  EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Falling;

  EXTI_InitStructure.EXTI_LineCmd = ENABLE;

  EXTI_Init(&EXTI_InitStructure);

  EXTI_GenerateSWInterrupt(EXTI_Line9);

  }

  中断函数:

  void EXTI4_IRQHandler(void)

  {

  if(EXTI_GetITStatus(EXTI_Line4)!= RESET){

  EXTI_ClearITPendingBit(EXTI_Line4);

  if(LEDflag == 0){

  Ledflag = 1;

  GPIOC->ODR |= 0X00000080;

  }

  else{

  Ledflag = 0;

  GPIOC->ODR &= 0XFFFFFF7F;

  }

  }

  }


责任编辑:David

【免责声明】

1、本文内容、数据、图表等来源于网络引用或其他公开资料,版权归属原作者、原发表出处。若版权所有方对本文的引用持有异议,请联系拍明芯城(marketing@iczoom.com),本方将及时处理。

2、本文的引用仅供读者交流学习使用,不涉及商业目的。

3、本文内容仅代表作者观点,拍明芯城不对内容的准确性、可靠性或完整性提供明示或暗示的保证。读者阅读本文后做出的决定或行为,是基于自主意愿和独立判断做出的,请读者明确相关结果。

4、如需转载本方拥有版权的文章,请联系拍明芯城(marketing@iczoom.com)注明“转载原因”。未经允许私自转载拍明芯城将保留追究其法律责任的权利。

拍明芯城拥有对此声明的最终解释权。

标签: FS4412 ARM芯片 ARM

相关资讯