在 FLASH 中留下数据数组(字体) - AVR GCC 中的 PROGMEM
啊哈,PROGMEM,指针,指向指针的指针,指针的地址......我的头晕了。
我有一个有关字体的数据数组,
const uint8_t dejaVuSans9ptBitmaps[] =
{
/* @0 ' ' (5 pixels wide) */
0x00, /* */
0x00, /* */
...
我已将 PROGMEM 添加到其中,
const uint8_t dejaVuSans9ptBitmaps[] PROGMEM =
这在另一个结构中被引用,如下所示;
const FONT_INFO dejaVuSans9ptFontInfo = {
13,
' ',
'~',
dejaVuSans9ptDescriptors,
dejaVuSans9ptBitmaps,
};
该结构定义为;
typedef struct {
const uint8_t height;
const uint8_t startChar;
const uint8_t endChar;
const FONT_CHAR_INFO* charInfo;
const uint8_t* data;
} FONT_INFO;
我假设这需要更改为正确吗?
typedef struct {
const uint8_t height;
const uint8_t startChar;
const uint8_t endChar;
const FONT_CHAR_INFO* charInfo;
const PGM_P data;
} FONT_INFO;
当我这样做时,它会抱怨
warning: pointer targets in initialization differ in signedness
对于 FONT_INFO 变量中的这一特定行;
const FONT_INFO dejaVuSans9ptFontInfo = {
13,
' ',
'~',
dejaVuSans9ptDescriptors,
--> dejaVuSans9ptBitmaps, <--
};
然后使用该函数绘制它;
void drawString(uint16_t x, uint16_t y, uint16_t color, const FONT_INFO *fontInfo, char *str) {
...
drawCharBitmap(currentX, y, color, &fontInfo->data[charOffset], charWidth, fontInfo->height);
...
最终绘制出字形;
void drawCharBitmap(const uint16_t xPixel, const uint16_t yPixel, uint16_t color, const uint8_t *glyph, uint8_t cols, uint8_t rows) {
...
if (glyph[indexIntoGlyph] & (0X80)) drawPixel(currentX, currentY, color);
...
我很困惑:/有人能给我一些指导吗?我花了几个小时尝试使用 PGM_P 和 pgm_read_byte 等但无济于事 - 我总是在屏幕上看到垃圾。
救救我吧!
Ahhh, PROGMEM, pointers, pointers to pointers, addresses of pointers... My head boggles.
I have a data array for the font in question
const uint8_t dejaVuSans9ptBitmaps[] =
{
/* @0 ' ' (5 pixels wide) */
0x00, /* */
0x00, /* */
...
to which I have added PROGMEM
const uint8_t dejaVuSans9ptBitmaps[] PROGMEM =
This is referenced in another structure like so;
const FONT_INFO dejaVuSans9ptFontInfo = {
13,
' ',
'~',
dejaVuSans9ptDescriptors,
dejaVuSans9ptBitmaps,
};
The structure is defined as;
typedef struct {
const uint8_t height;
const uint8_t startChar;
const uint8_t endChar;
const FONT_CHAR_INFO* charInfo;
const uint8_t* data;
} FONT_INFO;
Am I correct in assuming this needs to change to;
typedef struct {
const uint8_t height;
const uint8_t startChar;
const uint8_t endChar;
const FONT_CHAR_INFO* charInfo;
const PGM_P data;
} FONT_INFO;
When I do so, it complains that
warning: pointer targets in initialization differ in signedness
For this particular line in the FONT_INFO variable;
const FONT_INFO dejaVuSans9ptFontInfo = {
13,
' ',
'~',
dejaVuSans9ptDescriptors,
--> dejaVuSans9ptBitmaps, <--
};
It is then drawn using the function;
void drawString(uint16_t x, uint16_t y, uint16_t color, const FONT_INFO *fontInfo, char *str) {
...
drawCharBitmap(currentX, y, color, &fontInfo->data[charOffset], charWidth, fontInfo->height);
...
Which finally draws the glyph;
void drawCharBitmap(const uint16_t xPixel, const uint16_t yPixel, uint16_t color, const uint8_t *glyph, uint8_t cols, uint8_t rows) {
...
if (glyph[indexIntoGlyph] & (0X80)) drawPixel(currentX, currentY, color);
...
I am in over my head :/ Can anyone give me some direction? I have spent hours trying to use PGM_P, and pgm_read_byte etc to no avail - I always get garbage on the screen.
Save me!
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
好吧,我想我明白这是怎么回事了。
首先,const uint8_t* data 是指向 PROGMEM 中存储的数据的指针。
在函数 void drawString(uint16_t x, uint16_t y, uint16_t color, const FONT_INFO *fontInfo, char *str) 中,我们传递一个指向
fontInfo
的指针。要继续,了解以下内容很重要;
都是一样的。所以
ptr_to_fontInfo->data
返回数据(不是地址)然后使用
&
运算符,我们将此数据的“地址”传递给下一个函数该地址是存储在此处声明的指针变量
unint8_t *glyph
中;牢记这一点;
然后字形现在指向与
fontInfo->data[charOffset]
相同的地址。接下来要知道的是;
因此 glyph 是一个指针,当像这样使用时
glyph[indexIntoGlyph]
,它与* 相同(glyph + indexIntoGlyph)
,解引用运算符*
意味着我们在该地址获取数据。从那里,我们可以使用我们描述的 pgm 规则;
希望这个解释是正确的,并帮助人们(像我这样的新手!)更好地理解它。
OK, I think I understand what is going on here.
First,
const uint8_t* data
is a pointer to the data stored in PROGMEM.In the
function void drawString(uint16_t x, uint16_t y, uint16_t color, const FONT_INFO *fontInfo, char *str)
we pass a pointer tofontInfo
.To continue, the following is important to understand;
are all the same. So
ptr_to_fontInfo->data
returns the data (not address)Then using the
&
operator, we pass the 'address of' this data to the next functionThis address is stored in the declared pointer variable
unint8_t *glyph
here;Keeping this in mind;
Then glyph now points to the same address as
fontInfo->data[charOffset]
.The next thing to know is;
So glyph being a pointer, when used like this
glyph[indexIntoGlyph]
, it is the same as*(glyph + indexIntoGlyph)
, and the dereferencing operator*
means we get the data at that address.From there, we can use the pgm rules as wex described;
Hope this explanation is correct and helps people (newbies like me!) understand it a bit better.
我在 AVRfreaks.net 上得到了一些大力支持,我想我应该在这里发布答案以供该社区将来参考。谢谢“威克”!
“wek”根据我提供的信息确定,我需要发送从
drawCharBitmap()
中的&fontInfo->data[charOffset]
开始的多个字节。我仍在尝试理解这里的链接,但这是一个很好的答案,值得放在这里。感谢所有花时间查看此内容的人。
I got some great support over at AVRfreaks.net, and thought I'd post the answer here for future reference by this community. Thanks 'wek'!
'wek' identified that based on the information I gave, that I needed to send multiple bytes starting from
&fontInfo->data[charOffset]
indrawCharBitmap()
.I'm still trying to understand the links here, but it was such a great answer it deserved to be put on here. Thanks to all who took the time to look at this.