gpt4 book ai didi

c++ - 在PROGMEM中添加更多数据会中断Arduino Mega 2560上的SPI传输

转载 作者:行者123 更新时间:2023-12-02 10:37:18 26 4
gpt4 key购买 nike

我正在做一个涉及Arduino Mega(2560)和Waveshare ePaper显示器的小项目(或我认为是这样)。

我已经使它与库(epd7in5)一起正常工作,并将两个图像添加到PROGMEM中。但是,一旦我添加了第三张图像(并因此在PROGMEM中添加了第三项),ePaper屏幕就不会再启动了。在库中添加一些调试信息表明代码被卡在特定的SPI.transfer()上。

编辑:理论
当闪存中的数据过多时,SPI是否可能不兼容?我已经读过它最大为64kb。我有两个图像,略高于该图像,但三个图像则明显高于该图像。可能会破坏SPI吗?如果是这样,我可以解决它吗?

我添加了以下代码以及SPI.transfer()失败的库的特定部分。

Main.cpp

删除与dummy3相关的代码可确保dummy3数组不被编译。仅使用dummy1和dummy2一切正常。添加dummy3,程序陷入epd.Init()

#include <SPI.h>
#include <epd7in5.h>
#include "imagedata.h"

Epd epd;

void debug(String);

void setup() {
Serial.begin(9600);
debug("Serial begin");

if (epd.Init() != 0) {
debug("INIT FAILED!");
return;
}

debug("Changing image");
epd.DisplayFrame(dummy1); //DisplayFrame by default includes WaitUntilIdle.
debug("dummy1 on ePaper");
delay(1000);
debug("Changing image");
epd.DisplayFrame(dummy2);
debug("dummy2 on ePaper");
delay(1000);
debug("Changing image");
epd.DisplayFrame(dummy3);
debug("dummy2 on ePaper");
epd.SendCommand(POWER_OFF);
debug("POWER_OFF");
}

void loop() {
}

void debug(String message) {
Serial.print(millis());
Serial.print("\t");
Serial.println(message);
}

imagedata.cpp

我已经删除了很多实际的图像数据。
两张图片产生的总闪存为67326字节(约占2560总闪存的26%)。
三个图像导致的总闪存为98052字节(约占2560总闪存的38%)。
头文件仅包含声明。
#include "imagedata.h"
#include <avr/pgmspace.h>

const unsigned char dummy1[30726] PROGMEM = {...data...};
const unsigned char dummy2[30726] PROGMEM = {...data...};
const unsigned char dummy3[30726] PROGMEM = {...data...};

epd7in5.cpp

我添加了调试功能。 SendData也包括在内,并且也使用调试。
void Epd::debug(String message) {
Serial.print(millis());
Serial.print("\t");
Serial.print("EPD");
Serial.print("\t");
Serial.println(message);
}

int Epd::Init(void) {
if (IfInit() != 0) {
return -1;
}

debug("Resetting");
Reset();

debug("SendCommand(POWER_SETTING);");
SendCommand(POWER_SETTING);
debug("SendData(0x37);");
SendData(0x37);
debug("SendData(0x00);");
SendData(0x00);

debug("SendCommand(PANEL_SETTING);");
SendCommand(PANEL_SETTING);
SendData(0xCF);
SendData(0x08);

SendCommand(BOOSTER_SOFT_START);
SendData(0xc7);
SendData(0xcc);
SendData(0x28);

SendCommand(POWER_ON);
WaitUntilIdle();

SendCommand(PLL_CONTROL);
SendData(0x3c);

SendCommand(TEMPERATURE_CALIBRATION);
SendData(0x00);

SendCommand(VCOM_AND_DATA_INTERVAL_SETTING);
SendData(0x77);

SendCommand(TCON_SETTING);
SendData(0x22);

SendCommand(TCON_RESOLUTION);
SendData(0x02); //source 640
SendData(0x80);
SendData(0x01); //gate 384
SendData(0x80);

SendCommand(VCM_DC_SETTING);
SendData(0x1E); //decide by LUT file

SendCommand(0xe5); //FLASH MODE
SendData(0x03);

return 0;
}

void Epd::SendData(unsigned char data) {
debug("DigitalWrite(dc_pin, HIGH);");
DigitalWrite(dc_pin, HIGH);
debug("SpiTransfer(data);");
SpiTransfer(data);
}

epdif.cpp

这是SPI传输部分,不会继续。
void EpdIf::SpiTransfer(unsigned char data) {
digitalWrite(CS_PIN, LOW);
SPI.transfer(data);
digitalWrite(CS_PIN, HIGH);
}

该项目的串行打印如下...
0   Serial begin
0 EPD Resetting
400 EPD SendCommand(POWER_SETTING);
400 EPD SendData(0x37);
400 EPD DigitalWrite(dc_pin, HIGH);
435 EPD SpiTransfer(data);

因此,只要运行 SpiTransfer,该代码就会停止工作。看来它在 SPI.transfer();中处于无限循环中,但我不知道到底会如何发生。我看不到 PROGMEM如何干扰传输,而且我还有足够的闪存...

有什么解决方案?我需要更改SPI中的问题吗?还是我需要以其他方式将数据存储在 PROGMEM中?我有点茫然。

在此先感谢您的帮助,不胜感激。

最佳答案

您的问题不在于SPI(本身)。

它与您在程序和读取中拥有的数据量有关。如果您使用的Progmem数量超过64k,则会遇到两套不同的问题:

  • 以可靠的方式读取数据

  • 读取程序应该使用 pgm_read_xxx_far宏用于任何
    65536之后的地址。 Epd::DisplayFrame使用
    pgm_read_byte(&frame_buffer[i]);,所以您在
    库级别。我对该图书馆不熟悉,所以不确定
    如果您可以调用并提供其他功能
    从PROGMEM中读取缓冲区后,自己缓冲
    pgm_read_byte_far。这是问题的简单部分
  • 首先将数据输入到PROGMEM中

  • Arduino核心和avr编译器本身都假定所有指针仅为16位。将数据放入PROGMEM,将使其出现在运行程序的最终可执行文件中的arduino核心和可执行代码之前。

    正确执行此操作的可靠方法是使用自定义链接程序脚本,该脚本将使您的数据不受影响,并将其放置在所有可执行代码之后。这将很困难,而且恐怕我无法提供有关如何完成此操作的任何信息。

    另外,您可以尝试使用 _attribute__((section(".fini2")))来使用 .fini2部分。以前有人做过,对他们有用。

    您将这样使用它:
    const unsigned char __attribute__((section(".fini2"))) dummy1[30726] = {...data...};

    最后一种选择是完全不使用PROGMEM,而要使用某种外部存储来存储数据(例如某些SDCard)。这很可能是解决该问题的最简单方法。

    来源:westfw在arduino论坛上的出色文章和精彩见解:
    https://forum.arduino.cc/index.php?topic=485507.0

    关于c++ - 在PROGMEM中添加更多数据会中断Arduino Mega 2560上的SPI传输,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59663714/

    26 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com