当前位置:首页 > 显示光电 > 显示光电
[导读]电子纸不是“写显存就出图”的LCD。墨水粒子靠电压时序迁移,驱动IC按波形表(LUT)逐帧加压,画面才定型。 全刷干净但慢(单色常2~5秒、伴闪),局刷快且无闪,但多次会留残影。 低功耗驱动的本质就是:平时不刷、变化才刷、局刷为主、定期全刷兜底。


电子纸不是“写显存就出图”的LCD。墨水粒子靠电压时序迁移,驱动IC按波形表(LUT)逐帧加压,画面才定型。 全刷干净但慢(单色常2~5秒、伴闪),局刷快且无闪,但多次会留残影。 低功耗驱动的本质就是:平时不刷、变化才刷、局刷为主、定期全刷兜底。

一、控制器里的两块RAM

以SSD1680类SPI电子纸为例,驱动IC内部通常有:

0x24:当前新帧(黑白位图)

0x26:上一帧基准(局刷差分用)

0x22选刷新模式,0x20触发物理刷新

BUSY高电平表示波形执行中,别抢发命令

MCU侧再维护一份old_buf作软件基准,用来算脏区。

二、显存差分:只发变化行

电子纸SPI量小不代表能偷懒,全屏每次重发既慢又费电。标准做法是字节比对:

#define EPD_W 128

#define EPD_H 296

#define LINE_BYTES (EPD_W/8)


static uint8_t new_buf[EPD_H*LINE_BYTES];

static uint8_t old_buf[EPD_H*LINE_BYTES];


void epd_flush_partial(uint16_t x,uint16_t y,uint16_t w,uint16_t h){

   epd_wait_busy();                 // BUSY必须低

   for(int row=y; row<y+h; row++){

       uint8_t* n = &new_buf[row*LINE_BYTES];

       uint8_t* o = &old_buf[row*LINE_BYTES];

       int x0=LINE_BYTES, x1=-1;

       for(int i=0;i<LINE_BYTES;i++){

           if(n[i]!=o[i]){

               if(i<x0)x0=i; x1=i;

           }

       }

       if(x1<0) continue;           // 本行无变化

       epd_set_window(x0 * 8, row, (x1+1)*8-1, row);

       epd_write_ram(0x24, &n[x0], x1-x0+1);

       memcpy(o+x0, n+x0, x1-x0+1);

   }

   epd_update(EPD_MODE_PARTIAL);    // 0x22+0x20

}

局刷窗口一定要覆盖“旧内容实际占的区域”,只框新文字宽度常会留边影。

三、全刷计数器:残影兜底

局刷波形不给粒子完整复位,黑→白大面积切换几次就糊。 工程做法:

static uint8_t partial_cnt = 0;

#define PARTIAL_MAX 8


void epd_update_ui(const uint8_t*frame){

   memcpy(new_buf, frame, sizeof(new_buf));

   int diff = epd_calc_dirty(new_buf, old_buf);

   if(partial_cnt>=PARTIAL_MAX || diff>EPD_H*LINE_BYTES/2){

       epd_load_lut(FULL_LUT);

       epd_flush_full(new_buf);     // 清屏+整帧重写

       memcpy(old_buf, new_buf, sizeof(old_buf));

       partial_cnt = 0;

   }else{

       epd_load_lut(PARTIAL_LUT);

       epd_flush_partial(0,0,EPD_W,EPD_H);

       partial_cnt++;

   }

}

判据两条:

局刷次数超阈值 → 全刷

变化像素超比例(换页/切界面)→ 直接全刷

纯更新时间数字可以连刷多次;切菜单必须全刷。

四、LUT别自己拍电压

波形表是屏厂按膜片批次、温度曲线标定的,包含正反压、相位时长、DC平衡。 C代码里只做“选择LUT”,不手搓脉冲序列:

void epd_load_lut(const uint8_t*lut, int len){

   epd_cmd(0x32);

   for(int i=0;i<len;i++) epd_data(lut[i]);

}

低温场景用厂方给的低温LUT切换,别靠延时凑。

五、低功耗时序

电子纸静止时不耗电,耗电全在刷新瞬间:

唤醒RES(退出deep sleep必须复位)

初始化+装LUT

写0x24/0x26

等BUSY低

触发刷新,再等BUSY低

进0x10 deep sleep

MCU自己STOP/WFI

void epd_sleep(void){

   epd_wait_busy();

   epd_cmd(0x10); epd_data(0x01);   // deep sleep

}

刷新中途别切Wi-Fi/大电流动作,电压跌落会残影。

六、落坑清单

BUSY高时发SPI→命令丢失、控制器卡死

局刷不更新old_buf→下次差分错

只发新文字区→旧字残影

每次都全刷→慢、闪、费电

LUT自己改电压→批次屏发灰

局刷计数不设→半小时糊成一片

deep sleep不复位RES→下次唤不醒

SPI时钟顶太高→长排线丢字节

七、落地顺序

驱动IC确认(SSD1680/UC8151等)

维护new_buf/old_buf两份显存

字节级diff算脏行/脏矩形

局刷走0x24+partial LUT

计数或变化率触发全刷

全刷前装full LUT、整帧重写

每次等BUSY

刷完deep sleep,MCU进STOP

电子纸低功耗显示的关键不在“刷得快”,在“尽量少刷”。局刷解决日常更新功耗,全刷解决残影累积,波形LUT解决显示质量——三层配合起来,墨水屏才能真正做到“电池跑几个月”:静止零功耗,更新只动脏区,几小时一次全刷清底。代码层就是显存差分+模式切换+BUSY守门,别把电子纸当LCD刷。



本站声明: 本文章由作者或相关机构授权发布,目的在于传递更多信息,并不代表本站赞同其观点,本站亦不保证或承诺内容真实性等。需要转载请联系该专栏作者,如若文章内容侵犯您的权益,请及时联系本站删除( 邮箱:macysun@21ic.com )。
关闭