在线时间6061 小时
UID3426478
注册时间2017-9-25
NXP金币5835
TA的每日心情 | 慵懒 6 小时前 |
---|
签到天数: 1487 天 [LV.10]以坛为家III
超级版主
- 积分
- 93291
- 最后登录
- 2024-5-11
|
本帖最后由 stm1024 于 2021-12-30 18:29 编辑
又到了年底了,回头看看这一年,感觉又是稀里糊涂中度过的……不过最近各路大佬都踊跃参加活动,也让我见识到了不少大佬的风采,年终庆典说到用显示屏的事儿,我也参与一下,其实总感觉这事儿吧,我也玩不出啥花样出来,有点千篇一律的感觉。但是呢,最近由于自己装逼好为人师,总觉得吧,自己说了又没说清楚,还不如不说,既然这样,我就献丑了。
故事的起因是看到@jundao721大佬做了一个动态的小广告牌,原链接是:【2021年度庆典三】+ LPC54114 基于u8g2小屏动态广告牌
他的想法还是很有创意的,但是我就bb说全屏刷新效果不好,建议局部刷新,可能没说的太清楚,所以值此机会,先阐述一下实现方法和显示效果,供大家参考。
先看两种效果吧:
上边的一种是全局刷新,下边一种是局部刷新,这里所说的全局刷新是指的将整个显示屏先清屏,然后再将所有内容重绘;而局部刷新是根据需要更新的区域重绘。两种的更新周期都是100ms,但是实际测试发现全局刷新时,100ms都有点吃力,感觉没有跑出100ms的效果,右边就感觉丝滑很多。
当然,之前使用的是LPC54114,我这里使用的是LPC54608,而且看样子原来使用的是SPI协议,我这里使用的是I2C协议。
不过咱们抛开事实不谈,呃,抛开硬件差异不谈,就说说原理吧。
局部刷新实现原理其实也很简单,大概是这么回事儿:
例如上面的这个图,中间的“淡定”是一直保持不变的,但是这个小X会一直更新,那么我们可以这样:
先用“橡皮擦”将原来位置的小X清除,然后再在新的位置画X,至于中间的图形,没变化我就不更新,这样数据操作量将会小很多。
以上面的这个为例,图片尺寸是128*64像素,则需要用的字节数是128*64/8=1024字节。
如果我只更新这个小X,是一个8*8的小区域,则擦除用到的字节是8*8/8=8字节,再加上绘制新的,也是8字节,则一次操作是16字节。
相比较而言,可以提高的倍数是1024/16=64。
现在问题是,那个“橡皮擦”是啥?
其实你可以把它理解为一个图形,我们看到的像素,1的位置是被点亮,0的位置是熄灭的,那么我们就给指定的区域发送8个0x00的字节,不就把这一块区域清空了嘛。然后我们再在新的位置绘制那个小X,就像是X在移动一样(眼睛被欺骗了)。
废话这么多,直接上代码:
首先是全局刷新:
- uint8_t cx=0,cy=0,direction=0;//当前的XY值
- SSD1306_ShowImg(0,0,128,8,BMP1);
- SSD1306_ShowImg(cx,cy,cx+8,cy+1,X88);
- while(1)
- {
- SSD1306_Clear(); //
- SSD1306_ShowImg(0,0,128,8,BMP1);//
- //SSD1306_ShowImg(cx,cy,cx+8,cy+1,BLANK88);//clear previous 'X'
- switch(direction)
- {
- case 0://at top, go right
- {
- if(cx==120)//right border
- direction=1;
- else
- cx+=8;
- break;
- }
- case 1://at right, go down
- {
- if(cy==7)
- direction=2;
- else
- cy++;
- break;
- }
- case 2://at bottom,go left
- {
- if(cx==0)
- direction=3;
- else
- cx-=8;
- break;
- }
- case 3://at left, go up
- {
- if(cy==0)
- direction=0;
- else
- cy--;
- break;
- }
- }
- SSD1306_ShowImg(cx,cy,cx+8,cy+1,X88);//draw new 'X'
-
- LED_Toggle(3);
- **elay_ms(100);
复制代码 留意这三行就行了,后面的都是控制下一个X显示的位置的:- SSD1306_Clear(); //
- SSD1306_ShowImg(0,0,128,8,BMP1);//
- //SSD1306_ShowImg(cx,cy,cx+8,cy+1,BLANK88);//clear previous 'X'
全局刷新使用了Clear,这样的所有的区域都要重绘,所以会看到左图中的效果,如果把这两行注释掉,再把蓝色的那一会取消注释,就可以实现局部刷新了。
最后,祝大家虎年都虎起来。
|
|