24-25-1-单片机开卷部分习题和评分标准
依据相关规定试卷必须按评分标准进行批改。
给分一定是宽松的,能给分一定给,如有疑问也可以向学院教务办申请查卷。
一部分学生期末成绩由于紧张或其他原因导致分数过低,也是非常非常遗憾的。
个人也是非常抱歉的。
开卷考试
简答题
第一题
(本题
10
分)请描述
Arduino Mega 2560
数字
I/O
口(如引脚
13
)输出和输入过程及
原理。
(1)说明输出过程及原理。(5 分)
(2)说明输入过程及原理,以及保证读取数据正确的方法(5 分)
评阅标准:
(
1
)输出过程及原理(
5
分):
当在
Arduino
程序中设置数字
I/O
口(如引脚
13
)为输出模式(使用
pinMode(13, OUTPUT)
),并向该
引脚写入高电平(
digitalWrite(13, HIGH)
)或低电平(
digitalWrite(13, LOW)
)时,
Arduino Mega 2560
的微控制器会控制该引脚对应的寄存器,使引脚输出相应的电平。(
3
分)
输出高电平时,微控制器会通过内部电路使引脚
13
与电源(
VCC
)相连;输出低电平时,则使引脚
13
与地(
GND
)相连。(
2
分)
这一过程由
Arduino
的库函数和底层硬件抽象层(
HAL
)管理,无需用户直接操作寄存器。
(
2
)输入过程及原理,以及保证读取数据正确的方法(
5
分):
当设置数字
I/O
口(如引脚
13
)为输入模式(使用
pinMode(13, INPUT)
)时,
Arduino Mega 2560
的微
控制器会将该引脚配置为高阻态,即不会主动向外部电路提供电流或电压。(
2
分)
读取引脚状态时(使用
digitalRead(13)
),
Arduino
会检测引脚上的电平,并返回
HIGH
或
LOW
。(
1
分)
为了保证读取数据正确,应确保引脚
13
与外部电路的连接正确,且外部电路提供的电平信号足够稳
定,以避免误读。此外,若引脚
13
连接了上拉或下拉电阻,也能提高读取的稳定性。(
2
分)
第二题
2
、(本题
10
分)请结合
Arduino Mega 2560
的串口通信功能,描述串口的发送和接收工
作过程。
发送过程:
当调用
Serial.print()
、
Serial.println()
或
Serial.write()
等函数时,
Arduino
会将待发送的数据放入串口发送
缓冲区。(
2
分)
串口硬件(
USART
)会按照设定的波特率(通过
Serial.begin(baudRate)
设置)从发送缓冲区中逐位读取
数据,并将其转换为串行信号发送出去。(
2
分)
发送过程中,
USART
会控制
TXD
(发送数据)引脚的电平变化,以形成串行数据流。(
1
分)
接收过程:
当外部设备通过
RXD
(接收数据)引脚向
Arduino
发送串行数据时,
USART
会按照设定的波特率接
收这些数据。(
2
分)
接收到的数据会被放入串口接收缓冲区,等待程序通过
Serial.read()
、
Serial.available()
等函数读取。(
2 分)
在读取数据时,程序可以检查接收缓冲区的状态,以确定是否有数据可读,并读取数据。(
1
分)
第三题
3、 (本题
10
分)请完善以下 I2C 总线程序,该函数应适用于 Arduino Mega 2560,并说
明所完善程序的功能。
#include <Wire.h>
// 从设备的 I2C 地址
#define SLAVE_ADDRESS 0x27 // 根据具体的从设备修改此地址
void setup() {
// 初始化串口通信,用于调试
Serial.begin(9600);
// 初始化 I2C 通信
// 主设备初始化
Serial.println("I2C 初始化完成");
}
void loop() {
// 要发送的数据
byte dataToSend = 0x42; // 示例数据
// 开始传输到从设备
// 发送数据
// 结束传输
// 调试输出
Serial.print("发送数据: ");
Serial.println(dataToSend, HEX);
// 每隔 1 秒发送一次数据
delay(1000);
}
#include <Wire.h>
// 从设备的 I2C 地址
#define SLAVE_ADDRESS 0x27 // 根据具体的从设备修改此地址
void setup() {
// 初始化串口通信,用于调试
Serial.begin(9600);
// 初始化 I2C 通信
Wire.begin(); // 主设备初始化 (2 分)
Serial.println("I2C 初始化完成");
}
void loop() {
// 要发送的数据
byte dataToSend = 0x42; // 示例数据
// 开始传输到从设备
Wire.beginTransmission(SLAVE_ADDRESS); (2 分)
// 发送数据
Wire.write(dataToSend); (2 分)
// 结束传输
Wire.endTransmission(); (2 分)
// 调试输出
Serial.print("发送数据: ");
Serial.println(dataToSend, HEX);
// 每隔 1 秒发送一次数据
delay(1000);
}
使用 Arduino Mega 2560 作为主设备,向一个从设备(例如,具有 I2C 接口的 LCD 显示屏或 EEPROM 存
储器)发送数据。
1 包含 Wire 库。
2 初始化 I2C 通信。
3 向从设备发送数据。 (2 分)
分析编程题
1、(本题 20 分) 基于 Arduino Mega 2560 的 LED 控制和模拟电动机控制器
a) 当按下 KEY0 时,LED0 点亮,串口发送“电动机上电”;
b) 当按下 KEY1 时,LED1 点亮,串口发送“电动机正转”;
c) 当按下 KEY2 时,LED2 点亮,串口发送“电动机反转”;
d) 当按下 KEY3 时,LED3 点亮,串口发送“电动机停转”。
如果代码都有注释,分析编程合在一起。如果代码没有注释,必须要有代码的文字说明。
编程合理即可得分,答案不唯一。
//
定义按键和
LED
引脚数组
const int keyPins[] = {22, 23, 24, 25};
const int ledPins[] = {26, 27, 28, 29};
//
定义与按键对应的消息数组
const char* messages[] = {
"
电动机上电
",
"
电动机正转
",
"
电动机反转
",
"
电动机停转
"
};
(
5
分)
void setup() {
//
初始化串口通信
Serial.begin(9600);
//
设置按键引脚为输入,并启用内部上拉电阻
for (int i = 0; i < 4; i++) {
pinMode(keyPins[i], INPUT_PULLUP);
}
//
设置
LED
引脚为输出
for (int i = 0; i < 4; i++) {
pinMode(ledPins[i], OUTPUT);
}
}
(
5
分)
void loop() {
//
遍历按键和
LED
for (int i = 0; i < 4; i++) {
//
检查按键状态
if (digitalRead(keyPins[i]) == LOW) {
digitalWrite(ledPins[i], HIGH); //
点亮对应的
LED
Serial.println(messages[i]); //
发送对应的消息
} else {
digitalWrite(ledPins[i], LOW); //
熄灭对应的
LED
}
}
(
5
分)
//
延时以避免按键抖动
delay(50);
}
(
5
分)
数组存储引脚:
使用
keyPins
和
ledPins
数组来存储按键和
LED
的引脚号,这样可以通过循环来遍历它们,而不是为每个
按键和
LED
分别编写代码。
消息数组:
使用
messages
数组来存储与按键对应的消息,这样可以在按键被按下时轻松地发送正确的消息。
循环处理:
在
setup()
函数中,使用
for
循环来设置按键引脚为输入并启用内部上拉电阻,以及设置
LED
引脚为输出。
在
loop()
函数中,使用
for
循环来遍历按键和
LED
,检查按键状态,并根据需要点亮或熄灭
LED
,同时发
送相应的消息。
// 定义按键和 LED 引脚数组
const int keyPins[] = {22, 23, 24, 25};
const int ledPins[] = {26, 27, 28, 29};
// 定义与按键对应的消息数组
const char* messages[] = {
"电动机上电",
"电动机正转",
"电动机反转",
"电动机停转"
};
(5 分)
void setup() {
// 初始化串口通信
Serial.begin(9600);
// 设置按键引脚为输入,并启用内部上拉电阻
for (int i = 0; i < 4; i++) {
pinMode(keyPins[i], INPUT_PULLUP);
}
// 设置 LED 引脚为输出
for (int i = 0; i < 4; i++) {
pinMode(ledPins[i], OUTPUT);
}
}
(5 分)
void loop() {
// 遍历按键和 LED
for (int i = 0; i < 4; i++) {
// 检查按键状态
if (digitalRead(keyPins[i]) == LOW) {
digitalWrite(ledPins[i], HIGH); // 点亮对应的 LED
Serial.println(messages[i]); // 发送对应的消息
} else {
digitalWrite(ledPins[i], LOW); // 熄灭对应的 LED
}
}
(5 分)
// 延时以避免按键抖动
delay(50);
}