网站上面的图片是怎么做的,企销客,袜子技术支持北京网站建设,能免费建网站吗中断用于处理在程序正常执行期间通过外部事件或者响应软件指令触发时发生的事件。比如#xff0c;在一段呼吸灯的代码中#xff0c;正常运行时的结果为LED从暗到亮#xff0c;再从亮到暗持续地运行。我们可以通过一个中断来控制呼吸灯的运行和停止。使用中断功能#xff0c…中断用于处理在程序正常执行期间通过外部事件或者响应软件指令触发时发生的事件。比如在一段呼吸灯的代码中正常运行时的结果为LED从暗到亮再从亮到暗持续地运行。我们可以通过一个中断来控制呼吸灯的运行和停止。使用中断功能我们就不需要不停地监控一个引脚的状态当中断被触发内部控制器停止执行主程序并调用中断服务例程 (ISR) 。
中断服务例程 (ISR)
中断服务例程 (ISR)是特殊类型的函数它有一些特殊的特点和规则
1、将部分内部 SRAM0 区域分配给IRAM可以显著减少运行的迟延。
2、必须将中断服务例程 (ISR)放入 IRAM。
3、中断服务例程 (ISR)不能有任何参数也不返回任何值。
4、因为中断服务例程 (ISR)会中断主程序的运行运行时间过长会对主程序形成阻塞所以中断服务例程 (ISR)尽可能短和快。
在IRAM中放置代码可以使用 IRAM_ATTR 宏在源代码中指定该函数放置到IRAM中如:
void IRAM_ATTR ISR_function()
{// ...
}
我们在使用中断功能时会使用一个名为attachInterrupt()的函数个设置引脚中断。 函数attachInterrupt 作用用于将中断附加到定义的引脚。 格式attachInterrupt(uint8_t pin, voidFuncPtr handler, int mode); 参数 pin -定义监控的GPIO 引脚号。 handler -设置中断服务例程 (ISR) mode -设置中断模式 LOW -低电平触发 CHANGE -管脚电平变化触发 HIGH -高电平触发 RISING -管脚从低电平变化高电平触发即上升沿触发 FALLING -下降沿触发电平从高变低 示例代码
我们需要定义一个引脚来用于中断服务这里选择4号引脚:
int interrupt_pin 4; //引脚号 下面需要要定义一个计数器来记录中断的次数默认设为0
int interrupt_counter 0; //中断次数计数器
定义一个开关标记来记录中断时的开关状态
bool press_down; //中断标记开关
定义一个ISR函数放置到IRAM
void IRAM_ATTR ISR_function(){interrupt_counter; //中断次数计数器累加press_down true; //中断标记开关设为开
}
我们需要使用上面所介绍的attachInterrupt函数来把中断服务附加到指定的引脚
attachInterrupt(interrupt_pin, ISR_function, FALLING); //中断附加到引脚
以下为硬件的连接和完整的代码 int interrupt_pin 4; //引脚号
int interrupt_counter 0; //中断次数计数器
bool press_down; //中断标记开关void IRAM_ATTR ISR_function(){interrupt_counter; //中断次数计数器累加press_down true; //中断标记开关设为开
}void setup() {Serial.begin(115200);pinMode(interrupt_pin,INPUT_PULLUP); //引脚初始化为输入上拉模式attachInterrupt(interrupt_pin, ISR_function, FALLING); //中断附加到引脚
}void loop() {if(press_down){ //如果中断标记开关为开状态Serial.print(发生中断事件:); Serial.println(interrupt_counter); //串口输出计数器的值press_down false; //中断标记开关设为关}
}
代码说明
在该例程中我们设置监控4号引脚来触发中断服务。
我们把4号引脚设置为输入上拉模式当开机时4号引脚为高电平状态。
4号引脚通过一个开关与GND引脚连接当开关按下时4号引脚由高电平变为低电平状态。
这时触发中断主程序中断进入ISR_function函数函数功能包括给计数器累加中断次数和中断标记开关设置为开。
中断标记为开时满足if(press_down)条件进入分支串口此时输出计数器的值并设置中断标记开关为关闭状态。
测试代码
运行该代码打开串口监视器按下开关可以观察到计数器的变化 同时我们也会发现有时即使只按一次开关也会出现计数据多次增加。这是同于硬件生产工艺的原因造成的我们在直观上感觉只按了一次开关但在十分微小的时间里开关的接触弹片可能进行了多次的接触。释放按钮时也会发生同样的事情。在生产中工艺上是无法达到理想的完美状态的。以致产生了这种名为开关抖动的现象。我们可以通过硬件或软件的方式来消除这种抖动。
消除开关抖动
我们在上面的例程中加入添加代码以软件的方式来消除开关抖动。实现每按一次开只允许动行一次ISR程序
int interrupt_pin 4; //引脚号
int interrupt_counter 0; //中断次数计数器
bool press_down false ; //中断标记开关void IRAM_ATTR ISR_function(){static unsigned long lastInterruptTime 0;unsigned long interruptTime millis();if(interruptTime - lastInterruptTime 200){press_down true; //中断标记开关设为开interrupt_counter;}lastInterruptTime interruptTime;
}void setup() {Serial.begin(115200);pinMode(interrupt_pin,INPUT_PULLUP); //引脚初始化为输入上拉模式attachInterrupt(interrupt_pin, ISR_function, FALLING); //中断附加到引脚
}void loop() {if(press_down){ //如果中断标记开关为开状态Serial.print(发生中断事件:); Serial.println(interrupt_counter); //串口输出计数器的值press_down false; //中断标记开关设为关}
}