跳转到主要内容

MM32F0140 EXTI 学习笔记

<strong><font color="#004a85"> EXTI简介 </font> </strong>

EXTI是外部中断/事件控制器,包含多个边沿检测器,通过检测I/O端口的电平变化判断是否产生中断/事件请求。

MM32F0140的EXTI包含19个外部中断线,其中外部中断线EXTI0 ~ EXTI15用于I/O映射,EXTI16连接到PVD输出,EXTI19连接到比较器1输出,EXTI24连接到IWDG中断。可通过软件控制任意一个I/O端口作为EXTI的输入源,EXTI检测对应端口是否产生边沿触发,若检测到边沿触发则产生中断/事件请求,GPIO对应的16个外部中断/事件映射关系如图1所示。

<center><img src="http://mcu.eetrend.com/files/2022-02/wen_zhang_/100558015-243977-1.png&…; alt=“图1 MM32F0140 GPIO对应外部中断/事件映射"></center><center><i>图1 MM32F0140 GPIO对应外部中断/事件映射</i></center>

EXTI进行边沿检测时包含三种触发类型:

<strong>上升沿触发</strong>

电平由低到高时的一瞬间称为上升沿,由上升沿的产生触发输出变化就称作上升沿触发。

<strong>下降沿触发</strong>

电平由高到低时的一瞬间称为下降沿,由下降沿的产生触发输出变化则称为下降沿触发。

<strong>任意边沿触发</strong>

电平由上升沿或下降沿的产生而触发输出变化被称作任意边沿触发。

中断/事件产生过程如图2所示,EXTI边沿检测引脚的外部输入电平,若由于外部因素导致引脚电平变化并产生边沿触发,则边沿检测电路输出有效信号。或门电路接收边沿检测电路输出的信号与软件事件中断寄存器(EXTI_SWIER)的输出,软件事件中断寄存器能够通过软件启动中断/事件线。当外部中断线上触发边沿事件时,挂起寄存器(EXTI_PR)的对应位被置1,可通过读EXTI_PR寄存器获取当前中断/事件状态。或门电路的输出与中断屏蔽寄存器(EXTI_IMR)的输出相与,在使能对应线中断位且边沿触发有效信号时,输出有效信号到内核的NVIC中,NVIC进行中断处理。或门电路的输出与事件屏蔽寄存器(EXTI_EMR)的输出结果相与,当使能对应事件线位且边沿触发有效信号时,输出有效信号1,即脉冲信号,该脉冲信号可用于其他外设,例如触发TIM。

<center><img src="http://mcu.eetrend.com/files/2022-02/wen_zhang_/100558015-243978-2.png&…; alt=“图2 EXTI模块框图"></center><center><i>图2 EXTI模块框图</i></center>

<strong><font color="#004a85"> EXTI的配置 </font> </strong>

<strong>配置中断</strong>

配置并使能中断线,根据图1判断指定I/O端口对应的外部中断线与SYSCFG_EXTICRx寄存器中的控制位,(EXTI0~EXTI3使用SYSCFG_EXTICR1寄存器,EXTI4~EXTI7使用SYSCFG_EXTICR2寄存器,EXTI8~EXTI11使用SYSCFG_EXTICR3寄存器,EXTI12~EXTI15使用SYSCFG_EXTICR4寄存器)向SYSCFG_EXTICRx寄存器中外部中断线的对应位赋值,若使用PA管脚则对应位赋值为0000,PB管脚对应位赋值为0001,PC管脚对应位赋值为0010,PD管脚对应位赋值为0011。

配置边缘检测触发器的触发类型,若使用上升沿触发,则对上升沿触发选择寄存器(EXTI_RTSR)的外部中断线对应位置1;若使用下降沿触发,则对下降沿触发选择寄存器(EXTI_FTSR)的外部中断线对应位置1;若使用任意边沿触发,则EXTI_RTSR寄存器与EXTI_FTSR寄存器的外部中断线对应位均置1。

中断屏蔽寄存器(EXTI_IMR)的外部中断线对应位置1,允许中断请求。当指定的外部中断线检测到配置的触发条件时,产生一个中断请求,挂起寄存器(EXTI_PR)的对应位置1。通过软件对挂起寄存器中对应位写入1,使中断被清除。

配置软件中断事件寄存器(EXTI_SWIER)的外部中断线对应位为1并置1 EXTI_IMR寄存器的外部中断线对应位,也能产生中断。

<strong>配置事件</strong>

配置并使能事件线,对SYSCFG_EXTICRx寄存器中外部事件线的对应位赋值;配置边缘检测触发寄存器为需要的触发类型,对EXTI_RTSR寄存器与EXTI_FTSR寄存器赋值;事件屏蔽寄存器(EXTI_EMR)的对应位置1,允许事件请求。当检测到配置的触发条件时,产生一个事件请求,挂起寄存器对应位置 1;通过对挂起寄存器对应位写1清除事件。

配置软件中断事件寄存器(EXTI_SWIER)的外部中断/事件线对应位为1并置1 EXTI_EMR寄存器的对应位,也能产生事件。

<strong><font color="#004a85">实验</font> </strong>

本实验在灵动官方开发板MB-023上进行,通过配置EXTI下降沿触发中断,按下按键后产生边沿触发,进行中断处理,LED电平转换。配置按键所使用的I/O端口的对应外部中断线,对SYSCFG_EXTICRx寄存器的EXTIx位赋值,对EXTI_RTSR寄存器和EXTI_FTSR寄存器赋值配置触发类型,使用EXTI_IMR寄存器使能中断,EXTI_PR寄存器对应位置1清除中断。具体实验内容为配置按键K2的对应引脚PB2与LED2对应的PB3引脚(如图3所示),配置PB2对应的外部中断线为下降沿触发,若按下K2,按键对应的端口输入低电平,下降沿触发,产生中断。实验现象为按下按键K2,LED2电平反转一次。

<center><img src="http://mcu.eetrend.com/files/2022-02/wen_zhang_/100558015-243979-3.png&…; alt=“图3 MCU原理图中的EXTI引脚"></center><center><i>图3 MCU原理图中的EXTI引脚</i></center>

<strong>初始化外设时钟</strong>

SYSCFG在APB2线上,GPIO在AHB线上,实验使用SYSCFG配置外部中断,按键K2与LED2的引脚均为GPIOB组的引脚。因此对RCC_APB2ENR寄存器的SYSCFGEN位置1,对RCC_AHBENR寄存器的GPIOB对应位置1,从而初始化外设时钟。

<pre style="overflow-x:auto; background-color:#e9e9e9;">// Enable SYSCFG clock.
RCC->APB2ENR |= (1u &lt;&lt; 0u);
// Enable GPIOB clock.
RCC->AHB1ENR |= (1u &lt;&lt; 18u);</pre>

<strong>初始化按键</strong>

实验使用引脚为PB2的K2按键,按键原理图如图4所示,若K2按键按下则与GND导通,因此在初始化按键时需配置该端口的工作模式为上拉输入。

<center><img src="http://mcu.eetrend.com/files/2022-02/wen_zhang_/100558015-243980-4.png&…; alt=“图4 原理图中的按键"></center><center><i>图4 原理图中的按键</i></center>

GPIOx_CRL寄存器为端口配置低寄存器,用于配置指定端口的速度与工作模式;GPIOx_BSRR寄存器用于设置/清除对应端口,该寄存器低16位的对应端口位置1会产生高电平。由图5所示,K2所使用的端口PB2为GPIOx_CRL寄存器内第8 ~ 11位。

<center><img src="http://mcu.eetrend.com/files/2022-02/wen_zhang_/100558015-243981-5.png&…; alt=“图5 GPIOx_CRL寄存器"></center><center><i>图5 GPIOx_CRL寄存器</i></center>

<pre style="overflow-x:auto; background-color:#e9e9e9;">// Clear the configuration bit of port 2.
GPIOB->CRL &= ~(0xf &lt;&lt; 8u);
// Configure pull-up input mode.
GPIOB->CRL |= (0x8 &lt;&lt; 8u);
// Configure PB2 pin to high level.
GPIOB->BSRR |= (1u &lt;&lt; 2u);</pre>

<strong>初始化LED</strong>

实验使用PB3引脚,使用GPIOx_CRL寄存器对LED进行初始化配置,如图5所示,端口3为GPIOx_CRL寄存器内第12 ~ 15位。

<pre style="overflow-x:auto; background-color:#e9e9e9;">// Clear the configuration bit of port 3.
GPIOB->CRL &= ~(0xf &lt;&lt; 12u);
// Configure push-pull output mode.
GPIOB->CRL |= (0x1 &lt;&lt; 12u);</pre>

<strong>配置中断线</strong>

由图1可知,PB2使用的外部中断线为EXTI2,配置SYSCFG_EXTICR1寄存器的EXTI2对应位为0001,如图6所示,EXTI2处于SYSCFG_EXTICR1寄存器的8~ 11位。

<center><img src="http://mcu.eetrend.com/files/2022-02/wen_zhang_/100558015-243982-6.png&…; alt=“图6 GPIOx_EXTICR1"></center><center><i>图6 GPIOx_EXTICR1</i></center>

<pre style="overflow-x:auto; background-color:#e9e9e9;">// Clear EXTI2 and assign value, the corresponding value of PB is 0001.
SYSCFG->EXTICR1 = ( ( SYSCFG->EXTICR1 & ~(0xf &lt;&lt; 8u) ) | (0x1 &lt;&lt; 8u) );</pre>

<strong>配置触发类型</strong>

在按键初始化中配置按键未按下时处于高电平,因此,对上升沿触发选择寄存器(EXTI_RTSR)与下降沿触发选择寄存器(EXTI_FTSR)赋值时配置触发类型为下降沿触发。

<pre style="overflow-x:auto; background-color:#e9e9e9;">// Clear the corresponding bit of EXTI2 triggered by rising edge.
EXTI->RTSR &= ~ (1u &lt;&lt; 2u);
// Configure falling edge trigger.
EXTI->FTSR |= (1u &lt;&lt; 2u);</pre>

<strong>使能中断</strong>

配置EXTI_IMR寄存器的EXTI2对应位,使能中断。

<pre style="overflow-x:auto; background-color:#e9e9e9;">// Enable EXTI interrupt.
EXTI->IMR |= (1u &lt;&lt; 2u);</pre>

<strong>配置NVIC</strong>

EXTI控制中断,NVIC处理中断,使用Cortex-M0 core_cm0.h头文件中的NVIC_EnableIRQ使能中断线,EXTI2对应中断为EXTI2_3_IRQn。

<pre style="overflow-x:auto; background-color:#e9e9e9;">// Setup NVIC.
NVIC_EnableIRQ (EXTI2_3_IRQn);</pre>

<strong>编写中断服务程序</strong>

中断使能中使用EXTI2_3_IRQn,中断处理函数要与其匹配,因此使用EXTI2_3_IRQHandler,设置变量app_exti_event_on作为中断状态标志,该变量初始时为false,中断请求产生时中断状态标志转换为true,将EXRI_PR寄存器的对应位写入1来清除中断。

<pre style="overflow-x:auto; background-color:#e9e9e9;">void EXTI2_3_IRQHandler(void)
{
uint32_t flags = EXTI->PR;
if ( 0u != ( flags & (1u &lt;&lt; 2u) ) )
{
app_exti_event_on = true;
}

EXTI->PR |= (1u &lt;&lt; 2u); // Clear interrupt.
}</pre>

<strong>main()函数</strong>

主程序中初始化变量app_exti_event_times为0,设置该变量从0开始计数,当中断状态标志app_exti_event_on为true,即产生中断请求时,计数值加1,由于LED2初始化后显示为亮,计算计数值取余2,若余数不等于0则LED2灭,若余数为0则LED2亮。实验效果如图7所示。

<pre style="overflow-x:auto; background-color:#e9e9e9;">int main(void)
{
// Enable SYSCFG and GPIOB clock.
RCC->APB2ENR |= (1u &lt;&lt; 0u);
RCC->AHB1ENR |= (1u &lt;&lt; 18u);

// Setup K2.
GPIOB->CRL &= ~(0xf &lt;&lt; 8u);
GPIOB->CRL |= (0x8 &lt;&lt; 8u);
GPIOB->BSRR |= (1u &lt;&lt; 2u);

// Setup LED2.
GPIOB->CRL &= ~(0xf &lt;&lt; 12u);
GPIOB->CRL |= (0x1 &lt;&lt; 12u);

// Setup SYSCFG EXTI2.
SYSCFG->EXTICR1 = ( ( SYSCFG->EXTICR1 & ~(0xf &lt;&lt; 8u) ) | (0x1 &lt;&lt; 8u) );

// Setup EXTI.
EXTI->RTSR &= ~ (1u &lt;&lt; 2u);
EXTI->FTSR |= (1u &lt;&lt; 2u);

// Enable EXTI interrupt.
EXTI->IMR |= (1u &lt;&lt; 2u);

// Setup NVIC.
NVIC_EnableIRQ (EXTI2_3_IRQn);

while (1)
{
while ( !app_exti_event_on )
{
}
app_exti_event_on = false;

app_exti_event_times++;
if ( (app_exti_event_times % 2u) != 0u )
{

GPIOB->BSRR = (1u &lt;&lt; 3u);// LED2(PB3 pin) off.
}
else
{

GPIOB->BRR = (1u &lt;&lt; 3u);// LED2(PB3 pin) on.
}
}
}</pre>

<center><img src="http://mcu.eetrend.com/files/2022-02/wen_zhang_/100558015-243983-7.gif&…; alt=“图7 实验现象"></center><center><i>图7 实验现象</i></center>

来源:<a href="https://mp.weixin.qq.com/s/p0lOpCmClFB-y3RM-6t3gg"&gt; 灵动MM32MCU</a>
免责声明:本文为转载文章,转载此文目的在于传递更多信息,版权归原作者所有。本文所用视频、图片、文字如涉及作品版权问题,请联系小编进行处理(联系邮箱:cathy@eetrend.com)。