一.问题描述

遇到个问题,就是我的点阵屏 st7567有两种开机启动页面模式,一种是文字开机logo,一种是图片的的开机logo,因为我做的是多国语言,所以内存都快用没有了,我的芯片是py32f030x8,64kb的flash,8kb的ram,然后我现在出现的问题是,领导叫我加几个内容,就是WiFi蓝牙那些字模,后文会看到,就是不加就没啥事,加了就有问题了,不是这有问题就是那又问题,我加上了个阿拉伯语的内容文字就会出现一种问题:如果在图片logo模式下,就正常,但是要是文字logo的话就会,中文语言下,要么文字是乱成一团的点点,要么就是成功的跳转页面√,他是有一些乱糟糟毛刺点点,,相反不论怎么优化,就是要么这边没问题,但是切换开机logo选项另一边就会出现问题

然后我用keil的o2优化就都没有问题了,就说明基本上是内存的问题,

然后!

但是我师傅说最好用o1,然后我师傅也帮我分析了一下,

比如出现那种√的点点边边角角的毛刺,他叫我把√和×的的字模顺序换一下,

以前√在×的后面,现在√变×前面去了,那就是√没有边边角角的毛刺了,反倒是×有了,以前×没有的,

师傅说可能是内存的原因但是他也不知道具体的。

内存溢出?数组溢出?栈?还是什么,真的让我一头雾水,

但是还是解决了,内存的问题,因为你都是接近64kb的flash跑,风险还是很大的。

二.相关代码

2.1我的.map
Total RO Size (Code + RO Data) 64248 ( 62.74kB) 
Total RW Size (RW Data + ZI Data) 2928 ( 2.86kB) 
Total ROM Size (Code + RO Data + RW Data) 64408 ( 62.90kB)
2.2我的logo切换代码:
开机logo切换: /*--开关:文字图片<!!!!!!LOGO模式修改此处!!!!!!>----------------------------------------------------*/
    /*--<0>--图片LOGO----------------------------------------------------------------------------------*/ 
    /*--<1>--文字LOGO----------------------------------------------------------------------------------*/
    #if 1
    #define SWT_LOGO_TEXT 1 //LOGO_文字
    #else 
    #define SWT_LOGO_DRAW 2 //LOGO_图片 #endif
2.3logo的基础代码

/************************************************************************************************************************
函数名称: lcd_logo_texts_display
函数功能: LCD文字LOGO显示
输入参数: void
返回参数: void
特别说明:
************************************************************************************************************************/
void lcd_logo_texts_display(void)
{
#ifdef NEU_SmartBMS__t
    uint8_t* cn_logo_row2[4] = {HZ_Dian_4, HZ_Chi__2, HZ_Guan_3, HZ_Li___3};
    uint8_t* cn_logo_row3[4] = {HZ_Huan_1, HZ_Ying_2, HZ_Shi__3, HZ_Yong_4};

    switch(LCD__DATA.LANG_MODE)
    {
        case CHINESE_e:
        {
            st7567_display_chinese(LCD_ROW_2, 34, cn_logo_row2, 4);
            st7567_display_chinese(LCD_ROW_3, 34, cn_logo_row3, 4);
        }break;
	.....
        case HUNGARY_e:
        {
            st7567_display_strings(LCD_ROW_2, 38, "okos  BMS");
            st7567_display_strings(LCD_ROW_3, 10, "?dv=z=lj)k  haszn*lni");
        }break;
        default:
        {
            ;
        }break;
    }
#endif

void lcd_gui_lv0_logologo(void)
{
    lcd_gui_lv0______gif();

#ifdef SWT_LOGO_TEXT
    lcd_gui_lv0_wordages();
#endif
#ifdef SWT_LOGO_DRAW
    lcd_gui_lv0_pictures();
#endif
}

/************************************************************************************************************************
函数名称: lcd_gui_lv0______gif
函数功能: GUI_LV0_动态图
输入参数: void
返回参数: void
特别说明: 0-0
************************************************************************************************************************/
void lcd_gui_lv0______gif(void)
{
#ifdef SWT_SHOW__GIF
    if (TIME_INFO.Timer_Gif__Show >= 3400 && TIME_INFO.Timer_Gif__Show < 4000)
    {
        LCD__DATA.GIF__FLAG = OFF_e;
        TIME_INFO.Timer_Gif__Show = 6000;
        st7567_clear_allof();
#ifndef SWT_SHOW_LOGO
        LCD__DATA.TAB___ROW = 1;
#endif
    }
    if (TIME_INFO.Timer_Gif__Show >= 3200 && TIME_INFO.Timer_Gif__Show < 3400)
    {
        st7567_graphic__128x64(1, 1, GIF_NO__4);
    }
  .....
#endif
}

/************************************************************************************************************************
函数名称: lcd_gui_lv0_wordages
函数功能: GUI_LV0_文字LOGO
输入参数: void
返回参数: void
特别说明: 0-0
************************************************************************************************************************/
void lcd_gui_lv0_wordages(void)
{
    if (LCD__DATA.GIF__FLAG == OFF_e)
    {
        lcd_logo_texts_display();
    }
    if (LCD__DATA.TAB___ROW == 1)
    {
        st7567_clear_allof();
    }
}

/************************************************************************************************************************
函数名称: lcd_gui_lv0_pictures
函数功能: GUI_LV0_图片LOGO
输入参数: void
返回参数: void
特别说明: 0-0
************************************************************************************************************************/
void lcd_gui_lv0_pictures(void)
{
    if (LCD__DATA.GIF__FLAG == OFF_e)
    {
        st7567_graphic__128x64(1, 1, DRAW_LOGO);
		
    }
    if (LCD__DATA.TAB___ROW == 1)
    {
        st7567_clear_allof();
    }
}
2.4我的添加的字模

这里原来是200的数组大小,我给他增大一点点基本上能够兼顾两边,

但是又太大了,而且也会有一些小问题,

以前还有就是我的某一个页面直接卡住,只显示一个文字,等等,

 typedef struct WORD_INFO_struct
{
    uint8_t width;
    uint8_t w_info[218];//原来是200的大小,注意这里有问题
}WORD_INFO_t;,,

阿拉伯的字模:
const WORD_INFO_t AR_qaunbugaunbi={52,{0x00,0x00,0x40,0xE0,0xE0,0x40,0x00,0x00,0x00,0x00,0x80,0x00,0x00,0x00,0x80,0x00,
                                       0x00,0x80,0xC0,0xC0,0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x30,0x00,
                                       0xB0,0x00,0x00,0x18,0x30,0x60,0x80,0xF8,0x00,0x00,0xC0,0x6C,0x60,0x40,0x00,0x00,
                                       0x00,0x00,0xF8,0x00,0x00,0x0E,0x19,0x30,0x33,0x36,0x16,0x06,0x36,0x06,0x33,0x06,
                                       0x02,0x07,0x0D,0x07,0x06,0x06,0x06,0x32,0x03,0x03,0x03,0x00,0x00,0x00,0x00,0x1C,
                                       0x30,0x30,0x30,0x37,0x15,0x0F,0x00,0x04,0x04,0x06,0x03,0x03,0x06,0x06,0x07,0x07,
                                       0x06,0x02,0x01,0x00,0x28,0x14,0x13,0x00,}};
//wifi
const WORD_INFO_t AR_WIFI={42,{0x00,0x00,0x00,0x00,0x00,0x80,0x40,0x60,0xC0,0x80,0x00,0xF8,0x00,0x00,0x00,0x00,
                              0xCC,0xA0,0xC0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x40,0x60,0xC0,
                              0x80,0x00,0xF8,0x00,0x00,0x00,0x00,0x00,0x80,0x00,0x00,0x0E,0x1D,0x28,0x19,0x2B,
                              0x1B,0x0E,0x06,0x00,0x00,0x03,0x06,0x06,0x06,0x06,0x06,0x02,0x01,0x00,0x00,0x00,
                              0x00,0x00,0x0E,0x1D,0x28,0x19,0x2B,0x1B,0x0E,0x06,0x00,0x00,0x07,0x00,0x10,0x30,
                              0x30,0x37,0x15,0x0F,}};

//蓝牙
const WORD_INFO_t AR_BLue={31,{0x00,0x80,0x00,0x30,0x0C,0x30,0x00,0x80,0x00,0x00,0x00,0x00,0x80,0x00,0x00,0x30,
                               0x00,0xB0,0x00,0x00,0x00,0x00,0x80,0x00,0x00,0x00,0xF8,0x00,0x00,0x00,0x80,0x00,
                               0x03,0x06,0x06,0x06,0x06,0x06,0x03,0x10,0x30,0x30,0x37,0x15,0x0F,0x06,0x06,0x06,
                               0x03,0x10,0x30,0x30,0x37,0x15,0x0F,0x06,0x06,0x03,0x06,0x06,0x36,0x03,}};

 const WORD_INFO_t AR_open={30,{0x00,0x00,0x00,0x00,0x00,0x00,0xF8,0x00,0x00,0x00,0x80,0x00,0x80,0xD8,0xC0,0x80,
                               0x00,0x00,0x00,0x00,0x00,0x18,0x86,0x18,0xC0,0x80,0x00,0x30,0x00,0xB0,0x00,0x1C,
                               0x32,0x30,0x30,0x10,0x0F,0x06,0x36,0x06,0x33,0x06,0x06,0x03,0x07,0x06,0x06,0x06,
                               0x06,0x03,0x06,0x06,0x03,0x06,0x06,0x03,0x06,0x06,0x06,0x03,}};,中文汉字: const uint8_t HZ_dakai_1[]={0x00,0x08,0x08,0xFF,0x88,0x48,0x02,0x02,0x02,0x02,0xFE,0x02,0x02,0x02,0x00,0x00, 
                            0x00,0x21,0x21,0x3F,0x00,0x00,0x00,0x00,0x20,0x20,0x3F,0x00,0x00,0x00,0x00,0x00,};
//汉字字模,我原本以为是他的问题😬

//开
 const uint8_t HZ_kai_1[]={0x00,0x40,0x41,0x41,0xFF,0x41,0x41,0x41,0x41,0x41,0xFF,0x41,0x41,0x40,0x00,0x00,
                          0x00,0x20,0x10,0x0C,0x03,0x00,0x00,0x00,0x00,0x00,0x3F,0x00,0x00,0x00,0x00,0x00,};
//关
const uint8_t HZ_gaun_1[]={0x00,0x80,0x88,0x88,0x89,0x8E,0x88,0xF8,0x88,0x8C,0x8B,0x88,0x88,0x80,0x00,0x00,
                           0x00,0x20,0x20,0x10,0x08,0x04,0x03,0x00,0x03,0x04,0x08,0x10,0x20,0x20,0x00,0x00,};
//闭
const uint8_t HZ_Bi_1[]={0x00,0x00,0xF9,0x02,0x20,0x22,0x22,0xA2,0x62,0xFA,0x22,0x22,0x02,0xFE,0x00,0x00,
                         0x00,0x00,0x3F,0x00,0x04,0x02,0x01,0x08,0x08,0x0F,0x00,0x20,0x20,0x3F,0x00,0x00,};

//全
const uint8_t HZ_quan_1[]={0x00,0x40,0x40,0x20,0x50,0x48,0x44,0xC3,0x44,0x48,0x50,0x20,0x40,0x40,0x00,0x00,
                           0x00,0x20,0x20,0x20,0x22,0x22,0x22,0x3F,0x22,0x22,0x22,0x20,0x20,0x20,0x00,0x00,};

//部
const uint8_t HZ_Bu_1[]={0x00,0x40,0x54,0x65,0x46,0x44,0x64,0x54,0x40,0x00,0xFE,0x02,0x62,0x9E,0x00,0x00,
                         0x00,0x00,0x3E,0x12,0x12,0x12,0x12,0x3E,0x00,0x00,0x3F,0x08,0x08,0x07,0x00,0x00,};
2.5调用相关字模的的函数

//蓝牙WiFi显示
void lcd_gui_WiFi_Blue_Select(void)
{
    uint8_t *cn_sign_head[1] = {SY_Square};
    uint8_t *cn_sign_tail[1] = {SY_Arrows};

  uint8_t *cn_CHR_LanYa[4] = {HZ_dakai_1, HZ_kai_1, HZ_Lan__1, HZ_Ya___2}; // 打开蓝牙
     uint8_t *cn_CHR_Dakai[2] = {HZ_dakai_1, HZ_kai_1};                       // 打开WiFi
     uint8_t *cn_CHR_qaunbu[4] = {HZ_quan_1, HZ_Bu_1, HZ_gaun_1, HZ_Bi_1};    // 全部关闭


    switch (LCD__DATA.LANG_MODE)
    {

    case ENGLISH_e:
    {
        st7567_display_strings(LCD_ROW_1, 20, "Turn off All");
        st7567_display_strings(LCD_ROW_2, 20, "Turn on Bluetooth");
        st7567_display_strings(LCD_ROW_3, 20, "Turn on WiFi");
    }
    break;

    case CHINESE_e:
    {

        st7567_display_chinese(LCD_ROW_1, 20, cn_CHR_qaunbu, 4);
        st7567_display_chinese(LCD_ROW_2, 20, cn_CHR_LanYa, 4);
        st7567_display_chinese(LCD_ROW_3, 20, cn_CHR_Dakai, 2);
		 st7567_display_strings(LCD_ROW_3, 55, "WiFi");
    }
    break;
	
	
      case ARABIC__e:{
     st7567_display___words(LCD_ROW_1, 20, &AR_qaunbugaunbi);
	    st7567_display___words(LCD_ROW_2, 20, &AR_open);//打开
	  st7567_display___words(LCD_ROW_2, 50, &AR_BLue);
	      st7567_display___words(LCD_ROW_3, 20, &AR_open);//打开
	  st7567_display___words(LCD_ROW_3, 50, &AR_WIFI);
      }
      break;
........
    }

    // 通用显示
    st7567_display_chinese(LCD_ROW_1, 115, cn_sign_tail, 1);
    st7567_display_chinese(LCD_ROW_2, 115, cn_sign_tail, 1);
    st7567_display_chinese(LCD_ROW_3, 115, cn_sign_tail, 1);
    st7567_display_chinese(LCD__DATA.SEL___ROW + 1, 0, cn_sign_head, 1);
}
2.6屏幕驱动函数

注意关注这个函数:uint8_t st7567_display___words(uint8_t y_row, uint8_t x_col, const WORD_INFO_t* word_info),后面用得到


const CHAR_INFO_t CHAR_LIB_ENGLISH[CHAR_LIB_MAX] = {

/*--英文字符---------------------------------------------------------------------------------------*/
    {'a',  6,  {0x00,0x00,0x00,0x00,0x00,0x00,0x1A,0x25,0x25,0x3E,0x20,0x00,                   }},
    {'b',  6,  {0xE0,0x00,0x00,0x00,0x00,0x00,0x1F,0x22,0x21,0x21,0x1E,0x00,                   }},
  ........ 
    {'Y',  8,  {0x20,0xE0,0x20,0x00,0x20,0xE0,0x20,0x00,0x00,0x01,0x22,0x3C,0x22,0x01,0x00,0x00}},
    {'Z',  8,  {0x60,0x20,0x20,0x20,0xA0,0x60,0x20,0x00,0x30,0x28,0x24,0x23,0x20,0x20,0x38,0x00}},
/*--通用字符---------------------------------------------------------------------------------------*/
}

const CHAR_INFO_t CHAR_LIB_Deyu_SPECIAL[deyu_size] = 
{
		/*--德语字符---------------------------------------------------------------------------------------*/
	 {'@',  6,  {0x00,0x40,0x00,0x40,0x00,0x00,0x1A,0x25,0x25,0x15,0x3E,0x00 				   }},	//a..
	 {'!',  8, {0x00,0x84,0x4C,0x40,0x4C,0x84,0x00,0x00,0x00,0x0F,0x10,0x10,0x10,0x08,0x07,0x00,	}},//^o^	
	{'(',  4,  {0x00,0xF0,0x80,0x00,0x02,0x1F,0x00,0x00,}},  //    /|
};
....



/************************************************************************************************************************
函数名称: st7567_display_charter
函数功能: ST7567字符显示
输入参数: void
返回参数: void
特别说明:
************************************************************************************************************************/
uint8_t st7567_display___words(uint8_t y_row, uint8_t x_col,  const WORD_INFO_t* word_info)
{
    uint16_t i           = 0;
    uint16_t j           = 0;
    uint8_t  addr_row_A  = 0;
    uint8_t  addr_col_H  = 0;
    uint8_t  addr_col_L  = 0;
    uint8_t  row_y       = y_row * 2 - 1;
    uint8_t  col_x       = x_col;
    uint8_t  width       = word_info->width;
    uint8_t const *ginfo = &word_info->w_info[0];

    addr_row_A =   0xB0 + row_y - 1;
    addr_col_H = ((col_x >> 4) & 0x0F) + 0x10;
    addr_col_L =  (col_x & 0x0F- 1);

/*--字符显示-----------------------------------------------------------------------------*/
    for(i = 0; i < 2; i++)
    {
        LCD_WR_CMD(addr_row_A + i);
        LCD_WR_CMD(addr_col_H);
        LCD_WR_CMD(addr_col_L);

        for(j = 0; j < width; j++)
        {
            LCD_WR_DAT(*ginfo);
            ginfo++;
        }
    }

    return (col_x + width);
},




//这个函数我重写了,因为共享默认的英文,其他的语言是独立的字库,就不用单独的额外重复写
//如上头所示
uint8_t st7567_display_strings(uint8_t y_row, uint8_t x_col, char* string)
{

	uint8_t row_y = y_row * 2 - 1;
		uint8_t col_x = x_col;
		uint8_t char_index;
		uint16_t xioangyali_special_count;
		uint16_t fayu_special_count;
		uint16_t yuenan_special_count;
		uint16_t deyu_special_count;
		uint16_t bolanyu_special_count;
		if(col_x >= 128) return col_x;
	
		while(col_x < 128 && *string)
		{
			if(*string == '\r' || *string == '\n' || *string == 0)
			{
				return col_x;
			}
	
			// 根据当前语言选择查找表
			switch(LCD__DATA.LANG_MODE)
			{
				case HUNGARY_e:
					// 先在匈牙利特殊字符表中查找

					 xioangyali_special_count = sizeof(CHAR_LIB_HU_SPECIAL) / sizeof(CHAR_INFO_t);
					char_index = find_char_in_table(*string, CHAR_LIB_HU_SPECIAL, xioangyali_special_count);
					if(char_index != 0xFF)
					{
						col_x = st7567_display_charter(row_y, col_x, &CHAR_LIB_HU_SPECIAL[char_index]);
					}
					else
					{
						// 在共享表中查找
						char_index = find_char_in_table(*string, CHAR_LIB_ENGLISH, CHAR_LIB_MAX);
						if(char_index != 0xFF)
							col_x = st7567_display_charter(row_y, col_x, &CHAR_LIB_ENGLISH[char_index]);
						else
							col_x = st7567_display_charter(row_y, col_x, &CHAR_LIB_ENGLISH[0]);  // 默认字符
					}
					break;
					
			......
				default:
					// 其他语言只查找共享表
					char_index = find_char_in_table(*string, CHAR_LIB_ENGLISH, CHAR_LIB_MAX);
					if(char_index != 0xFF)
						col_x = st7567_display_charter(row_y, col_x, &CHAR_LIB_ENGLISH[char_index]);
					else
						col_x = st7567_display_charter(row_y, col_x, &CHAR_LIB_ENGLISH[0]);
					break;
			}
			
			string++;
		}
		
		return col_x;


	
},,,
/************************************************************************************************************************
函数名称: st7567_display_chinese
函数功能: ST7567汉字显示
输入参数: void
返回参数: void
特别说明:
************************************************************************************************************************/
void st7567_display_chinese(uint8_t y_row, uint8_t x_col,  uint8_t *buff_array[], uint8_t buff_num)
{
    uint8_t i     =  0;
    uint8_t row_y = (y_row - 1) * 2 + 1;
    uint8_t col_x = x_col;

    while(i <= (buff_num - 1))
    {
        st7567_graphic___08x16(row_y, col_x, buff_array[i]);
        col_x += CN_CHAR_WIDTH;
        i++;
    }
}/************************************************************************************************************************
函数名称: display_graphic_8x16
函数功能: ST7567固定显示:8x16
输入参数: void
返回参数: void
特别说明:
************************************************************************************************************************/
void st7567_graphic___08x16(uint8_t y_row, uint8_t x_col,  uint8_t *buff)
{
    uint8_t i          = 0;
    uint8_t j          = 0;
    uint8_t addr_row_A = 0;
    uint8_t addr_col_H = 0;
    uint8_t addr_col_L = 0;
    uint8_t row_y      = y_row;
    uint8_t col_x      = x_col;

    addr_row_A =   0xB0 + row_y - 1;
    addr_col_H = ((col_x >> 4) & 0x0F) + 0x10;
    addr_col_L =  (col_x & 0x0F - 1);

/*--字符显示-----------------------------------------------------------------------------*/
    for(i = 0; i < 2; i++)
    {
        LCD_WR_CMD(addr_row_A + i);
        LCD_WR_CMD(addr_col_H);
        LCD_WR_CMD(addr_col_L);

        for(j = 0; j < 16; j++)
        {
            LCD_WR_DAT(*buff);
            buff++;
        }
    }
}
2.7栈的问题吗?

也不是。我也考虑了一下栈的原因,增大了也没什么用,


Stack_Size      EQU     0x00000400

                AREA    STACK, NOINIT, READWRITE, ALIGN=3
Stack_Mem       SPACE   Stack_Size
__initial_sp


; <h> Heap Configuration
;   <o>  Heap Size (in Bytes) <0x0-0xFFFFFFFF:8>
; </h>

Heap_Size       EQU     0x00000000

                AREA    HEAP, NOINIT, READWRITE, ALIGN=3
__heap_base
Heap_Mem        SPACE   Heap_Size
__heap_limit,,

三 解决

3.1 问题分析

1.现在遇到的并不是“单一 bug”,而是一个「Flash 几乎顶满 + 字模数据越界/重叠 + 显存写入未受保护」叠加引发的典型嵌入式显示灾难。
所以它才会表现为:

  • 文字 LOGO / 图片 LOGO 二选一时必坏一个
  • 加阿拉伯语后随机花屏 / 毛刺 / 偶尔正常
  • 优化这里,那里又炸
  • 调栈、调数组大小只能“缓解”,不能根治

结合我的看法,师傅的看法,还有ai的看法,就是内存的原因,那现在只有在优化了

给的数据已经说明一切

2.“贴着天花板在跑”

Flash 总容量:64 KB

Total ROM Size = 64408 bytes (62.90 KB)
Total RO Size  = 64248 bytes (62.74 KB)

只剩不到 1KB 的安全余量

这在 MCU 里是极度危险状态,尤其还在做:

  • 大量 const 字模数组
  • 多语言
  • 图片 + GIF
  • 函数指针表
  • 条件编译切换不同显示路径

⚠️ 任何一个数组越界、编译器重排、对齐变化,都会直接踩到别人的数据


3.这个“毛刺点点”的根因不是 LCD,也不是栈

你描述的现象非常关键:

  • 中文文字 LOGO 下
    • 要么乱码成点
    • 要么能跳转
    • 要么有毛刺
  • 图片 LOGO 下正常
  • 两种模式互相“此消彼长”

❌ 这不是:

  • LCD 时序问题(否则图片也会炸)
  • SPI/I2C 硬件问题
  • 栈溢出(你已经验证过)

✅ 真正原因是 「字模数据被当成别的东西在读」


4.最关键的炸点:**WORD_INFO_t**你现在的定义:

typedef struct WORD_INFO_struct
{
    uint8_t width;
    uint8_t w_info[218];
} WORD_INFO_t;

靠增大数组能缓解”,本身就是越界铁证

你自己已经发现了:

👉 **w_ino** 从 200 改大,问题缓解
👉 但太大会引入新问题

这在嵌入式里意味着什么?

你之前已经发生了读越界
✅ 只是“越界刚好没踩到致命数据”
✅ 改大只是把“雷往后挪了几步”你现在的系统里,其实已经发生过这些事

5.你自己也提到了,非常重要

“某一个页面直接卡住,只显示一个文字”

“切换语言后行为不一致”

这 100% 是:

Flash const 区被当成了函数指针 / 数据结构在读

你还有这个:

void (*LCD_GUI_TABLE[20][8])();

如果字模数组越界,踩到它会发生什么?

👉 直接跳转到错误地址
👉 界面卡死
👉 只显示一个字
👉 程序没 HardFault,但逻辑死了

6.为什么「图片 LOGO 正常,文字 LOGO 炸」
这是一个非常经典的 MCU 行为:
图片 LOGO 路径
st7567_graphic__128x64(…)

特点:
固定 1024 字节
memcpy / DMA 一次性写
不会越界读
文字 LOGO 路径
st7567_display_chinese()
st7567_display___words()
st7567_display_strings()

特点:
指针 + width + 自己算偏移
字模数组长度不统一
多语言条件编译
很容易越界
👉 所以你看到的是:
“文字模式才会花,图片模式不花”

3.2解决方案

字模长度显式化,取消固定长度,节省空间

typedef struct {
    uint8_t width;
    uint16_t size;     // ⭐ 明确数据长度
    const uint8_t *buf;
} WORD_INFO_t;

改为:

const uint8_t AR_open_buf[] = { ... };

const WORD_INFO_t AR_open = {
    .width = 30,
    .size  = sizeof(AR_open_buf),
    .buf   = AR_open_buf,
};

然后就真的节省7kb左右的内存,问题消除

为什么当时用的固定长度啊,师傅写的,那时候不需要这么多内容,谁知道后面就加越多
收工哈哈哈,今晚可以早点下班了。

Logo

有“AI”的1024 = 2048,欢迎大家加入2048 AI社区

更多推荐