Arduino 外部中断与串口通信实验 - 完整代码及详解
Arduino 外部中断与串口通信实验 - 完整代码及详解
实验目的
- 掌握 Arduino 的外部中断引脚,例如 Arduino Uno 的引脚 2 和 3 支持外部中断。
- 掌握串口通信的接口,例如 Arduino Uno 的引脚 0 和 1 默认用于串口通信,也可以使用软件串口库来使用其它引脚进行串口通信。
- 理解外部中断的触发方式和回调函数的应用,例如使用
attachInterrupt()函数来绑定中断服务函数。 - 掌握串口通信的初始化和数据发送方法,例如使用
Serial.begin()和Serial.println()函数进行串口通信。
实验内容
实验一:单按键计数并通过串口打印
- 将一个按键连接到 Arduino 的外部中断引脚 2 上。
- 使用中断服务函数记录按键的次数。
- 通过串口将按键次数打印出来。
实验二:双按键计数并控制 LED 显示
- 将两个按键分别连接到 Arduino 的外部中断引脚 2 和 3 上。
- 将 5 个 LED 连接到 Arduino 的其它 5 个数字引脚上。
- 使用中断服务函数分别记录两个按键的次数。
- 将两个按键的次数组合成一个十进制数,然后将其转换为二进制数。
- 根据二进制数的每一位控制 5 个 LED 的亮灭状态。
- 通过串口打印二进制数。
实验代码
#include <SoftwareSerial.h> // 引用串口通信库
SoftwareSerial mySerial(10, 11); // 新建串口对象
volatile int count2 = 0; // 记录2号引脚按键次数
volatile int count3 = 0; // 记录3号引脚按键次数
volatile boolean state2 = false; // 2号引脚状态
volatile boolean state3 = false; // 3号引脚状态
void setup() {
pinMode(2, INPUT_PULLUP); // 配置2号引脚为上拉输入
pinMode(3, INPUT_PULLUP); // 配置3号引脚为上拉输入
pinMode(4, OUTPUT); // 配置4号引脚为输出
pinMode(5, OUTPUT); // 配置5号引脚为输出
pinMode(6, OUTPUT); // 配置6号引脚为输出
pinMode(7, OUTPUT); // 配置7号引脚为输出
pinMode(8, OUTPUT); // 配置8号引脚为输出
attachInterrupt(digitalPinToInterrupt(2), count2Func, FALLING); // 绑定2号引脚中断服务函数
attachInterrupt(digitalPinToInterrupt(3), count3Func, FALLING); // 绑定3号引脚中断服务函数
Serial.begin(9600); // 初始化串口通信
mySerial.begin(9600); // 初始化串口通信
}
void loop() {
if(state2 && state3) { // 如果2号引脚和3号引脚都按下了
int num = count2 * 10 + count3; // 计算按键次数的十进制数
String binary = String(num, BIN); // 将十进制数转化为二进制字符串
int length = binary.length(); // 计算字符串长度
for(int i = 0; i < length; i++) { // 循环控制LED
digitalWrite(i+4, binary.charAt(length-i-1)=='1'?HIGH:LOW); // 根据二进制数的每一位决定LED的状态
}
Serial.println(binary); // 在串口上打印二进制数
mySerial.println(binary); // 在另一个串口上打印二进制数
state2 = false; // 清除2号引脚状态
state3 = false; // 清除3号引脚状态
count2 = 0; // 清零2号引脚按键次数
count3 = 0; // 清零3号引脚按键次数
}
}
void count2Func() { // 2号引脚中断服务函数
count2++; // 2号引脚按键次数加1
state2 = true; // 2号引脚状态变为按下
}
void count3Func() { // 3号引脚中断服务函数
count3++; // 3号引脚按键次数加1
state3 = true; // 3号引脚状态变为按下
}
代码解析
-
包含串口通信库
#include <SoftwareSerial.h>使用
SoftwareSerial库来实现软件串口,以便使用 Arduino Uno 的其它引脚进行串口通信。 -
创建串口对象
SoftwareSerial mySerial(10, 11);创建
SoftwareSerial对象,并指定其使用的引脚为 10 和 11。 -
定义变量
volatile int count2 = 0; volatile int count3 = 0; volatile boolean state2 = false; volatile boolean state3 = false;使用
volatile关键字修饰变量,以确保在中断服务函数中修改变量的值时,主函数可以正确读取。count2和count3用于记录两个按键的次数。state2和state3用于记录两个按键的状态,true表示按下,false表示未按下。
-
配置引脚
pinMode(2, INPUT_PULLUP); pinMode(3, INPUT_PULLUP); pinMode(4, OUTPUT); pinMode(5, OUTPUT); pinMode(6, OUTPUT); pinMode(7, OUTPUT); pinMode(8, OUTPUT);- 将引脚 2 和 3 配置为上拉输入,用于连接按键。
- 将引脚 4 到 8 配置为输出,用于控制 LED。
-
绑定中断服务函数
attachInterrupt(digitalPinToInterrupt(2), count2Func, FALLING); attachInterrupt(digitalPinToInterrupt(3), count3Func, FALLING);使用
attachInterrupt()函数将中断服务函数绑定到外部中断引脚上。digitalPinToInterrupt(pin)函数用于获取指定引脚的外部中断号。count2Func和count3Func分别是两个按键的中断服务函数。FALLING表示当引脚电平由高电平变为低电平时触发中断。
-
初始化串口
Serial.begin(9600); mySerial.begin(9600);初始化串口通信,波特率为 9600。
-
主循环
void loop() { if(state2 && state3) { int num = count2 * 10 + count3; String binary = String(num, BIN); int length = binary.length(); for(int i = 0; i < length; i++) { digitalWrite(i+4, binary.charAt(length-i-1)=='1'?HIGH:LOW); } Serial.println(binary); mySerial.println(binary); state2 = false; state3 = false; count2 = 0; count3 = 0; } }- 循环判断两个按键的状态,如果两个按键都按下,则执行以下操作:
- 计算按键次数的十进制数。
- 将十进制数转换为二进制字符串。
- 根据二进制字符串的每一位控制 LED 的亮灭状态。
- 在串口上打印二进制字符串。
- 清除按键状态和按键次数。
- 循环判断两个按键的状态,如果两个按键都按下,则执行以下操作:
-
中断服务函数
void count2Func() { count2++; state2 = true; } void count3Func() { count3++; state3 = true; }count2Func和count3Func分别是两个按键的中断服务函数,用于记录按键的次数和状态。
总结
本文详细讲解了如何使用 Arduino 实现外部中断与串口通信的实验,并提供完整的示例代码。希望本文能够帮助您快速掌握 Arduino 的外部中断和串口通信应用。
注意事项
- 实验过程中需要注意 Arduino 的引脚分配,避免连接错误。
- 使用
volatile关键字修饰变量,以确保在中断服务函数中修改变量的值时,主函数可以正确读取。 - 选择合适的外部中断触发方式,例如
FALLING、RISING或CHANGE。 - 确保串口通信的波特率设置一致。
扩展
- 可以使用其它外部中断引脚,例如引脚 0 和 1,但需要注意这些引脚默认用于串口通信。
- 可以使用其它串口通信协议,例如 SPI 或 I2C。
- 可以将按键和 LED 扩展到更多,实现更复杂的应用。
祝您实验顺利!
原文地址: https://www.cveoy.top/t/topic/nP8q 著作权归作者所有。请勿转载和采集!