32单片机从入门到精通之数据处理——数学运算(十三)

无论你身在何处,无论你面对什么困难,只要对自己充满信心,坚持不懈地努力,相信自己的能力,你就能战胜任何困难,实现自己的目标。不要害怕失败,因为失败并不意味着你没有能力成功,只是说明你还需要再努力一些。每一次挫折都是人生的一次锻炼,将使你变得更加坚强。无论遇到什么困难,都要勇敢地面对,不要放弃,相信自己,相信你的能力。记住,只有经历了艰辛的努力才能获得真正的成功。所以,不管遇到什么困难,都要坚持下去,直到达到自己的目标。

目录

上一张试卷

一、选择题(每题2分,共20分)

二、简答题(每题10分,共30分)

三、编程题(每题15分,共30分)

知识点讲解

[1. 基本数学运算](#1. 基本数学运算)

平均值计算

最大值/最小值查找

简单的一阶低通滤波器

[2. 高精度计算](#2. 高精度计算)

浮点单元(FPU)

定点数运算

试卷

一、选择题(每题2分,共10分)

二、简答题(每题10分,共30分)

三、编程题(每题15分,共30分)


上一张试卷

一、选择题(每题2分,共20分)

  1. 在读取DHT22温湿度传感器数据时,以下哪个库可以简化操作?

    • B. DHT.h
  2. I2C通信中,用于标识数据传输开始的是:

    • C. 起始条件
  3. LM35温度传感器输出的电压值与摄氏度之间的关系是:

    • B. 每10mV对应1°C
  4. PWM信号的主要用途之一是:

    • B. 控制电机速度或LED亮度
  5. 下列哪种传感器通常使用I²C接口进行通信?

    • B. ADXL345

二、简答题(每题10分,共30分)

  1. 描述如何使用Arduino平台上的DHT库读取DHT22传感器的数据。

    使用Arduino平台上的DHT库可以大大简化对DHT22温湿度传感器的操作。首先需要包含DHT.h库文件,然后定义连接传感器的引脚以及传感器类型。通过创建一个DHT类的对象,并调用其提供的方法如readHumidity()readTemperature()来获取湿度和温度数据。在程序初始化阶段(setup()函数),应该初始化串口通信以便于调试信息的输出,并调用dht.begin()来启动传感器。在主循环中,可以通过这些API读取并处理传感器数据。

  2. 解释如何利用微控制器内置的ADC将来自LM35温度传感器的模拟信号转换为数字值,并计算出实际温度。

    微控制器通常配备有模数转换器(ADC),它能够将模拟电压值转换成数字表示形式。对于LM35温度传感器,其输出电压与摄氏温度成线性关系,即每上升1°C,输出电压增加10mV。为了得到实际温度,我们先使用analogRead()函数读取连接到指定模拟输入引脚上的电压值,该函数返回一个介于0到1023之间的整数值,代表了0到5V的电压范围。接下来,根据比例换算公式 voltage = sensorValue * (5.0 / 1023.0) 计算实际电压,再通过 temperatureC = voltage * 100.0 将电压转换为摄氏温度。

  3. 说明PWM(脉宽调制)的工作原理以及它在控制电机或其他执行机构中的应用。

    PWM是一种用来生成具有可变占空比的方波的技术,其中周期固定但高电平时间(占空比)可以根据需要调整。当应用于电机驱动时,PWM允许改变施加给电机的平均电压,从而有效地调节电机的速度或扭矩。同样地,PWM也可以用来调整LED灯的亮度,通过快速切换LED的开关状态,在视觉上实现亮度的变化。此外,PWM还可以用于其他类型的执行器,例如伺服电机的位置控制等。


三、编程题(每题15分,共30分)

  1. 编写一段Arduino代码,初始化一个DHT22传感器并打印温度和湿度值。
#include <DHT.h>

#define DHTPIN 2          // DHT22 数据引脚连接到数字引脚2
#define DHTTYPE DHT22     // 指定使用的是DHT22型号

DHT dht(DHTPIN, DHTTYPE); // 创建DHT对象

void setup() {
  Serial.begin(9600); // 初始化串行通信,波特率为9600
  dht.begin();        // 初始化DHT传感器
}

void loop() {
  float humidity = dht.readHumidity();   // 读取湿度
  float temperature = dht.readTemperature(); // 读取温度

  if (isnan(humidity) || isnan(temperature)) { // 检查是否成功读取到了有效数值
    Serial.println("Failed to read from DHT sensor!");
    return;
  }

  // 打印湿度和温度值到串口监视器
  Serial.print("Humidity: ");
  Serial.print(humidity);
  Serial.print("%  Temperature: ");
  Serial.print(temperature);
  Serial.println("°C");

  delay(2000); // 等待两秒再读取新数据
}
  1. 编写一段Arduino代码,从模拟输入读取LM35温度传感器的电压值,将其转换为摄氏度,并通过串口打印出来。
const int analogPin = A0; // 定义模拟输入引脚

void setup() {
  Serial.begin(9600); // 初始化串行通信,波特率为9600
}

void loop() {
  int sensorValue = analogRead(analogPin); // 读取模拟引脚上的电压值

  // 将ADC值转换为实际温度(假设使用LM35,每10mV对应1°C)
  float voltage = sensorValue * (5.0 / 1023.0); // 转换为电压值
  float temperatureC = voltage * 100.0;         // 转换为摄氏度

  // 打印温度值到串口监视器
  Serial.print("Temperature: ");
  Serial.print(temperatureC);
  Serial.println("°C");

  delay(1000); // 等待一秒再读取新数据
}

这份试卷涵盖了基本的传感器接口知识,包括如何读取温度、湿度、加速度计等传感器的数据,处理模拟信号输入,以及控制PWM输出。

知识点讲解

在嵌入式系统中,进行数学运算是常见的任务,包括但不限于平均值、最大最小值的查找、滤波算法等。根据应用的需求和处理器的能力,可以选择使用浮点运算或定点数运算来实现这些功能。下面将详细讲解如何在嵌入式环境中执行基本的数学运算,并提供相应的代码示例及注释。

1. 基本数学运算
平均值计算

知识点讲解:

平均值(Mean)是统计学中最常用的度量之一,它反映了数据集的一般水平。对于一组数值 x1,x2,...,xnx1​,x2​,...,xn​,其平均值可以通过将所有数值相加后除以数值的数量 nn 来计算:

mean=x1+x2+...+xnnmean=nx1​+x2​+...+xn​​

代码及注释:

#include <stdio.h>

// 函数:计算数组中所有元素的平均值
float calculate_average(int array[], int size) {
    float sum = 0; // 初始化累加器为0
    for (int i = 0; i < size; i++) {
        sum += array[i]; // 将每个元素加入到累加器中
    }
    return sum / size; // 返回平均值,即总和除以元素数量
}

int main() {
    int data[] = {1, 2, 3, 4, 5}; // 定义一个整型数组
    int size = sizeof(data) / sizeof(data[0]); // 计算数组大小
    
    // 调用函数并打印结果
    printf("Average: %.2f\n", calculate_average(data, size));
    
    return 0;
}
最大值/最小值查找

知识点讲解:

为了找到一组数据的最大值或最小值,我们需要遍历整个数据集,并且不断更新当前已知的最大值或最小值。开始时可以假设第一个元素就是最大/最小值,然后逐个比较其他元素。

代码及注释:

#include <stdio.h>

// 函数:查找数组中的最大值和最小值
void find_max_min(int array[], int size, int *max, int *min) {
    *max = *min = array[0]; // 初始化最大值和最小值为第一个元素
    for (int i = 1; i < size; i++) {
        if (array[i] > *max) *max = array[i]; // 更新最大值
        if (array[i] < *min) *min = array[i]; // 更新最小值
    }
}

int main() {
    int data[] = {3, 1, 4, 1, 5, 9, 2, 6, 5, 3}; // 定义一个整型数组
    int size = sizeof(data) / sizeof(data[0]);
    int max, min;

    // 调用函数并打印结果
    find_max_min(data, size, &max, &min);
    printf("Max: %d, Min: %d\n", max, min);
    
    return 0;
}
简单的一阶低通滤波器

知识点讲解:

滤波器用于减少信号中的噪声成分。一阶低通滤波器是一种简单的线性滤波器,它允许低频信号通过而衰减高频信号。它可以用来平滑快速变化的数据序列,如传感器读数。公式如下:

y[n]=α⋅y[n−1]+(1−α)⋅x[n]y[n]=α⋅y[n−1]+(1−α)⋅x[n]

其中 αα 是介于0到1之间的滤波系数,y[n]y[n] 是当前输出,y[n−1]y[n−1] 是上一次输出,x[n]x[n] 是当前输入。

代码及注释:

#include <stdio.h>

#define FILTER_COEFFICIENT 0.9 // 滤波系数,接近1表示更慢响应,但更好的平滑效果

// 函数:实现一阶低通滤波器
float low_pass_filter(float input, float previous_output) {
    return FILTER_COEFFICIENT * previous_output + (1 - FILTER_COEFFICIENT) * input;
}

int main() {
    float input_samples[] = {1.0, 2.0, 3.0, 2.5, 2.0, 1.5, 1.0}; // 输入样本
    int num_samples = sizeof(input_samples) / sizeof(input_samples[0]);
    float output = 0.0; // 初始化输出值为0

    // 对每个输入样本应用滤波器
    for (int i = 0; i < num_samples; i++) {
        output = low_pass_filter(input_samples[i], output); // 更新输出
        printf("Filtered Output: %.2f\n", output); // 打印过滤后的输出
    }

    return 0;
}
2. 高精度计算
浮点单元(FPU)

知识点讲解:

现代微控制器通常内置了硬件浮点单元(FPU),可以直接支持IEEE 754标准的单精度(32位)和双精度(64位)浮点数运算。这使得执行复杂的数学运算更加容易,并且能够提供更高的精度。然而,浮点运算相对消耗更多的资源,因此需要权衡性能和功耗。

注意事项:

  • 使用浮点数时应注意溢出、舍入误差等问题。
  • 如果可能的话,尽量减少不必要的浮点运算,以节省资源。
定点数运算

知识点讲解:

对于没有FPU或者为了节省资源的情况,可以采用定点数运算。定点数是一种模拟浮点数的方式,但只使用整数表示法。开发者必须明确指定小数点的位置,并手动处理溢出等问题。虽然这种方法牺牲了一些灵活性和易用性,但它可以在资源受限的环境中提供足够的精度,同时保持较低的能耗。

注意事项:

  • 在设计定点算法时,需考虑数值范围和精度要求。
  • 必须小心处理乘法和除法操作,因为它们可能导致溢出或不准确的结果。

上述代码片段展示了如何在C语言中实现基本的数学运算以及简单的滤波算法。当涉及到更复杂的应用时,可能还需要考虑数值稳定性、边界条件处理等因素。此外,在选择浮点还是定点运算时,应该基于具体应用场景的要求来决定,考虑到精度需求、性能限制和功耗等因素。希望这些内容能帮助你更深入地理解各个知识点,并且能够根据提供的代码示例快速上手实践。

试卷

一、选择题(每题2分,共10分)

  1. 在计算平均值时,如果数据集为 x1,x2,...,xnx1​,x2​,...,xn​,则平均值的公式是:

    • A. mean=x1+x2+...+xnn+1mean=n+1x1+x2+...+xn
    • B. mean=x1+x2+...+xnnmean=nx1+x2+...+xn
    • C. mean=x1+x2+...+xn−1nmean=nx1+x2+...+xn−1
    • D. mean=x1+x2+...+xn−1n−1mean=n−1x1+x2+...+xn−1
  2. 下列哪种方法可以用来查找一组数据的最大值?

    • A. 遍历数组并更新最大值
    • B. 对数组进行排序后取第一个元素
    • C. 计算所有元素的和然后除以元素数量
    • D. 取所有元素的乘积再开平方根
  3. 一阶低通滤波器的主要作用是什么?

    • A. 提高信号频率
    • B. 减少高频噪声
    • C. 增加信号幅度
    • D. 改变信号相位
  4. 在嵌入式系统中,为了节省资源而选择不使用浮点运算时,通常会采用什么方式来替代?

    • A. 整数运算
    • B. 定点数运算
    • C. 字符串运算
    • D. 布尔运算
  5. 浮点单元(FPU)能够支持哪种标准的浮点数运算?

    • A. IEEE 754
    • B. ASCII
    • C. Unicode
    • D. UTF-8

二、简答题(每题10分,共30分)

  1. 描述如何在嵌入式系统中计算一组数值的平均值,并提供一个简单的C语言代码示例。

  2. 解释如何在嵌入式系统中找到一组数值的最大值和最小值,并给出相应的C语言代码。

  3. 说明一阶低通滤波器的工作原理及其在嵌入式应用中的实际用途,并附上一段C语言代码实现。


三、编程题(每题15分,共30分)

  1. 编写一段C语言代码,初始化一个包含若干整数的数组,并计算这些整数的平均值。

  2. 编写一段C语言代码,从用户输入获取一系列整数,存储在一个动态分配的数组中,然后找到这个数组中的最大值和最小值,并通过屏幕输出。

相关推荐
7yewh1 小时前
自制红外热像仪(二) MLX90640移植 RP2040 STM32 ESP32
驱动开发·stm32·单片机·嵌入式硬件·mcu·计算机视觉
冰糖雪莲IO2 小时前
【江协STM32】10-2/3 MPU6050简介、软件I2C读写MPU6050
stm32·单片机·嵌入式硬件
1101 11012 小时前
STM32-笔记39-SPI-W25Q128
笔记·stm32·嵌入式硬件
Leiditech__2 小时前
汽车氛围灯静电浪涌的难点
嵌入式硬件·汽车·硬件工程
云山工作室4 小时前
基于单片机的客车载客状况自动检测系统(论文+源码)
单片机·嵌入式硬件·毕业设计·毕设
2301_805962936 小时前
NRF24L01模块STM32通信-发送端
stm32·单片机·嵌入式硬件
LeoZY_8 小时前
CH348结合开源ModBus协议组成串口温度采集服务器
运维·笔记·嵌入式硬件·开源
我想学LINUX8 小时前
【STM32+QT项目】基于STM32与QT的智慧粮仓环境监测与管理系统设计(完整工程资料源码)
stm32·嵌入式硬件·qt·毕业设计·课程设计·项目开发
吾与春风皆过客8 小时前
STM32和国民技术(N32)单片机串口中断接收数据及数据解析
stm32·单片机·嵌入式硬件
JaneZJW8 小时前
江科大STM32入门——IIC通信笔记总结
c语言·笔记·stm32·单片机·嵌入式硬件·嵌入式·iic