历史上的今天
返回首页

历史上的今天

今天是:2024年12月30日(星期一)

正在发生

2021年12月30日 | STM32F103外部中断实现

2021-12-30 来源:eefocus

中断是单片机中最重要的一个功能了,通过中断可以提高程序的运行效率,可以是单片机及时的响应各种外设的请求。STM32系列单片机的中断主要由嵌套向量中断控制器来管理。


嵌套向量中断控制器特性如下:


68个可屏蔽中断通道(不包含16个Cortex™-M3的中断线);

16个可编程的优先等级(使用了4位中断优先级);

低延迟的异常和中断处理;

电源管理控制;


系统控制寄存器的实现;

嵌套向量中断控制器( NVIC ) 和处理器核的接口紧密相连,可以实现低延迟的中断处理和高效地处理晚到的中断。


外部中断/事件控制器由19个能产生事件/中断请求的边沿检测器。每个输入线可以独立地配置输入类型(脉冲或挂起)和对应的触发事件(上升沿或下降沿或者双边沿都触发)。每个输入线都可以独立地被屏蔽。挂起寄存器保持着状态线的中断请求。


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


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

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

支持多达20个软件的中断/事件请求

检测脉冲宽度低于APB2时钟宽度的外部信号。参见数据手册中电气特性部分的相关参数。


中断控制框图如下:

image.png?imageView2/2/w/550

下面用按键口作为中断检测口,来演示一下中断的使用方法。


//KEY0 PC1  KEY1 PC13  WK_UP  PA0


void KEY_Init(void)

{

    GPIO_InitTypeDef GPIO_InitStructure;

    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA | RCC_APB2Periph_GPIOC, ENABLE);


    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_1 | GPIO_Pin_13;

    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU; //上拉输入

    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;

    GPIO_Init(GPIOC, &GPIO_InitStructure);


    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0;

    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPD; //下拉输入

    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;

    GPIO_Init(GPIOA, &GPIO_InitStructure);

}


首先初始化按键所使用的IO口,这里使用了三个按键,其中一个按键默认为低电平,按键按下后为高电平。其余两个按键默认是高电平,按下按键后为低电平。 下面开始初始化中断。


//KEY0 PC1  KEY1 PC13  WK_UP  PA0

void EXTIx_Init(void)

{

    EXTI_InitTypeDef EXTI_InitStructure;

    NVIC_InitTypeDef NVIC_InitStructure;


    // 1、初始化IO

    KEY_Init(); //按键端口初始化

    // 2、开启AFIO时钟

    RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO, ENABLE); //使能复用功能时钟

    // 3、设置IO口与中断线的映射关系

    GPIO_EXTILineConfig(GPIO_PortSourceGPIOA, GPIO_PinSource0); //PA0

    // 4、初始化线上中断,设置触发条件

    EXTI_InitStructure.EXTI_Line = EXTI_Line0; //WK_UP 上升沿

    EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt;

    EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Rising;

    EXTI_InitStructure.EXTI_LineCmd = ENABLE;

    EXTI_Init(&EXTI_InitStructure);


    GPIO_EXTILineConfig(GPIO_PortSourceGPIOC, GPIO_PinSource1); //PC1


    EXTI_InitStructure.EXTI_Line = EXTI_Line1; //KEY0 下降沿

    EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt;

    EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Falling;

    EXTI_InitStructure.EXTI_LineCmd = ENABLE;

    EXTI_Init(&EXTI_InitStructure);


    GPIO_EXTILineConfig(GPIO_PortSourceGPIOC, GPIO_PinSource13);//PC13


    EXTI_InitStructure.EXTI_Line = EXTI_Line13; //KEY1 上升沿

    EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt;

    EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Falling;

    EXTI_InitStructure.EXTI_LineCmd = ENABLE;

    EXTI_Init(&EXTI_InitStructure);

    // 5、配置中断分组,并使能中断

    NVIC_InitStructure.NVIC_IRQChannel = EXTI0_IRQn;

    NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0x02;

    NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0x03;

    NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;

    NVIC_Init(&NVIC_InitStructure);


    NVIC_InitStructure.NVIC_IRQChannel = EXTI1_IRQn;

    NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0x02;

    NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0x02;

    NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;

    NVIC_Init(&NVIC_InitStructure);


    NVIC_InitStructure.NVIC_IRQChannel = EXTI15_10_IRQn;

    NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0x02;

    NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0x01;

    NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;

    NVIC_Init(&NVIC_InitStructure);

}


void EXTI0_IRQHandler(void)

{

    if(EXTI_GetITStatus(EXTI_Line0) != RESET)

    {

        delay_ms(10);

        if(WK_UP == 1)

        {

            LED0 = !LED0;

            LED1 = !LED1;

        }

        EXTI_ClearITPendingBit(EXTI_Line0);

    }

}

void EXTI1_IRQHandler(void)

{

    if(EXTI_GetITStatus(EXTI_Line1) != RESET)

    {

        delay_ms(10);

        if(KEY0 == 1)

        {

            LED0 = !LED0;

        }

        EXTI_ClearITPendingBit(EXTI_Line1);

    }

}

void EXTI15_10_IRQHandler(void)

{

    if(EXTI_GetITStatus(EXTI_Line13) != RESET)

    {

        delay_ms(10);

        if(KEY1 == 1)

        {

            LED1 = !LED1;

        }

        EXTI_ClearITPendingBit(EXTI_Line13);

    }


}


初始化中断时需要设置每个IO口对应的中断线,中断线对应关系如下图:

image.png?imageView2/2/w/550

通过上图可以看出所有的P0口对应的都是中断线0,所有的P1口对应的都是中断线1,依次类推。这里使用的三个按键分别是PC1、PC13、PA0,也就是对应的中断线为中断线1、中断线13、中断线0。


中断线设置完成之后,还需要设置中断分组,也就是设置中断的优先级,当中断同时触发的时候,优先级越高的中断优先处理。


中断线设置好之后,还需要提供中断入口函数,因为中断触发后,系统就会自动跳转到中断入口函数中,执行中断函数的代码。每个中断入口的函数名称都是固定的,不能自己定义。中断函数的入口名称可以在startup_stm32f10x_hs.s文件中查看。


                ; External Interrupts

                DCD     WWDG_IRQHandler            ; Window Watchdog

                DCD     PVD_IRQHandler             ; PVD through EXTI Line detect

                DCD     TAMPER_IRQHandler          ; Tamper

                DCD     RTC_IRQHandler             ; RTC

                DCD     FLASH_IRQHandler           ; Flash

                DCD     RCC_IRQHandler             ; RCC

                DCD     EXTI0_IRQHandler           ; EXTI Line 0

                DCD     EXTI1_IRQHandler           ; EXTI Line 1

                DCD     EXTI2_IRQHandler           ; EXTI Line 2

                DCD     EXTI3_IRQHandler           ; EXTI Line 3

                DCD     EXTI4_IRQHandler           ; EXTI Line 4

                DCD     DMA1_Channel1_IRQHandler   ; DMA1 Channel 1

                DCD     DMA1_Channel2_IRQHandler   ; DMA1 Channel 2

                DCD     DMA1_Channel3_IRQHandler   ; DMA1 Channel 3

                DCD     DMA1_Channel4_IRQHandler   ; DMA1 Channel 4

                DCD     DMA1_Channel5_IRQHandler   ; DMA1 Channel 5

                DCD     DMA1_Channel6_IRQHandler   ; DMA1 Channel 6

                DCD     DMA1_Channel7_IRQHandler   ; DMA1 Channel 7

                DCD     ADC1_2_IRQHandler          ; ADC1 & ADC2

                DCD     USB_HP_CAN1_TX_IRQHandler  ; USB High Priority or CAN1 TX

                DCD     USB_LP_CAN1_RX0_IRQHandler ; USB Low  Priority or CAN1 RX0

                DCD     CAN1_RX1_IRQHandler        ; CAN1 RX1

                DCD     CAN1_SCE_IRQHandler        ; CAN1 SCE

                DCD     EXTI9_5_IRQHandler         ; EXTI Line 9..5

                DCD     TIM1_BRK_IRQHandler        ; TIM1 Break

                DCD     TIM1_UP_IRQHandler         ; TIM1 Update

                DCD     TIM1_TRG_COM_IRQHandler    ; TIM1 Trigger and Commutation

                DCD     TIM1_CC_IRQHandler         ; TIM1 Capture Compare

                DCD     TIM2_IRQHandler            ; TIM2

                DCD     TIM3_IRQHandler            ; TIM3

                DCD     TIM4_IRQHandler            ; TIM4

                DCD     I2C1_EV_IRQHandler         ; I2C1 Event

                DCD     I2C1_ER_IRQHandler         ; I2C1 Error

推荐阅读

史海拾趣

E-Switch公司的发展小趣事

在E-Switch的发展历程中,品质一直是公司最为重视的方面之一。公司始终坚持严格的质量管理体系,从原材料采购到生产流程控制,再到产品出厂检验,每一个环节都严格把关。正是这种对品质的执着追求,让E-Switch的产品在市场上赢得了良好的口碑。

ECI公司的发展小趣事

ECI公司深知人才是企业发展的关键因素。因此,公司高度重视人才的引进、培养和激励。公司建立了完善的人才选拔机制,选拔具有潜力和才华的员工进行重点培养。同时,公司还提供了丰富的培训和发展机会,帮助员工提升自身素质和能力。此外,ECI还建立了科学合理的薪酬制度和激励机制,让员工在为公司创造价值的同时也能获得相应的回报。这种对人才的重视和投入让ECI公司汇聚了一批优秀的员工队伍,为公司的发展提供了有力的保障。

ETA Electric Industry Co Ltd公司的发展小趣事

进入新世纪,ETA Electric Industry Co Ltd意识到技术创新是企业发展的关键。于是,公司开始加大研发投入,引进了一批高素质的研发人员。他们专注于开发新型电子元器件,特别是在微型化、高性能方面取得了显著成果。其中,他们研发的一种新型微型电容器,因其体积小、性能稳定而广受好评。这一技术创新不仅提升了公司的市场竞争力,还为公司赢得了更多的合作机会。

Greenwich Instruments Ltd公司的发展小趣事

面对日益激烈的市场竞争和不断变化的客户需求,Greenconn Corp积极推动智能制造转型。公司引进先进的生产设备和技术,优化生产流程和管理模式,提高生产效率和产品质量。同时,公司还加强与高校、科研机构的合作,共同研发智能制造关键技术,推动智能制造技术在连接器生产领域的应用。这些努力不仅提升了Greenconn Corp的竞争力,还为公司的可持续发展奠定了坚实基础。

AirBorn公司的发展小趣事

在航空航天领域,AirBorn的产品广泛应用于飞机、导弹系统、通信设备等关键领域。为了满足航空航天领域对连接器的严苛要求,AirBorn不断投入研发力量,推出了一系列具有高性能、高可靠性的连接器产品。这些产品不仅满足了航空航天领域的需求,还为公司带来了可观的收益。

长运通(CYT)公司的发展小趣事

在市场竞争日益激烈的背景下,长运通积极拓展市场,加强品牌建设。公司不仅在国内市场取得了良好的销售业绩,还积极开拓国际市场,与多家国际知名企业建立了合作关系。同时,长运通也注重品牌形象的塑造和传播,通过参加各种展会、论坛等活动,提升公司的知名度和影响力。这些努力使得长运通在电子行业中树立了良好的品牌形象。

问答坊 | AI 解惑

单片机模拟类红外接收仿真

本帖最后由 paulhyde 于 2014-9-15 09:00 编辑 单片机模拟类红外接收仿真  …

查看全部问答>

反射型光电探测器 RPR220

本帖最后由 paulhyde 于 2014-9-15 03:32 编辑 反射型光电探测器 RPR220 中英文资料    …

查看全部问答>

有做过ARM和PFGA通讯的吗?

来自:EEWORLD合作群63762526,群主:wangkj…

查看全部问答>

SKYEYE

我在ubuntu 下想用skyeye 模拟硬件平台,可是发现xtem 启动不了,而且无法动态地调试,加载程序! 当然可以单独地启动xtem ,到底是什么原因,渴求高手指点啊! …

查看全部问答>

问一个memcpy的问题

在我的程序中使用memcpy除了点问题,pBufOut 是一个BYTE的指针,pbuf是局部变量的数组, BYTE pbuf[40]; memcpy( pBufOut, pbuf + 3, 32 ); 执行memcpy后调试信息就出来一大堆: Data Abort: Thread=8fc7e550 Proc=89a8ca60 \'OwireTest.exe\' ...…

查看全部问答>

WinCE中保存信息的方法

  如题,我想数据量不大的情况下,用.ini文件来保存,所以程序可以实现读写.ini文件。 但是问题出现了,想人工手动修改这个.ini文件的配置信息,直接双击在WinCE里面打不开,然后复制出来到Windows上,打开了,但是中文字信息看不清(是 ...…

查看全部问答>

LED半导体照明电源及控制电路

replyreload += \',\' + 687345;Timson,如果您要查看本帖隐藏内容请回复…

查看全部问答>

工程師應該掌握的20個模擬電路 完整PDF檔案

一、桥式整流电路二、电源滤波器三、信号滤波器四、微分和积分电路...…

查看全部问答>

调EEPROm出现的问题

在调EEPROM(IIC),板子上电后第一次运行程序,可以正常运行,但是,再重新下载一次程序再运行,Serial Bus一直处于忙状态,无法进行正常读写,这是为什么 …

查看全部问答>

main中的raw_memcpy((void *)0, (void *)(exception_vector), 128)

我在main函数中看到这个函数 raw_memcpy((void *)0, (void *)(exception_vector), 128); 有点不理解这个的意思 这里的\"0\"表示的是什么? 最终把什么东西复制到了\"0\"处? 麻烦回答一下啊…

查看全部问答>