本帖最后由 gaoyang9992006 于 2025-1-9 19:11 编辑
#申请原创# @21小跑堂
今天分享MCC下AVR单片机的IO中断配置与使用
书接上回ATMEGA4809点亮LED,新年第一次点灯
https://bbs.21ic.com/icview-3426362-1-1.html
在此基础上配置IO中断IO中断是用来处理IO突发信号的,在发生指定的信号后,不管MCU在干什么都要立刻来到中断入口处处理中断事件,处理完就立刻回到原来的程序执行处继续执行。
对比上一课的IO查询法实现IO的输入检测,使用中断法可以看起来不用打断主程序的执行,即可处理按钮按下后需要的变量修改。
配置工具使用顺序如下所示
IO口输入与感应配置支持多达6种模式,我们常用的是上升沿,下降沿,双边沿跳变检测。
根据原理图,如果你想按下就触发,那么可以设置为下降沿触发模式,如果想松开后触发,那么设置上升沿模式,如果想实现检测按下时间长短,可以设置为双边沿模式,在双边沿模式可以通过计算两次触发的时间间隔来执行不同的长短按检测。
这里我们先使用下降沿模式,配置如下
执行Generate生成相关代码
查看代码
我们注意到在pins.c生成了对应的处理函数
你可以之间在默认函数内执行中断处理任务
void SW_DefaultInterruptHandler(void)
{
// add your SW interrupt custom code
// or set custom function using SW_SetInterruptHandler()
}
如果不想在这个函数内完成,我们可以编写自己的中断处理
例如,我们定义一个全局变量,在某个函数内对该变量翻转,然后将该函数指针传递到中断处理函数内。
最后要使能全局中断控制器。
#include "mcc_generated_files/system/system.h"
#include"mcc_generated_files/timer/delay.h"
/*
Main application
*/
unsigned int flag=0;
void sw_int_handle(void)
{
flag=flag?0:1;
}
int main(void)
{
SYSTEM_Initialize();
SW_SetInterruptHandler(sw_int_handle);
Enable_global_interrupt();
while(1)
{
if(flag)
{
YELLOW_LED_Toggle();
DELAY_milliseconds(500);
}
else
{
YELLOW_LED_SetHigh();
}
}
}
如上所示,这里我们使用三目运算符实现0和1的切换。
void sw_int_handle(void)
{
flag=flag?0:1;
}
如果使用取反符号那么将会按位取反,而不是在0和1之间切换。
函数sw_int_handle就是我们自己定义的中断处理函数
通过SW_SetInterruptHandler(sw_int_handle);传递函数名(指针)到中断函数。
然后通过Enable_global_interrupt();开启全局中断功能。
编译烧录,这个时候默认上电灯是熄灭的,按下按钮,灯开始闪烁,就算你没抬起来,也开始闪烁。抬起后再按一下,就又开始闪烁了。
其中对应的全局中断函数在目录utils下的interrupt_avr8.h里
关于IO的各种操作的库函数在pin.h和pin.c里面
比如,IO中断处理函数也在这里面。
可以看到MCC给配置为输出的IO也生成了中断处理函数,这个对程序没有影响,不用理会,希望后续升级汇中能过滤掉不需要的配置。
下一课我们讲解时钟系统与定时器的用法https://bbs.21ic.com/icview-3426584-1-1.html
|
@21小跑堂 :那我抽空再完善一下内容。引证一下手册里的说明
字数未满800字不予审核,建议和上篇合并为一篇申请原创