当前位置:首页 > 显示光电 > 显示光电
[导读]16×16点阵屏跑滚动动画,卡顿和鬼影基本不是IO不够,而是“主循环delay刷屏+直接改显示数据”这套写法不对。正确结构是:字模只作数据源、显示缓冲隔离硬件、定时器中断做行扫描、主循环只改滚动偏移。


16×16点阵屏跑滚动动画,卡顿和鬼影基本不是IO不够,而是“主循环delay刷屏+直接改显示数据”这套写法不对。正确结构是:字模只作数据源、显示缓冲隔离硬件、定时器中断做行扫描、主循环只改滚动偏移。

一、字模格式先统一

16×16单色点阵每字32字节,每行16点拆成2字节,行优先存。

取模规则必须固定成一条:

横向取模

高位在前(bit7对应最左列)

字节顺序和扫描代码一致

const uint8_t font_hi[] = {   // “示”示例占位

0x00,0x00,0x00,0x00,0x00,0x3E,0x00,0x02,

/* ...共32字节... */

};

取模工具和驱动解析不匹配,字就左右镜像或断笔,先拿“实心行0xFF,0xFF”测一遍再上汉字。

二、显示缓冲:中断和主循环分开

直接把字模往屏上推,滚动时半截旧帧半截新帧=撕裂。开一块当前屏缓冲:

#define COL_BYTES 2

uint8_t disp_buf[16][COL_BYTES];   // 当前16行×16列

volatile uint8_t cur_row = 0;

行扫描用定时器中断,例如1ms一次,扫一行;16行扫完约16ms,整屏刷新约60Hz,肉眼不闪。

void TIM_IRQHandler(void){

   row_off_all();                       // 消隐,防鬼影

   send_col_data(disp_buf[cur_row]);    // 列数据进595

   select_row(cur_row);                 // 开当前行

   latch_595();

   cur_row = (cur_row+1) & 0x0F;

}

中断里只做“取缓冲→发数据→切行”,别做位移、别做memcpy、别delay。

三、滚动本质:偏移截取

整条标语先做字模拼接缓冲,比如“HELLO”5字×16列=80列,每列16bit:

uint8_t msg_buf[80][COL_BYTES];   // 预展开成列

int scroll_off = 0;               // 像素列偏移

刷新屏缓冲时,从msg_buf里按偏移取16列填进disp_buf:

void build_frame(void){

   for(int r=0;r<16;r++){

       for(int c=0;c<16;c++){

           int src = scroll_off + c;

           if(src < MSG_COLS)

               disp_buf[r][c>>3] = msg_buf[src][r];

           else

               disp_buf[r][c>>3] = 0;   // 空白填充

       }

   }

}

纯左移每帧scroll_off++即可;想平滑到“像素级”就用位偏移把相邻两列做移位或运算,别整字节跳。

四、速度别在中断里调

滚动节奏放主循环定时器或软计数:

void app_1ms_tick(void){

   static uint16_t cnt=0;

   if(++cnt >= 30){          // 约30ms移一列

       cnt=0;

       scroll_off++;

       if(scroll_off >= MSG_COLS) scroll_off=0;

       build_frame();

   }

}

中断只管刷屏,主循环只管“下一帧内容”,两者解耦后CPU还能同时扫按键、解串口。

五、流畅的几个硬点

消隐必须做:切行前关所有行,不然旧列数据在新行亮一下出鬼影

双缓冲可选:build_frame写到back buf,中断切换front指针,滚动更稳

取模方向错:字镜像,先测单行

中断里算位移:扫描周期被拉长→闪

共阳/共阴取反:列数据按硬件反相,别在字模里硬改逻辑

74HC595时序:DS稳定→SHCP上升沿→STCP锁存,别把列数据和行选同时打

亮度不均:每行点亮时间要等长约1ms,别前面行多刷后面行少刷

六、最小落地顺序

静态显示一个汉字:字模→disp_buf→中断扫描

确认无鬼影、无镜像

多字拼msg_buf

主循环改scroll_off

build_frame截取

调速、加留白、循环复位

16×16点阵流畅滚动的核心就一句:字模是源,disp_buf是当前帧,中断只搬运,滚动只是偏移量往前推。主循环动内容、中断动时序,两边不抢同一块数据,动画就顺;反过来在中断里直接改字模、在主循环里delay刷屏,多少优化都救不回来。



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