3

我有一个项目,其中一个 ATtiny2313V 正在控制一个 7x5 LED 矩阵来显示滚动文本。为了显示文本,我构建了一个字体,它与程序的其余部分一起存储在闪存中。

整个程序,包括整个字体,占用了 1106 个字节。但是当我将它加载到芯片中时,它似乎没有运行;相反,它只是点亮了几个 LED,仅此而已。

但是,当我删除大部分字体并仅使用字母 A 到 J 进行编译时,程序大小为 878 字节,并且运行良好。

这是因为 AVR 闪存的某种溢出吗?

ATtiny2313V 的数据表说它有 2KByte 的闪存!1106字节怎么会太多呢?

更新:为了清楚起见,我使用的工具链是 AVR Studio(用于编译代码),然后 AVRDude 将其上传到微控制器。据我所知,AVR Studio 使用一个版本的 avr-gcc 来编译代码。

4

3 回答 3

7

我不确定您使用的是什么工具链,但在 avr-gcc 中,您需要使用<avr/pgmspace.h>标头在闪存中存储和访问数据 - 仅声明您的数据是不够的,const因为它仍然加载到内存中运行时,因此占用闪存和内存中的空间(就像任何其他初始化变量一样)。

查看用户手册标题文档了解更多信息。用法相当简单,在flash中声明一个char数组,使用PROGMEM宏:

char data[] PROGMEM = {0xc4, 0x77}; // etc

然后为了访问数据,您需要使用提供的宏

char d = pgm_read_byte(&(data[i]));

编辑:还请记住,avrdude 仅报告 ram 的静态分配部分(.data 和 .bss),用于全局变量和静态变量等。您需要为堆栈留出空间 - 多少取决于您的程序(提示:递归不好)。

于 2009-10-27T06:05:50.227 回答
2

我发誓 SO 有一些神奇之处;几个星期以来,我一直在绞尽脑汁,试图弄清楚这一点,在这里提出问题后 - 我终于可以看到一直盯着我的脸!

以下是仅使用字体中的 AJ 字母进行编译的内存使用情况:

AVR Memory Usage
----------------
Device: attiny2313

Program:     872 bytes (42.6% Full)
(.text + .data + .bootloader)

Data:         82 bytes (64.1% Full)
(.data + .bss + .noinit)

这里又是字母 AZ:

AVR Memory Usage
----------------
Device: attiny2313

Program:     952 bytes (46.5% Full)
(.text + .data + .bootloader)

Data:        162 bytes (126.6% Full)
(.data + .bss + .noinit)

看到126.6%数据中的?哎呀!我真的溢出了!

于 2009-10-19T20:41:58.737 回答
1

检查你的堆栈没有溢出?这可能会产生难以检测的崩溃。您可以在编译器/链接器设置中的某处设置堆栈大小,也可以将一些局部变量转换为全局变量。嵌入式处理器通常没有任何堆栈溢出检查,它只是崩溃。

于 2009-10-19T10:04:06.060 回答