首页 > 其他分享 >32单片机从入门到精通之测试与验证——单元测试(十五)

32单片机从入门到精通之测试与验证——单元测试(十五)

时间:2025-01-10 20:00:13浏览次数:3  
标签:32 单元测试 单片机 测试 每题 carry display 进位 255

人生苦短,我们都会面临困难和挑战。但是,只要我们保持积极的心态和勇往直前的精神,我们就能战胜一切困难,实现自己的目标。

成功并不是一蹴而就的,它需要我们付出努力和坚持不懈。就像爬山一样,我们可能会遇到陡峭的山路和艰难的攀登,但只要我们不放弃,不停止前进,就一定能登上山顶,看到美丽的风景。

每一次挑战都是一次成长的机会。当我们面对困难时,不要害怕,不要退缩,而是要勇敢地面对,勇往直前。在面对挫折和失败时,我们要学会反思和总结经验,不断调整自己的方法和策略,再次出发。只有经历过失败,我们才会更加珍惜成功的喜悦。

努力和坚持不仅仅是为了实现自己的梦想,更是为了成为更好的自己。在追求目标的过程中,我们会变得更加坚强、更加自信。每一次努力都会让我们变得更加优秀,无论结果如何,我们都会因为自己的付出而自豪。

在人生的道路上,没有永远的平坦,但也没有永远的困难。只要我们保持积极的心态,勇敢面对挑战,努力奋斗,我们就一定能够战胜困难,实现自己的梦想。让我们一起努力,继续前行,向着成功的方向迈进!

目录

上一张试卷

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

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

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

四、设计题(每题15分,共30分)

知识点讲解

1. 功能模块:8位加法器

2. 编写测试用例

3. 使用自动化测试框架

4. C语言代码及注释

5. 调试与仿真

仿真器调试

实际硬件调试

总结

试卷

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

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

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


上一张试卷

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

  1. 在嵌入式系统中,哪种屏幕类型通常具有更高的对比度和更薄的设计?

     

    B. OLED

  2. 使用Adafruit_SSD1306库控制OLED显示屏时,以下哪个函数用于清除屏幕内容?

     

    B. display.clearDisplay()

  3. 触摸屏的灵敏度可以通过调整哪个参数来改变?

     

    A. TOUCH_THRESHOLD

  4. 对于按键输入,Arduino中的INPUT_PULLUP模式的作用是什么?

     

    B. 内部上拉电阻

  5. 下列哪一项不是触摸屏接口常见的通信协议?

     

    D. USB (虽然USB可以用来连接触摸屏,但它不是直接的通信协议,I2C, SPI, 和UART是更为常见的触摸屏通信协议。)

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

  1. 描述如何在嵌入式系统中使用LCD/OLED屏幕显示信息,并说明可能需要的图形库支持。

     

    要在嵌入式系统中使用LCD或OLED屏幕显示信息,首先需要选择合适的屏幕控制器并安装相应的驱动库。例如,对于OLED屏幕,可以使用Adafruit提供的SSD1306库。初始化屏幕后,你可以通过调用库函数来绘制文本、图形等。

     

    可能需要的图形库支持包括:

    • 文本渲染:用于显示字符和字符串。
    • 形状绘制:如线条、矩形、圆等基本形状的绘制功能。
    • 图像处理:支持加载和显示位图图像。
    • 颜色管理:如果屏幕支持彩色显示,则需要颜色管理和转换的功能。
  2. 解释如何设计按键、触摸屏等人机交互界面以增强用户体验,并讨论如何集成到嵌入式系统中。

     

    设计人机交互界面(HMI)时,应该注重直观性和易用性。对于按键,应确保布局合理,标识清晰,响应及时。触摸屏则提供更加自然的操作方式,但需注意校准准确性和触控反馈。

     

    将这些组件集成到嵌入式系统中涉及硬件连接和软件编程两个方面。硬件上要正确连线;软件上,需要编写代码来读取按键状态或触摸坐标,并根据用户动作执行相应命令。此外,还可以加入声音或振动反馈来改善交互体验。

  3. 说明在设计用户界面时应考虑哪些因素来优化用户体验。

    • 直观性:界面应当易于理解和操作,避免复杂的导航结构。
    • 响应速度:保证系统对用户的每个动作都能快速响应。
    • 视觉设计:采用一致的颜色方案、字体大小等元素,使界面美观且易于阅读。
    • 可访问性:考虑到不同用户群体的需求,比如为视力受限者提供更大的字体或高对比度模式。
    • 容错机制:设计友好的错误提示信息,帮助用户理解问题所在,并指导他们如何纠正。
    • 性能优化:确保界面流畅运行,减少不必要的动画或特效以节省资源。

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

  1. 编写一段C语言代码,初始化一个OLED屏幕并打印“Hello, World!”。
#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>

#define SCREEN_WIDTH 128 // OLED display width, in pixels
#define SCREEN_HEIGHT 64 // OLED display height, in pixels

// Declaration for an SSD1306 display connected to I2C (SDA, SCL pins)
#define OLED_RESET    -1 // Reset pin # (or -1 if sharing Arduino reset pin)
Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, OLED_RESET);

void setup() {
  // Initialize the OLED display
  if(!display.begin(SSD1306_SWITCHCAPVCC, 0x3C)) { // Address 0x3C for 128x64
    Serial.println(F("SSD1306 allocation failed"));
    for(;;);
  }
  display.clearDisplay();
  display.setTextSize(1);      // Normal 1:1 pixel scale
  display.setTextColor(SSD1306_WHITE); // Draw white text
  display.setCursor(0,0);     // Start at top-left corner
  display.cp437(true);         // Use full 256 char 'Code Page 437' font

  // Display static text
  display.print("Hello, World!");
  display.display();           // Show initial text
}

void loop() {
  // Nothing here, all is done in setup()
}
  1. 编写一段C语言代码,检测一个物理按键的状态并在按键按下时通过OLED屏幕显示一条消息。
const int buttonPin = 2; // The number of the pushbutton pin
int lastButtonState = LOW;
unsigned long lastDebounceTime = 0;  // the last time the output pin was toggled
unsigned long debounceDelay = 50;    // the debounce time; increase if the output flickers

void setup() {
  pinMode(buttonPin, INPUT_PULLUP);
  if (!display.begin(SSD1306_SWITCHCAPVCC, 0x3C)) {
    Serial.println(F("SSD1306 allocation failed"));
    for (;;);
  }
  display.clearDisplay();
  display.display();
}

void loop() {
  int reading = digitalRead(buttonPin);

  if (reading != lastButtonState) {
    lastDebounceTime = millis();
  }

  if ((millis() - lastDebounceTime) > debounceDelay) {
    if (reading != HIGH) {
      display.clearDisplay();
      display.print("Button Pressed");
      display.display();
    }
  }

  lastButtonState = reading;
}

四、设计题(每题15分,共30分)

  1. 设计一个简单的菜单系统,该系统使用四个按键进行导航(上、下、确认、返回)。

     

    这个菜单系统的实现可以基于一个循环结构,在其中检查按键状态,并根据按下的键更新当前选中的菜单项索引。当“确认”键被按下时,执行对应菜单项的动作。为了防止按键抖动影响程序逻辑,每次按键事件都应包含去抖处理。

  2. 设计一个基于触摸屏的用户界面,允许用户从几个预设选项中选择一个。

     

    主屏幕可以列出所有可用选项,每个选项作为一个按钮。点击某个按钮后进入对应的子屏幕,子屏幕上同样可以有其他选项或者返回主屏幕的按钮。为了实现这种多级菜单结构,你需要维护一个状态机来跟踪当前所在的屏幕层级,并根据触摸位置判断用户选择了哪个按钮。同时,确保触摸屏校准准确,以便能够精确识别用户意图。

知识点讲解

我将详细讲解如何为一个嵌入式系统中的功能模块编写单元测试用例,并使用仿真器或实际硬件平台进行调试。我们将以一个简单的8位加法器为例,不仅提供理论知识,还会包括具体的C语言代码示例和详细的注释。

1. 功能模块:8位加法器

在数字逻辑中,8位加法器接收两个8位二进制数作为输入,并输出它们相加的结果(同样是一个8位二进制数)。如果加法导致结果超出8位的表示范围,则会产生一个进位标志。

2. 编写测试用例

为了验证8位加法器的功能正确性,我们需要考虑以下几种类型的测试用例:

  • 正常情况:测试普通值的加法。
  • 边界条件:如0 + 0, 255 + 0, 0 + 255, 255 + 255等极端情况。
  • 溢出情况:当两个较大的数相加时可能会产生溢出,这时需要检查进位标志是否被正确设置。
  • 错误处理:虽然在这个例子中没有明确的错误状态,但在其他更复杂的模块中,你可能需要测试模块对无效输入或其他异常情况的反应。

3. 使用自动化测试框架

我们将使用Google Test (gtest) 来实现单元测试。如果你的项目是纯C语言编写的,你可以选择类似的C语言测试框架如CUnit。

4. C语言代码及注释

首先,我们定义8位加法器函数:

#include <stdint.h>

/**
 * @brief 实现一个8位加法器。
 * 
 * @param a 第一个8位无符号整数
 * @param b 第二个8位无符号整数
 * @param carry 指向存储进位标志的变量指针
 * @return uint8_t 返回8位加法结果
 */
uint8_t adder_8bit(uint8_t a, uint8_t b, uint8_t *carry) {
    uint16_t sum = (uint16_t)a + (uint16_t)b;
    // 如果sum大于255,说明有进位
    *carry = (sum > 255) ? 1 : 0;
    // 返回低8位作为结果
    return (uint8_t)(sum & 0xFF);
}

接下来,我们将编写对应的测试用例。假设你已经在项目中集成了Google Test。

#include <gtest/gtest.h>
#include "adder_8bit.h" // 包含上述定义的adder_8bit函数头文件

// 测试正常加法情况
TEST(Adder8BitTest, NormalCase) {
    uint8_t carry;
    // 测试10 + 20应该等于30且无进位
    EXPECT_EQ(adder_8bit(10, 20, &carry), 30);
    EXPECT_EQ(carry, 0);
}

// 测试边界条件
TEST(Adder8BitTest, BoundaryConditions) {
    uint8_t carry;
    // 测试0 + 0应该等于0且无进位
    EXPECT_EQ(adder_8bit(0, 0, &carry), 0);
    EXPECT_EQ(carry, 0);

    // 测试255 + 0应该等于255且无进位
    EXPECT_EQ(adder_8bit(255, 0, &carry), 255);
    EXPECT_EQ(carry, 0);

    // 测试0 + 255应该等于255且无进位
    EXPECT_EQ(adder_8bit(0, 255, &carry), 255);
    EXPECT_EQ(carry, 0);

    // 测试255 + 255应该等于254且有进位
    EXPECT_EQ(adder_8bit(255, 255, &carry), 254);
    EXPECT_EQ(carry, 1);
}

// 测试溢出情况
TEST(Adder8BitTest, Overflow) {
    uint8_t carry;
    // 测试200 + 70应该等于14并产生进位
    EXPECT_EQ(adder_8bit(200, 70, &carry), 14); // 因为200 + 70 = 270, 但是8位只能表示到255
    EXPECT_EQ(carry, 1);
}

// 如果你的环境支持运行这些测试,请确保链接了gtest库,并且编译和运行此文件。
int main(int argc, char **argv) {
    ::testing::InitGoogleTest(&argc, argv);
    return RUN_ALL_TESTS();
}

5. 调试与仿真

仿真器调试

对于FPGA或类似的硬件描述语言(如VHDL/Verilog)实现的加法器,可以使用ModelSim等仿真工具创建一个测试平台来模拟各种输入条件,并观察输出和进位信号的变化。

实际硬件调试

一旦通过了仿真阶段,就可以将代码烧录到实际的嵌入式系统上,比如Arduino、Raspberry Pi或者专用的开发板。连接调试器(如JTAG/SWD),然后通过串口通信或者其他接口监视程序的执行情况,确保一切工作正常。

  • 烧录固件:使用适当的编程工具(如AVRDUDE用于Arduino)将编译后的二进制文件上传到目标板上。
  • 连接调试工具:根据硬件平台的不同,使用合适的接口(如JTAG或SWD)连接PC与目标板,以便实时监控程序执行。
  • 现场测试:在实际工作条件下测试系统,确保它按照预期的方式运行,并能够承受现实世界的各种挑战。

总结

以上就是针对8位加法器模块的单元测试编写过程以及利用仿真器或实际硬件平台进行调试的详细介绍。希望这个例子能帮助你理解如何为数字逻辑设计编写有效的测试用例,并进行充分的调试。

试卷

一、选择题(每题2分,共20分)
  1. 在数字逻辑中,哪一种门电路只有当所有输入都为高电平时输出才为高电平? A. AND门
    B. OR门
    C. NOT门
    D. NAND门

  2. 如果一个8位二进制数的最高位是符号位,那么它可以表示的最大正整数值是多少? A. 127
    B. 128
    C. 255
    D. 256

  3. 下列哪一项不是组合逻辑电路的特点? A. 输出仅取决于当前输入
    B. 没有记忆功能
    C. 包含反馈路径
    D. 实现即时响应

  4. Karnaugh图主要用于什么目的? A. 简化布尔表达式
    B. 设计时序逻辑电路
    C. 编写程序代码
    D. 绘制电路图

  5. VHDL和Verilog属于哪种类型的编程语言? A. 高级编程语言
    B. 硬件描述语言
    C. 脚本语言
    D. 数据库查询语言

  6. 以下哪一项不是可编程逻辑器件(PLD)的优点? A. 成本低
    B. 易于修改设计
    C. 开发周期长
    D. 可以重复编程

  7. 对于一个四位二进制加法器,如果两个操作数都是1111,那么结果是什么? A. 0000,进位=0
    B. 1110,进位=1
    C. 1111,进位=0
    D. 0000,进位=1

  8. 哪种触发器在时钟信号上升沿到来时改变状态? A. RS触发器
    B. JK触发器
    C. D触发器
    D. T触发器

  9. 测试平台(testbench)主要用于做什么? A. 编译硬件描述语言代码
    B. 仿真和验证电路行为
    C. 部署应用程序到嵌入式系统
    D. 设计用户界面

  10. IEEE 754标准定义了哪种类型的数据格式? A. ASCII字符编码
    B. Unicode字符编码
    C. 浮点数运算规则
    D. UTF-8字符编码

二、简答题(每题10分,共30分)
  1. 描述什么是有限状态机(FSM),并给出一个简单的例子说明它如何工作。

  2. 解释Karnaugh图的作用,并提供一个使用K-map简化布尔表达式的实例。

  3. 说明为什么在数字逻辑设计中使用硬件描述语言(HDL)进行电路设计变得越来越重要。

三、编程题(每题15分,共30分)
  1. 编写一段C语言代码,实现一个函数,该函数接收两个8位无符号整数作为参数,并返回它们相加后的结果。同时,通过指针参数返回是否产生了进位。

  2. 编写一个简单的测试平台(testbench),用于验证上述加法器函数的功能。测试平台应该包括至少三种不同的测试用例:正常情况、边界条件以及溢出情况。

标签:32,单元测试,单片机,测试,每题,carry,display,进位,255
From: https://blog.csdn.net/speaking_me/article/details/145064433

相关文章

  • STM32之LWIP网络通讯设计-上(十四)
    STM32F407系列文章-LWIP-Network(十四)目录前言一、以太网简介二、网络协议简介1.OSI模型2.TCP/IP协议3.协议层报文间的封装与拆封4.lwIP1.lwIP特性2.lwIP开源网址3.lwIP参考书籍三、通讯连接示意四、STM32内部ETH 1.内部MAC2.内部DMA五、PHY驱动芯片1.功......
  • 单片机实物成品-011 火灾监测
    火灾监测(20个版本)版本20:oled显示+温湿度+烟雾浓度+火焰传感器+天然气浓度+窗户+风扇+水泵+排气系统+声光报警+语音播报+按键+WIFI模块-----------------------------------------------------------------------------https://www.bilibili.com/video/BV1N6YaekEgw/?spm_id......
  • 单片机毕业设计项目分享(4)
    毕业设计项目单片机12329草原防灾减害监控系统的设计与实现单片机12328仓储多点温度湿测量系统单片机12327病房呼叫系统实物单片机12326便携式气象仪单片机12325便携式可充电,可调亮度Led灯设计单片机12324变电站综合监控系统的设计单片机12323变电站蓄电池组工作状态在......
  • SENT协议深度解析-----使用STM32发送SENT信号
    一、SENT信号的结构在上一期中,我们介绍了SENT信号的接收,这一期我们来讲解一下SENT信号的发送,在讲解之前,我们需要先了解一下SENT信号的结构,SENT信号分为两种类型:快速通道类型、慢速通道类型,慢速通道分为短串行数据、增强串行数据,一共三种信号结构发送方式,在汽车MCU领域中,SEN......
  • 【STM32】MCU运行多段代码,Flash程序更新的实现方式之一
    【STM32】MCU运行多段代码,Flash程序更新的实现方式之一文章目录BootLeader跳转到BootLeader跳转到Flash其他位置MCU运行多段代码其他程序更新烧录方式附录:Cortex-M架构的SysTick系统定时器精准延时和MCU位带操作SysTick系统定时器精准延时延时函数阻塞延时非阻塞延时......
  • 从玩具到工业控制--51单片机的跨界传奇【1】
    由于博主本人即喜欢软件也喜欢硬件,硬件方面更偏向于单片机的学习和使用。为了知识的巩固和提高,所以打算开辟一个新的专栏——51单片机。我们就以经典且基础的51单片机讲起,帮助大家为后面学习更高级的单片机打好基础。我们会从零基础进行讲解,欢迎各位点赞+收藏+转发+评论,谢谢各......
  • 怎么提升单片机代码执行效率
    提升单片机代码执行效率是一个综合性的任务,涉及代码优化、硬件资源利用、编译器设置等多个方面。以下是本人的一些具体的方法和建议:一、代码优化减少冗余代码:通过代码复用和模块化,避免在程序中出现重复的代码段。例如,使用函数封装重复的操作,减少代码冗余,提高执行效率。简化算......
  • 02-51单片机数码管与矩阵键盘
    一、数码管模块1.数码管介绍如图所示为一个数码管的结构图:说明:数码管上下各有五个引脚,其中上下中间的两个引脚是联通的,一般为数码管的公共端,分为共阴极或共阳极;其它八个引脚分别对应八个二极管,从a~g包括右下角的点,每个二极管与就近的引脚一一对应。2.单片机数......
  • 01-51单片机LED与独立按键
    一、单片机概述注意:个人学习笔记,里面涉及到的C语言和进程转换相关的知识在C语言部分已经写了,这里是默认都会的状态学习单片机。1.什么是单片机单片机,英文MicroControllerUnit,简称MCU。其内部集成了CPU、RAM、ROM、定时器、中断系统、通讯接口等一系列电脑的常用硬件功......
  • 基于单片机的智能苗圃灌溉系统设计与实现:嵌入式程序设计
    基于单片机的智能苗圃灌溉系统设计与实现:嵌入式程序设计引言随着智能化农业的迅速发展,传统的农业灌溉模式逐渐被现代化智能灌溉系统取代。智能苗圃灌溉系统作为智能农业的重要组成部分,通过结合传感器技术、单片机控制技术以及数据通信技术,能够实现苗圃灌溉的自动化与智能......