系列文章目录
1.连续打卡第一天:提前对CPK_RA2E1是瑞萨RA系列开发板的初体验,了解一下
5.Keil配置使用(使用 RASC 生成 Keil 工程)
6.Keil配置使用(使用 RASC 生成 Keil 工程)
文章目录
目录
3.选择“New Stack”后,依次选择“Input”、“Extern IRQ Driver on r_icu”。
4.选择“FSP Configuration”后,点击“g_external_irq0_External IRQ r_icu”,如下图所示。
5.在“g_external_irq0_External IRQ r_icu”栏中,可以根据需求选择“Trigger”模式,使能“Digital Filtering”,并为外部中断回调函数命名
前言
时钟讲完,立即该接上我们的外部中断这一块了,外部中断这一块也是咱们必修之一,非常之重要,于是外部中断这篇文章应运而生。后续也会接着定时器,讲定时器中断。
一、RA2E1中断是什么?
ICU(中断控制单元)负责控制哪些中断信号链接到NVIC和DTC模块。在RA产品中使用ICU来配置外部中断。
中断控制器单元(ICU)控制着一些事件发出的信号,从而链接到嵌套矢量中断控制器(NVIC)、DMA控制器(DMAC)和数据传输控制器(DTC)模块。ICU还控制着不可屏蔽的中断。 所以可以说围绕着 ICU 的有四个部分:NVIC、DMAC、DTC和NMI。
模块1 | NMI | 不可屏蔽的中断 |
模块2 | NVIC | 嵌套向量中断控制器 |
模块3 | DTC | 数据传输控制器 |
模块4 | DMAC | 直接内存访问控制器 |
其中在ICU里最重要的是NVIC,它是属于内核级别的中断控制器。其次是DTC,用于提供在被中断请求激活时传输数据的功能。之后是DMAC,当产生DMA传输请求时,DMAC将存储在传输源地址的数据传输到传输目的地地址。最后是NMI不可屏蔽中断NonMaskable,用于处理非常紧急的事件。
其实对学过stm32的同学,应该是不陌生NVIC的操作。
NVIC 英文名全称:(Nested Vector Interrupt Controller)中文名:嵌套向量中断控制。 在所有Cortex-M系列处理器中都包含了一个叫做 NVIC 模块,控制着整个芯片中断相关的功能,它跟内核紧密耦合,是内核里面的一个外设。但是各个芯片厂商在设计芯片的时候会对Cortex-M系列的内核里面的NVIC进行裁剪。
NVIC能够处理系统异常比如复位和一些系统错误,NVIC还能够处理中断源,比如定时器中断、外部中断等。
RA系列MCU在内核水平上搭载了一个异常响应系统,支持为数众多的系统异常和外部中断。其中系统异常有8个(如果把Reset和HardFault也算上的话就是10个)。 除了个别异常的优先级被定死外,其它异常的优先级都是可编程的。 有关具体的系统异常和外部中断可在core_cm33.h这个头文件查询到,在IRQn_Type这个结构体里面包含了RA系列MCU全部的异常声明。
中断向量嵌套控制器是用来管理所有中断和事件的,包括中断的使能和除能,中断的优先级。这个是属于内核的东西。
代码 15‑1 NVIC结构体定义,来自固件库头文件:core_cm33.h
typedef struct
{
__IOM uint32_t ISER[16U]; // 中断使能寄存器
uint32_t RESERVED0[16U];
__IOM uint32_t ICER[16U]; //中断清除使能寄存器
uint32_t RSERVED1[16U];
__IOM uint32_t ISPR[16U]; //中断挂起寄存器
uint32_t RESERVED2[16U];
__IOM uint32_t ICPR[16U]; //中断清除挂起寄存器
uint32_t RESERVED3[16U];
__IOM uint32_t IABR[16U]; // 中断激活寄存器\中断有效位寄存器
uint32_t RESERVED4[16U];
__IOM uint32_t ITNS[16U]; //中断目标安全寄存器
uint32_t RESERVED5[16U];
__IOM uint8_t IPR[496U]; // 中断优先级寄存器
uint32_t RESERVED6[580U];
__OM uint32_t STIR;
} NVIC_Type;
二、中断设置
1.NVIC设置
2.外部中断编程
RA2E1开发板支持16个中断优先级,优先级从0到15,数值越小的中断优先级越高。具体的中断优先级如下:
中断优先级 中断源 0 NMI 1 WDT 2 LVD 3 RTC 4 S12AD 5 TAU0 6 TAU1 7 TAU2 8 TAU3 9 TAU4 10 TAU5 11 DMAC0 12 DMAC1 13 DMAC2 14 DMAC3 15 DMAC4
3.FSP配置
双击 configuration.xml 打开配置界面: 然后点开依次点击 Stacks -> Peripherals -> Storage -> New Stack -> Input-> IRQ 来配置外部中断模块。
IRQ页面的属性介绍
IRQ属性 | 描述 |
---|---|
Name | 名称 |
Channel | 通道 |
Trigger | 触发方式 |
Digital Filtering | 滤波 |
Callback | 中断服务回调函数 |
Pin Input priority | 中断优先级 |
三、实操
1.新建工程
2.选择“Stacks”选项栏
3.选择“New Stack”后,依次选择“Input”、“Extern IRQ Driver on r_icu”。
4.选择“FSP Configuration”后,点击“g_external_irq0_External IRQ r_icu”,如下图所示。
5.在“g_external_irq0_External IRQ r_icu”栏中,可以根据需求选择“Trigger”模式,使能“Digital Filtering”,并为外部中断回调函数命名
6. 完成设置后,点击“Generate Project Content”,待右下方进度条完成后,配置结束。
7.外部中断初始化
/* IRQ初始化函数 */
void IRQ_Init(void)
{
/* 初始化外部中断*/
R_ICU_ExternalIrqOpen(int0.p_ctrl,int0.p_cfg);
R_ICU_ExternalIrqEnable(int0.p_ctrl);
}
R_ICU_ExternalIrqOpen()配置一个IRQ输入引脚与外部中断接口一起使用。
R_ICU_ExternalIrqEnable()在NVIC为指定通道启用外部中断。
#include "hal_data.h"
FSP_CPP_HEADER
void R_BSP_WarmStart(bsp_warm_start_event_t event);
FSP_CPP_FOOTER
#define LED1_ON R_IOPORT_PinWrite(&g_ioport_ctrl, BSP_IO_PORT_05_PIN_01, BSP_IO_LEVEL_LOW)
#define LED2_ON R_IOPORT_PinWrite(&g_ioport_ctrl, BSP_IO_PORT_05_PIN_02, BSP_IO_LEVEL_LOW)
#define LED1_OFF R_IOPORT_PinWrite(&g_ioport_ctrl, BSP_IO_PORT_05_PIN_01, BSP_IO_LEVEL_HIGH)
#define LED2_OFF R_IOPORT_PinWrite(&g_ioport_ctrl, BSP_IO_PORT_05_PIN_02, BSP_IO_LEVEL_HIGH)
#define Irq_io_ON R_IOPORT_PinWrite(&g_ioport_ctrl, BSP_IO_PORT_04_PIN_11, BSP_IO_LEVEL_HIGH)
#define Irq_io_OFF R_IOPORT_PinWrite(&g_ioport_ctrl, BSP_IO_PORT_04_PIN_11, BSP_IO_LEVEL_LOW)
#define KEY_ON 1
#define KEY_OFF 0
/* 开发板,两个按键引脚定义 */
#define KEY1_SW2_PIN BSP_IO_PORT_00_PIN_04
#define LED_Red BSP_IO_PORT_05_PIN_01
uint32_t Key_Scan(bsp_io_port_pin_t key)
{
bsp_io_level_t state;
// 读取按键引脚电平
R_IOPORT_PinRead(&g_ioport_ctrl, key, &state);
if (BSP_IO_LEVEL_HIGH == state)
{
return KEY_OFF; //按键没有被按下
}
else
{
do //等待按键释放
{
R_IOPORT_PinRead(&g_ioport_ctrl, key, &state);
} while (BSP_IO_LEVEL_LOW == state);
}
return KEY_ON; //按键被按下了
}
/* 简单的软件延时函数
使用不同的系统时钟,延时不一样
*/
void Delay(__IO uint32_t nCount)
{
for(; nCount != 0; nCount--);
}
/* IRQ初始化函数 */
void IRQ_Init(void)
{
/* 初始化外部中断*/
R_ICU_ExternalIrqOpen(int0.p_ctrl,int0.p_cfg);
R_ICU_ExternalIrqEnable(int0.p_ctrl);
}
bsp_io_level_t int0_status = BSP_IO_LEVEL_LOW; //状态结构体
/* 中断服务回调函数 */
void int0_callback(external_irq_callback_args_t *p_args) //当产生中断时会访问中断服务函数
{
(void) p_args;
R_IOPORT_PinWrite(&g_ioport_ctrl, LED_Red, int0_status);
int0_status =~ int0_status;
}
/*******************************************************************************************************************//**
* main() is generated by the RA Configuration editor and is used to generate threads if an RTOS is used. This function
* is called by main() when no RTOS is used.
**********************************************************************************************************************/
void hal_entry(void)
{
R_IOPORT_Open (&g_ioport_ctrl, g_ioport.p_cfg);
IRQ_Init();
LED1_ON;
LED2_ON;
while(1)
{
}
#if BSP_TZ_SECURE_BUILD
/* Enter non-secure code */
R_BSP_NonSecureEnter();
#endif
}
视频效果:
RA2E1 外部中断 控制led闪烁
总结
外部中断已完结!下一步定时器!!!加油,希望文章能对大家有所帮助。