#申请原创# @21小跑堂 @21小跑堂 @21小跑堂
往期回顾
【CPKCOR-RA8D1B核心板】1、板卡基本信息
【CPKCOR-RA8D1B核心板】2、搭建开发环境
【CPKCOR-RA8D1B核心板】3、离不开的点灯——GPIO输出操作
【CPKCOR-RA8D1B核心板】4、另一种闪烁——非阻塞式闪烁
【CPKCOR-RA8D1B核心板】5、不一样的点灯系列——点呼吸灯
【CPKCOR-RA8D1B核心板】6、指示明灯——串口打印
按键作为最直接的交互方式在很多的场景中都被广泛应用,咱们得核心板上也配备了一个用户按键,接下来我们进行一下对外部中断按键状态采集。
首先了解一下外部中断:
上图是ICU框图,根据ICU的功能框图可以知道,首先需要配置IRQCR寄存器(IRQ Control Register,IRQ英文全称:Interrupt ReQuest,中文名:中断请求);之后我们要配置IELSR寄存器(英文全称:ICU Event Link Setting Register,中文名:中断控制单元事件链接设置寄存器);之后使能IR寄存器; 最后我们需要配置NVIC。
当中断来临的时候会最先经过IRQ寄存器,IRQ寄存器检测到中断的时候,会向中央处理嵌套向量中断控制器NVIC发送中断信号, 当NVIC检测到中断请求的时候,会将相应的中断服务函数进行挂起。之后将运行的八个寄存器进行压栈,堆栈完成之后将中断服务程序进行激活。 此时当另一个优先级更高的中断源发生请求的时候,会将相应的中断服务函数进行挂起。之后将当前运行的八个寄存器进行压栈,压栈完成之后将中断服务程序进行激活。 当中断服务程序运行完之后会将原先压栈的寄存器取出,之后继续运行之前中断服务的程序。中断服务程序运行完成之后之后将原先压栈的寄存器取出,继续运行之前的程序。
中断在嵌入式应用中的地位不言而喻,之前的定时器和串口都有使用中断服务,中断对事件得到第一时间处理是非常重要的。 我们设计使用按键来作为触发源,使得控制器产生中断,并在中断服务函数中修改LED以及呼吸灯速率。
硬件按键电路:
另一个按键为复位按键,用于复位MCU芯片,上面这个按键是用户按键,可以用于本次的外部中断实现,对应的引脚是P008,按键按下时P008会出现下降沿和低电平。
软件需要哪些处理呢?
首先配置中断,先去引脚看一下对应的中断(P008-IRQ12):
然后配置引脚状态:
创建外部中断外设:
属性中配置:
外部中断模块(r_icu)的属性介绍如下表所示。
External IRQ 属性
| 描述
| Name
| 名称
| Channel
| 通道(IRQ中断号)
| Trigger
| 触发方式:上升沿、下降沿、双边沿或低电平触发
| Digital Filtering
| 数字滤波使能
| Digital Filtering Sample Clock
(Only valid when Digital Filtering is Enabled)
| 数字滤波采样时钟
| Callback
| 中断回调函数
2个按键外部中断的中断回调函数可以设置为相同,
只需要在函数中判断触发中断的中断号即可互相区分
| Pin Interrupt Priority
| 中断优先级
| 配置完成之后可以按下快捷键“Ctrl + S”保存, 最后点右上角的 “Generate Project Content” 按钮,让软件自动生成配置代码即可。
软件中添加初始化程序:
<article data-content="[{"type":"block","id":"qJuV-1729007702184","name":"code","data":{"wrap":false,"tokensPerLine":[],"language":"","theme":"default"},"nodes":[{"type":"block","id":"FRbM-1729007702183","name":"code-line","data":{},"nodes":[{"type":"text","id":"zZOv-1729007702182","leaves":[{"text":"void Key_IRQ_Init(void){","marks":[]}]}]},{"type":"block","id":"P0ul-1729007704223","name":"code-line","data":{},"nodes":[{"type":"text","id":"LMEk-1729007704222","leaves":[{"text":" fsp_err_t err = FSP_SUCCESS;","marks":[]}]}]},{"type":"block","id":"Kscz-1729007704227","name":"code-line","data":{},"nodes":[{"type":"text","id":"Qby6-1729007704226","leaves":[{"text":" /* Open ICU module */","marks":[]}]}]},{"type":"block","id":"8WcO-1729007704229","name":"code-line","data":{},"nodes":[{"type":"text","id":"SHw3-1729007704228","leaves":[{"text":" err = R_ICU_ExternalIrqOpen(&g_external_irq12_ctrl, &g_external_irq12_cfg);","marks":[]}]}]},{"type":"block","id":"gUfk-1729007704233","name":"code-line","data":{},"nodes":[{"type":"text","id":"G8oN-1729007704232","leaves":[{"text":" err = R_ICU_ExternalIrqEnable(&g_external_irq12_ctrl);","marks":[]}]}]},{"type":"block","id":"9L3j-1729007704237","name":"code-line","data":{},"nodes":[{"type":"text","id":"KjTu-1729007704236","leaves":[{"text":"}","marks":[]}]}]}],"state":{}}]"><div yne-bulb-block="code" data-theme="default" style="white-space-collapse: preserve;" data-language="">void Key_IRQ_Init(void){
fsp_err_t err = FSP_SUCCESS;
/* Open ICU module */
err = R_ICU_ExternalIrqOpen(&g_external_irq12_ctrl, &g_external_irq12_cfg);
err = R_ICU_ExternalIrqEnable(&g_external_irq12_ctrl);
}</div></article>
中断回调函数处理:
<article data-content="[{"type":"block","id":"YRbC-1729007732439","name":"code","data":{"wrap":false,"tokensPerLine":[],"language":"","theme":"default"},"nodes":[{"type":"block","id":"LW3W-1729007732438","name":"code-line","data":{},"nodes":[{"type":"text","id":"DGQi-1729007732437","leaves":[{"text":"void g_external_irq12_Callback(external_irq_callback_args_t *p_args){","marks":[]}]}]},{"type":"block","id":"uwZW-1729007762925","name":"code-line","data":{},"nodes":[{"type":"text","id":"W47j-1729007762924","leaves":[{"text":" /* 判断中断通道 */","marks":[]}]}]},{"type":"block","id":"UvGQ-1729007762927","name":"code-line","data":{},"nodes":[{"type":"text","id":"frvP-1729007762926","leaves":[{"text":" if (12 == p_args->channel){// 用户按键按下","marks":[]}]}]},{"type":"block","id":"UtNW-1729007762929","name":"code-line","data":{},"nodes":[{"type":"text","id":"19S0-1729007762928","leaves":[{"text":" LED.speed++;","marks":[]}]}]},{"type":"block","id":"5J3v-1729007762931","name":"code-line","data":{},"nodes":[{"type":"text","id":"Kaqr-1729007762930","leaves":[{"text":" LED.speed %= 3;","marks":[]}]}]},{"type":"block","id":"4WIo-1729007762933","name":"code-line","data":{},"nodes":[{"type":"text","id":"RGgQ-1729007762932","leaves":[{"text":" }","marks":[]}]}]},{"type":"block","id":"Unpx-1729007762935","name":"code-line","data":{},"nodes":[{"type":"text","id":"ImqI-1729007762934","leaves":[{"text":"}","marks":[]}]}]}],"state":{}}]"><div yne-bulb-block="code" data-theme="default" style="white-space-collapse: preserve;" data-language="">void g_external_irq12_Callback(external_irq_callback_args_t *p_args){
/* 判断中断通道 */
if (12 == p_args->channel){// 用户按键按下
LED.speed++;
LED.speed %= 3;
}
}</div></article>
在定时器中断对LED处理处加入速率控制:
<article data-content="[{"type":"block","id":"sR1t-1729007798556","name":"code","data":{"wrap":false,"tokensPerLine":[],"language":"","theme":"default"},"nodes":[{"type":"block","id":"w4qk-1729007798555","name":"code-line","data":{},"nodes":[{"type":"text","id":"CLdL-1729007798554","leaves":[{"text":"void g_timer0_Callback(timer_callback_args_t * p_args){","marks":[]}]}]},{"type":"block","id":"u76G-1729007813673","name":"code-line","data":{},"nodes":[{"type":"text","id":"KAj2-1729007813672","leaves":[{"text":" if (TIMER_EVENT_CYCLE_END == p_args->event){","marks":[]}]}]},{"type":"block","id":"W33T-1729007813675","name":"code-line","data":{},"nodes":[{"type":"text","id":"TlyD-1729007813674","leaves":[{"text":" LED.timercnt++;","marks":[]}]}]},{"type":"block","id":"BesV-1729007813677","name":"code-line","data":{},"nodes":[{"type":"text","id":"11Ro-1729007813676","leaves":[{"text":" if(LED.timercnt >= 50*(LED.speed+1)){","marks":[]}]}]},{"type":"block","id":"FAo4-1729007813679","name":"code-line","data":{},"nodes":[{"type":"text","id":"G730-1729007813678","leaves":[{"text":" LED.timercnt = 0;","marks":[]}]}]},{"type":"block","id":"3Bm6-1729007813682","name":"code-line","data":{},"nodes":[{"type":"text","id":"GfNz-1729007813681","leaves":[{"text":" LED.flag = 1;","marks":[]}]}]},{"type":"block","id":"lpOC-1729007813684","name":"code-line","data":{},"nodes":[{"type":"text","id":"5zTv-1729007813683","leaves":[{"text":" LED.cnt++;","marks":[]}]}]},{"type":"block","id":"Zlv8-1729007813686","name":"code-line","data":{},"nodes":[{"type":"text","id":"NrSQ-1729007813685","leaves":[{"text":" }","marks":[]}]}]},{"type":"block","id":"Pzjd-1729007813688","name":"code-line","data":{},"nodes":[{"type":"text","id":"5Na7-1729007813687","leaves":[{"text":"","marks":[]}]}]},{"type":"block","id":"HzqE-1729007813690","name":"code-line","data":{},"nodes":[{"type":"text","id":"hzeo-1729007813689","leaves":[{"text":" BreathLED.cnt++;","marks":[]}]}]},{"type":"block","id":"2Vxc-1729007813692","name":"code-line","data":{},"nodes":[{"type":"text","id":"dZen-1729007813691","leaves":[{"text":" if(BreathLED.cnt>5 && BreathLED.cnt<=95){","marks":[]}]}]},{"type":"block","id":"NQSs-1729007813694","name":"code-line","data":{},"nodes":[{"type":"text","id":"JZrK-1729007813693","leaves":[{"text":" GPT4_PWM_SetDuty(BreathLED.cnt);","marks":[]}]}]},{"type":"block","id":"eawf-1729007813696","name":"code-line","data":{},"nodes":[{"type":"text","id":"B5d1-1729007813695","leaves":[{"text":" }","marks":[]}]}]},{"type":"block","id":"jqxj-1729007813698","name":"code-line","data":{},"nodes":[{"type":"text","id":"ltIh-1729007813697","leaves":[{"text":" else if(BreathLED.cnt>105 && BreathLED.cnt<=195){","marks":[]}]}]},{"type":"block","id":"u6Tt-1729007813700","name":"code-line","data":{},"nodes":[{"type":"text","id":"lO9U-1729007813699","leaves":[{"text":" GPT4_PWM_SetDuty(200-BreathLED.cnt);","marks":[]}]}]},{"type":"block","id":"RYAA-1729007813702","name":"code-line","data":{},"nodes":[{"type":"text","id":"dIGX-1729007813701","leaves":[{"text":" }","marks":[]}]}]},{"type":"block","id":"oQIs-1729007813704","name":"code-line","data":{},"nodes":[{"type":"text","id":"UO02-1729007813703","leaves":[{"text":" else if(BreathLED.cnt >= 200)","marks":[]}]}]},{"type":"block","id":"vcTL-1729007813706","name":"code-line","data":{},"nodes":[{"type":"text","id":"MxrG-1729007813705","leaves":[{"text":" BreathLED.cnt = 0;","marks":[]}]}]},{"type":"block","id":"1l9q-1729007813708","name":"code-line","data":{},"nodes":[{"type":"text","id":"oCPg-1729007813707","leaves":[{"text":" }","marks":[]}]}]},{"type":"block","id":"3Aqc-1729007813710","name":"code-line","data":{},"nodes":[{"type":"text","id":"dXiX-1729007813709","leaves":[{"text":"}","marks":[]}]}]}],"state":{}}]"><div yne-bulb-block="code" data-theme="default" style="white-space-collapse: preserve;" data-language="">void g_timer0_Callback(timer_callback_args_t * p_args){
if (TIMER_EVENT_CYCLE_END == p_args->event){
LED.timercnt++;
if(LED.timercnt >= 50*(LED.speed+1)){
LED.timercnt = 0;
LED.flag = 1;
LED.cnt++;
}
BreathLED.cnt++;
if(BreathLED.cnt>5 && BreathLED.cnt<=95){
GPT4_PWM_SetDuty(BreathLED.cnt);
}
else if(BreathLED.cnt>105 && BreathLED.cnt<=195){
GPT4_PWM_SetDuty(200-BreathLED.cnt);
}
else if(BreathLED.cnt >= 200)
BreathLED.cnt = 0;
}
}</div></article>
下载验证就可以看到我们可以通过按键控制LED闪烁的速率了:
|