You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Arduino电容电量三位七段数码管显示异常及串口乱码问题

问题分析与解决方案

老哥你这问题典型得很——堆内存泄漏导致的溢出,这可是Arduino这类小内存MCU上的高频踩坑点,咱们一步步捋清楚:

问题根源:内存泄漏榨干了堆空间

你的Decode函数每次调用都会用new uint8_t[3]动态分配数组,但调用Show(number)后,这块内存从来没被释放。像Uno这类板子堆空间才2KB左右,反复调用几次chargeDisplay.Show(),堆直接就被耗空了。之后的内存操作(比如串口输出的缓冲区分配、数码管驱动的变量读写)会开始乱踩其他内存区域,这就是你看到的:

  • 数码管数秒后停在最后一位:程序内存混乱,没法正常更新显示逻辑
  • 串口先正常输出"a",之后乱码甚至喷完整ASCII序列:堆溢出破坏了串口的内部缓冲区或相关变量,导致输出彻底失控

另外,你的codes成员用new动态分配完全没必要,不仅浪费堆空间,还多了个潜在泄漏风险(虽然这个只初始化一次,但完全可以用更安全的方式)。

具体修复步骤

1. 彻底干掉Decode函数的内存泄漏

别再动态分配digits数组了,改成让调用者提供数组(或者用栈上的数组),彻底绕开堆操作:

先在头文件里更新Decode的声明:

void Decode(uint8_t number, uint8_t digits[]);

然后在cpp文件里实现这个函数:

void Display::Decode(uint8_t number, uint8_t digits[]) {
  // 先把所有位初始化为空白(对应codes[10])
  digits[0] = codes[10];
  digits[1] = codes[10];
  digits[2] = codes[10];

  if (number == 0) {
    digits[2] = codes[0];
    return;
  }

  uint8_t offset = 2;
  while (number > 0) {
    Serial.println("a");
    digits[offset] = codes[number % 10];
    number /= 10;
    offset--;
    // 防止offset越界(number最大100,offset最多到0)
    if (offset < 0) break;
  }
}

接着修改Show(uint8_t)函数,用栈上的数组接收解码结果:

void Display::Show(uint8_t number) {
  uint8_t digits[3]; // 栈上数组,函数结束自动释放,不用手动管内存
  Decode(number, digits);
  Show(digits);
}

2. 优化codes数组的定义

把动态分配的codes改成静态const数组,这样会被存放在Flash内存里(能省出宝贵的SRAM),还更安全:

在头文件的类私有成员里声明:

private:
  uint8_t* an;
  uint8_t* ca;
  // 声明静态const数组
  static const uint8_t codes[11];

在cpp文件里初始化这个数组:

// 七段码初始化,自动存到Flash中
const uint8_t Display::codes[11] = {
  0b11111100, 0b01100000, 0b11011010, 0b11110010, 
  0b01100110, 0b10110110, 0b10111110, 0b11100000, 
  0b11111110, 0b11110110, 0b00000000
};

3. 可选小优化

你的Show(uint8_t values[])函数里,delayMicroseconds(1)可以根据实际显示效果调整(比如改成2-3微秒),避免数码管闪烁,但这不是核心问题,修复内存泄漏后再微调就行。

修复后为啥能解决问题?

  • 栈上数组会在函数执行完自动释放,彻底杜绝内存泄漏
  • 静态const数组存放在Flash,不占用SRAM,给MCU留更多可用内存
  • 堆内存不再被耗尽,程序的内存操作恢复正常,数码管和串口输出自然就稳定了

内容的提问来源于stack exchange,提问作者trinarSK

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.11 09:29:16