wokwi arduino mega 2560 - 外部中断案例keyinterrupt

截图:

wokwi arduino mega 2560 - 外部中断案例keyinterrupt

链接:

https://wokwi.com/projects/413880919557075969

代码:

// 此程序仅供cslg单片机课程1624221,1624222演示用
// 在Arduino Mega 2560(或任何其他基于AVR微控制器的Arduino板)上,
// 中断函数(Interrupt Service Routine, ISR)中使用延时函数(如delay())是不推荐的,
// 甚至可能是危险的。

const int ledPin = 13; // 定义LED连接的引脚为13
const int buttonPin = 2; // 定义按钮连接的引脚为2,对应interrupt 0
char ledc = 0, leda = 8, ledi = 0, leds = 0; // 定义快闪中断配置变量

volatile boolean buttonState = LOW; // 定义一个易失性布尔变量,用于在ISR和主程序之间传递状态

// 自定义延时函数,将毫秒转换为微秒并分段延时
void zhangrelaydelay(unsigned int delay_ms) {
  // 将毫秒转换为微秒
  unsigned long delay_us = delay_ms * 1000;
  
  // 定义每次delayMicroseconds()调用的最大微秒数
  // (根据平台可能有所不同,但通常1000或更少是安全的)
  const unsigned int max_micros_per_call = 1000;
  
  // 循环直到达到所需的总延时
  while (delay_us > 0) {
    // 计算本次循环应该延时的微秒数
    unsigned int current_delay_us = min(delay_us, max_micros_per_call);
    
    // 使用delayMicroseconds()进行延时
    delayMicroseconds(current_delay_us);
    
    // 更新剩余的延时
    delay_us -= current_delay_us;
  }
}

void setup() {
  pinMode(ledPin, OUTPUT); // 设置LED引脚为输出模式
  pinMode(buttonPin, INPUT_PULLUP); // 设置按钮引脚为输入模式,并启用内部上拉电阻

  // 设置外部中断,当buttonPin引脚状态变化时调用buttonISR函数
  attachInterrupt(digitalPinToInterrupt(buttonPin), buttonISR, CHANGE);
}

void loop() {
  digitalWrite(ledPin, HIGH); // 慢闪烁5s亮
  delay(5000); // 延时5秒
  digitalWrite(ledPin, LOW); // 5s灭
  delay(5000); // 延时5秒
}

// 中断服务程序(ISR)
void buttonISR() {
  // 在ISR中切换快闪状态
  leds = digitalRead(ledPin); // 读取当前LED状态
  for (ledc = 0; ledc < leda; ledc++) { // 循环控制快闪次数(由leda决定)
    digitalWrite(ledPin, HIGH); // 中断触发时LED亮
    for (ledi = 0; ledi < leda; ledi++) { // 内部循环控制亮的时间(由leda决定,但此处延时固定为100ms)
      zhangrelaydelay(100); // 延时100ms
    }
    digitalWrite(ledPin, LOW); // LED灭
    for (ledi = 0; ledi < leda; ledi++) { // 内部循环控制灭的时间(由leda决定,但此处延时固定为10000ms即10s,逻辑上可能不合理)
      zhangrelaydelay(10000); // 延时10000ms(10秒)
    }
  }
  digitalWrite(ledPin, leds); // 恢复LED到中断前的状态
}

中文注释说明:

  1. 全局变量
    • ledPin:定义LED连接的引脚。
    • buttonPin:定义按钮连接的引脚。
    • ledcledaledileds:用于控制快闪模式的变量,其中leda可能用于控制循环次数,ledcledi为循环计数器,leds用于保存LED中断前的状态。
    • buttonState:用于在ISR和主程序之间传递按钮状态(虽然在此代码中未实际使用)。
  2. 自定义延时函数
    • zhangrelaydelay:将毫秒转换为微秒,并分段使用delayMicroseconds进行延时,以避免在ISR中直接使用delay函数。
  3. setup函数
    • 设置LED引脚为输出模式。
    • 设置按钮引脚为输入模式,并启用内部上拉电阻。
    • 绑定外部中断,当按钮引脚状态变化时调用buttonISR函数。
  4. loop函数
    • 实现LED的慢闪烁,每5秒亮灭一次。
  5. buttonISR函数
    • 中断服务程序,当按钮状态变化时触发。
    • 读取当前LED状态并保存。
    • 通过嵌套循环控制LED的快闪模式,但内部循环的延时设置可能不符合实际需求(如灭的时间固定为10秒,可能过长)。
    • 恢复LED到中断前的状态。

注意事项:

  • 在ISR中使用延时函数(即使是自定义的zhangrelaydelay)仍然是不推荐的,因为这可能导致主程序响应延迟或其他不可预测的行为。
  • buttonISR中的快闪逻辑可能需要根据实际需求进行调整,特别是灭的时间设置。
  • leda变量在此代码中用于控制循环次数,但其具体作用可能需要根据实际代码逻辑进一步确认。


Wokwi Arduino Mega 2560 外部中断案例:KeyInterrupt

项目概述

本案例演示了如何在Arduino Mega 2560上使用外部中断来控制LED的闪烁模式。当按下连接到特定引脚的按钮时,会触发中断服务程序(ISR),从而改变LED的闪烁状态。此示例中,主程序让LED以5秒的间隔慢闪烁,而中断服务程序则让LED快速闪烁一段时间,然后恢复到原来的状态。

硬件需求
  • Arduino Mega 2560
  • LED
  • 按钮(开关)
  • 电阻(如10kΩ,用于上拉电阻,如果使用内部上拉则不需要)
  • 面包板和连接线
电路连接
  1. LED连接
    • 将LED的正极(长引脚)连接到Arduino Mega 2560的数字引脚13。
    • 将LED的负极(短引脚)连接到Arduino的GND。
  2. 按钮连接
    • 将按钮的一端连接到Arduino的数字引脚2。
    • 将按钮的另一端连接到Arduino的GND。
    • 如果不使用内部上拉电阻,可以在按钮和Arduino的5V之间连接一个10kΩ的电阻。
软件实现

以下是完整的Arduino代码,包括详细注释:

 

cpp复制代码

// 此程序仅供cslg单片机课程1624221,1624222演示用
// 在Arduino Mega 2560上,中断函数中使用延时函数是不推荐的,但本例用于演示目的
const int ledPin = 13; // 定义LED连接的引脚为13
const int buttonPin = 2; // 定义按钮连接的引脚为2,对应interrupt 0
char ledc = 0, leda = 8, ledi = 0, leds = 0; // 定义快闪中断配置变量
volatile boolean buttonState = LOW; // 定义一个易失性布尔变量,用于在ISR和主程序之间传递状态(本例中未实际使用)
// 自定义延时函数,将毫秒转换为微秒并分段延时
void zhangrelaydelay(unsigned int delay_ms) {
unsigned long delay_us = delay_ms * 1000;
const unsigned int max_micros_per_call = 1000;
while (delay_us > 0) {
unsigned int current_delay_us = min(delay_us, max_micros_per_call);
delayMicroseconds(current_delay_us);
delay_us -= current_delay_us;
}
}
void setup() {
pinMode(ledPin, OUTPUT); // 设置LED引脚为输出模式
pinMode(buttonPin, INPUT_PULLUP); // 设置按钮引脚为输入模式,并启用内部上拉电阻
// 设置外部中断,当buttonPin引脚状态变化时调用buttonISR函数
attachInterrupt(digitalPinToInterrupt(buttonPin), buttonISR, CHANGE);
}
void loop() {
digitalWrite(ledPin, HIGH); // 慢闪烁5s亮
delay(5000); // 延时5秒
digitalWrite(ledPin, LOW); // 5s灭
delay(5000); // 延时5秒
}
// 中断服务程序(ISR)
void buttonISR() {
leds = digitalRead(ledPin); // 读取当前LED状态
for (ledc = 0; ledc < leda; ledc++) { // 循环控制快闪次数(由leda决定)
digitalWrite(ledPin, HIGH); // 中断触发时LED亮
for (ledi = 0; ledi < leda; ledi++) { // 内部循环控制亮的时间(此处延时固定为100ms)
zhangrelaydelay(100); // 延时100ms
}
digitalWrite(ledPin, LOW); // LED灭
for (ledi = 0; ledi < leda; ledi++) { // 内部循环控制灭的时间(此处延时固定为10000ms即10s)
zhangrelaydelay(10000); // 延时10000ms(10秒),注意:这可能导致ISR执行时间过长
}
}
digitalWrite(ledPin, leds); // 恢复LED到中断前的状态
}
注意事项
  1. 中断中的延时:在中断服务程序中使用延时函数(即使是自定义的)通常是不推荐的,因为它会阻塞其他中断的执行,并可能导致系统响应延迟。在本例中,为了演示目的而使用了延时,但在实际应用中应尽量避免。

  2. 中断逻辑:中断服务程序中的快闪逻辑可能需要根据实际需求进行调整。特别是灭的时间设置为10秒可能过长,导致LED长时间保持熄灭状态。

  3. 硬件去抖动:按钮在按下和释放时可能会产生抖动,导致中断多次触发。在实际应用中,可能需要添加硬件去抖动电路或软件去抖动逻辑。

  4. Wokwi仿真:在Wokwi等在线仿真平台上测试此代码时,请注意仿真环境可能无法完全模拟实际硬件行为,特别是中断响应时间和延时函数的准确性。

结论

本案例展示了如何在Arduino Mega 2560上使用外部中断来控制LED的闪烁模式。通过按下按钮触发中断服务程序,可以改变LED的闪烁状态。然而,在实际应用中,应谨慎使用中断中的延时函数,并考虑添加去抖动逻辑以提高系统的稳定性和可靠性。


Wokwi Arduino Mega 2560 中断系统详细课程教程


一、课程概述

本课程将详细介绍 Arduino Mega 2560 的中断系统,包括中断的基本概念、中断引脚、中断模式、中断服务程序(ISR)的编写,以及如何在 Wokwi 平台上进行中断系统的仿真和调试。通过本课程的学习,学员将掌握如何利用中断系统实现实时响应外部事件的功能。


二、课程内容

1. 中断系统基础
  • 中断的概念:中断是单片机在执行主程序的过程中,由于某种外部或内部事件的需要,暂时中止当前程序的执行,转而执行一段特定的处理程序(ISR),处理完毕后再返回原程序继续执行的过程。
  • 中断的优点
    • 实时控制:能够立即响应外部事件。
    • 分时操作:提高 CPU 的利用率。
    • 故障处理:及时响应和处理系统故障。
2. Arduino Mega 2560 中断引脚
  • 外部中断引脚:Arduino Mega 2560 支持 6 个外部中断引脚,分别是 2(中断 0)、3(中断 1)、18(中断 5)、19(中断 4)、20(中断 3)、21(中断 2)。
  • 中断编号:每个中断引脚对应一个中断编号,用于在程序中配置和触发中断。
3. 中断模式
  • LOW:低电平触发。
  • CHANGE:电平变化触发(从低电平到高电平或从高电平到低电平)。
  • RISING:上升沿触发(从低电平到高电平)。
  • FALLING:下降沿触发(从高电平到低电平)。
4. 中断服务程序(ISR)
  • ISR 的定义:ISR 是中断发生时执行的特定代码段,用于处理中断事件。
  • ISR 的编写要求
    • ISR 必须没有参数和返回值。
    • ISR 应尽可能简短,避免使用延时函数(如 delay())。
    • ISR 中可以使用全局变量来传递数据。
5. 中断配置函数
  • attachInterrupt() 函数:用于配置中断引脚和中断模式。
    • 语法:attachInterrupt(interrupt, ISR, mode)
    • 参数说明:
      • interrupt:中断编号。
      • ISR:中断服务程序名。
      • mode:中断触发模式。
  • detachInterrupt() 函数:用于关闭中断。
    • 语法:detachInterrupt(interrupt)
    • 参数说明:
      • interrupt:中断编号。
6. 定时中断
  • 定时中断的概念:利用单片机内部的定时器产生的中断,称为定时中断。
  • 定时中断库:Arduino 没有直接的定时中断设置,需要使用第三方库,如 FlexiTimer2 或 MsTimer2
  • 定时中断的配置
    • 设置定时中断周期。
    • 使能或禁止定时中断。
7. Wokwi 平台中断系统仿真
  • 创建项目:在 Wokwi 平台上选择 Arduino Mega 2560 型号,创建新的项目。
  • 编写代码:使用 attachInterrupt() 函数配置中断引脚和中断模式,编写 ISR。
  • 仿真运行:观察中断事件触发时,ISR 的执行情况。
  • 调试工具:使用串口监视器查看中断触发时的调试信息。
8. 实例项目
  • 项目一:外部中断控制 LED 闪烁
    • 使用外部中断引脚和按钮,实现按下按钮时 LED 闪烁的功能。
  • 项目二:定时中断控制 LED 亮度调节
    • 使用定时中断库,实现 LED 亮度随时间逐渐变化的功能。

三、课程总结

  • 回顾知识点:总结中断系统的基本概念、中断引脚、中断模式、ISR 的编写要求等。
  • 强调实践:鼓励学员在 Wokwi 平台上进行中断系统的仿真和调试,通过实例项目加深对中断系统的理解。
  • 展望未来:介绍中断系统在更复杂项目中的应用前景,如智能家居、环境监测、机器人控制等。

四、学习资源

  • 官方文档:Arduino 官方网站的中断系统相关文档。
  • 在线教程:Wokwi 平台的教程和 Arduino 中文社区的教程。
  • 书籍推荐:《Arduino 编程从入门到实践》、《Arduino 高级编程》等。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

zhangrelay

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值