首页 > 其他分享 >[单片机框架][bsp层][AT32F415][bsp_exti] EXTI配置和使用

[单片机框架][bsp层][AT32F415][bsp_exti] EXTI配置和使用

时间:2022-10-31 18:03:02浏览次数:46  
标签:AT32F415 单片机 irq void bsp callback NULL EXTI


7.2.1 主要特性
EXTI 控制器的主要特性如下:
● 每个中断/事件都有独立的触发和屏蔽
● 每个中断线都有专用的状态位
● 支持多达 23 个软件的中断/事件请求
● 检测脉冲宽度低于 APB2 时钟宽度的外部信号。参见数据手册中电气特性部分的相关参数。

7.2.4 功能说明
要产生中断,必须先配置好并使能中断线。根据需要的边沿检测设置 2 个触发寄存器,同时在中断屏蔽寄存器的相应位写’1’允许中断请求。当外部中断线上发生了期待的边沿时,将产生一个中断请求,对应的挂起位也随之被置’1’。在挂起寄存器的对应位写’1’,将清除该中断请求。
如果需要产生事件,必须先配置好并使能事件线。根据需要的边沿检测设置 2 个触发寄存器,同时在事件屏蔽寄存器的相应位写’1’允许事件请求。当事件线上发生了需要的边沿时,将产生一个事件请求脉冲,对应的挂起位不被置’1’。
通过在软件中断/事件寄存器写’1’,也可以通过软件产生中断/事件请求。
硬件中断选择 通过下面的过程来配置 23 个线路做为中断源:
● 配置23个中断线的屏蔽位(EXTI_INTEN)
● 配置所选中断线的触发选择位(EXTI_RTRSEL和EXTI_FTRSEL);
● 配置对应到外部中断控制器(EXTI)的NVIC中断通道的使能和屏蔽位,使得23个中断线中的请求可以被正确地响应。

硬件事件选择
通过下面的过程,可以配置 23 个线路为事件源
● 配置23个事件线的屏蔽位(EXTI_EVTEN)
● 配置事件线的触发选择位(EXTI_RTRSEL和EXTI_FTRSEL)

软件中断/事件的选择
23 个线路可以被配置成软件中断/事件线。下面是产生软件中断的过程:
● 配置23个中断/事件线屏蔽位(EXTI_INTEN, EXTI_EVTEN)
● 设置软件中断寄存器的请求位(EXTI_SWIE)

[单片机框架][bsp层][AT32F415][bsp_exti] EXTI配置和使用_AT32F415

另外七个 EXTI 线的连接方式如下:
● EXTI 线 16 连接到 PVD 输出
● EXTI 线 17 连接到 ERTC 闹钟事件
● EXTI 线 18 连接到 USB OTG FS 唤醒事件
● EXTI 线 19 连接到 COMP1 唤醒事件
● EXTI 线 20 连接到 COMP2 唤醒事件
● EXTI 线 21 连接到 ERTC 入侵和时间戳事件
● EXTI 线 22 连接到 ERTC 唤醒事件

/********************************************************************************
* @file bsp_exti.c
* @author jianqiang.xue
* @version V1.0.0
* @date 2021-09-30
* @brief NULL
********************************************************************************/
/* Includes ------------------------------------------------------------------*/
#include <stdio.h>
#include <stdint.h>
#include <stdbool.h>

#include "RTE_Components.h"
#include CMSIS_device_header

#include "sys_api.h"
/* Private Includes ----------------------------------------------------------*/
/* Private Define ------------------------------------------------------------*/
/* Private Variables ---------------------------------------------------------*/
bool bsp_exti_init = false;

typedef void(*bsp_gpio_exti_callback)(void *gpiox, uint16_t gpio_pin);
static bsp_gpio_exti_callback g_irq_callback;
/* Public Function Prototypes ------------------------------------------------*/
/**
* @brief 设置外部中断NVIC
* @param irqn: 中断号(在typedef enum IRQn中,例如:USART1_IRQn)
* @param priority: 中断优先级
*/
void bsp_exit_set(uint8_t irqn, uint32_t priority)
{
if (!bsp_exti_init)
{
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);
bsp_exti_init = true;
}
NVIC_InitType NVIC_InitStructure;
NVIC_InitStructure.NVIC_IRQChannel = irqn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = priority;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0x0;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
}

/**
* @brief 清除外部中断设置
* @param irqn: 中断号(在typedef enum IRQn中,例如:USART1_IRQn)
*/
void bsp_exit_clear_set(uint8_t irqn)
{
EXTI_ClearIntPendingBit((IRQn_Type)(irqn));
}

/**
* @brief 清除外部中断标志位
* @param *gpiox: 预留
* @param pin: 引脚号
*/
void bsp_exit_clear_flag(void *gpiox, uint8_t pin)
{
EXTI_ClearFlag(1 << pin);
}

/**
* @brief 注册外部中事件回调函数
* @param *event: 事件函数
*/
bool bsp_gpio_exit_irq_register_callback(void *event)
{
if (g_irq_callback != NULL)
{
return false;
}
else
{
g_irq_callback = (bsp_gpio_exti_callback)event;
}
return true;
}

/**
* @brief This function handles External lines 0 interrupt request.
*/
void EXTI0_IRQHandler(void)
{
if (EXTI_GetIntStatus(EXTI_Line0) != RESET)
{
/* Write the descriptor through the endpoint */
/* Clear the EXTI line 0 pending bit */
EXTI_ClearIntPendingBit(EXTI_Line0);
if (g_irq_callback)
{
g_irq_callback(NULL, 0);
}
}
}

/**
* @brief This function handles External lines 1 interrupt request.
*/
void EXTI1_IRQHandler(void)
{
if (EXTI_GetIntStatus(EXTI_Line1) != RESET)
{
/* Write the descriptor through the endpoint */
/* Clear the EXTI line 1 pending bit */
EXTI_ClearIntPendingBit(EXTI_Line1);
if (g_irq_callback)
{
g_irq_callback(NULL, 1);
}
}
}

/**
* @brief This function handles External lines 2 interrupt request.
*/
void EXTI2_IRQHandler(void)
{
if (EXTI_GetIntStatus(EXTI_Line2) != RESET)
{
/* Write the descriptor through the endpoint */
/* Clear the EXTI line 2 pending bit */
EXTI_ClearIntPendingBit(EXTI_Line2);
if (g_irq_callback)
{
g_irq_callback(NULL, 2);
}
}
}

/**
* @brief This function handles External lines 3 interrupt request.
*/
void EXTI3_IRQHandler(void)
{
if (EXTI_GetIntStatus(EXTI_Line3) != RESET)
{
/* Write the descriptor through the endpoint */
/* Clear the EXTI line 3 pending bit */
EXTI_ClearIntPendingBit(EXTI_Line3);
if (g_irq_callback)
{
g_irq_callback(NULL, 3);
}
}
}

/**
* @brief This function handles External lines 4 interrupt request.
*/
void EXTI4_IRQHandler(void)
{
if (EXTI_GetIntStatus(EXTI_Line4) != RESET)
{
/* Write the descriptor through the endpoint */
/* Clear the EXTI line 4 pending bit */
EXTI_ClearIntPendingBit(EXTI_Line4);
if (g_irq_callback)
{
g_irq_callback(NULL, 4);
}
}
}

/**
* @brief This function handles External lines 9 to 5 interrupt request.
*/
void EXTI9_5_IRQHandler(void)
{
if (EXTI_GetIntStatus(EXTI_Line9) != RESET)
{
//<Clear the EXTI line 9 pending bit
EXTI_ClearIntPendingBit(EXTI_Line9);
if (g_irq_callback)
{
g_irq_callback(NULL, 9);
}
}
else if (EXTI_GetIntStatus(EXTI_Line8) != RESET)
{
//<Clear the EXTI line 8 pending bit
EXTI_ClearIntPendingBit(EXTI_Line8);
if (g_irq_callback)
{
g_irq_callback(NULL, 8);
}
}
else if (EXTI_GetIntStatus(EXTI_Line7) != RESET)
{
//<Clear the EXTI line 7 pending bit
EXTI_ClearIntPendingBit(EXTI_Line7);
if (g_irq_callback)
{
g_irq_callback(NULL, 7);
}
}
else if (EXTI_GetIntStatus(EXTI_Line6) != RESET)
{
//<Clear the EXTI line 6 pending bit
EXTI_ClearIntPendingBit(EXTI_Line6);
if (g_irq_callback)
{
g_irq_callback(NULL, 6);
}
}
else if (EXTI_GetIntStatus(EXTI_Line5) != RESET)
{
//<Clear the EXTI line 5 pending bit
EXTI_ClearIntPendingBit(EXTI_Line5);
if (g_irq_callback)
{
g_irq_callback(NULL, 5);
}
}
}

/**
* @brief This function handles External lines 15 to 10 interrupt request.
*/
void EXTI15_10_IRQHandler(void)
{
if (EXTI_GetIntStatus(EXTI_Line15) != RESET)
{
//<Clear the EXTI line 15 pending bit
EXTI_ClearIntPendingBit(EXTI_Line15);
if (g_irq_callback)
{
g_irq_callback(NULL, 15);
}
}
else if (EXTI_GetIntStatus(EXTI_Line14) != RESET)
{
//<Clear the EXTI line 14 pending bit
EXTI_ClearIntPendingBit(EXTI_Line14);
if (g_irq_callback)
{
g_irq_callback(NULL, 14);
}
}
else if (EXTI_GetIntStatus(EXTI_Line13) != RESET)
{
//<Clear the EXTI line 13 pending bit
EXTI_ClearIntPendingBit(EXTI_Line13);
if (g_irq_callback)
{
g_irq_callback(NULL, 13);
}
}
else if (EXTI_GetIntStatus(EXTI_Line12) != RESET)
{
//<Clear the EXTI line 12 pending bit
EXTI_ClearIntPendingBit(EXTI_Line12);
if (g_irq_callback)
{
g_irq_callback(NULL, 12);
}
}
else if (EXTI_GetIntStatus(EXTI_Line11) != RESET)
{
//<Clear the EXTI line 11 pending bit
EXTI_ClearIntPendingBit(EXTI_Line11);
if (g_irq_callback)
{
g_irq_callback(NULL, 11);
}
}
else if (EXTI_GetIntStatus(EXTI_Line10) != RESET)
{
//<Clear the EXTI line 10 pending bit
EXTI_ClearIntPendingBit(EXTI_Line10);
if (g_irq_callback)
{
g_irq_callback(NULL, 10);
}
}
}
/********************************************************************************
* @file bsp_exti.h
* @author jianqiang.xue
* @version V1.0.0
* @date 2021-04-09
* @brief NULL
********************************************************************************/

#ifndef __BSP_EXTI_H
#define __BSP_EXTI_H

/* Includes ------------------------------------------------------------------*/
#include <stdint.h>

/* Public Function Prototypes ------------------------------------------------*/

void bsp_exit_set(uint8_t irqn, uint32_t priority);
void bsp_exit_clear_set(uint8_t irqn);
void bsp_exit_clear_flag(void *gpiox, uint8_t pin);

// 引脚外部中断回调

bool bsp_gpio_exit_irq_register_callback(void *event);

#endif


标签:AT32F415,单片机,irq,void,bsp,callback,NULL,EXTI
From: https://blog.51cto.com/xuejianqiang/5810732

相关文章