本文主要是介绍#基于NRF52832的墨水屏移植与GUI设计(2),希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!
1 屏幕显示原理
2 图片文字显示
屏幕显示原理
任何的屏幕,都是由一个个的像素点组成的。无论是LCD,OLED ,还是这个墨水屏,屏幕最终的显示效果,是由它的一个个像素点整体的组合效果,所以无论是哪种数据的传输都是在屏幕上打点。通过控制像素点颜色,进行显示不同的色彩。我们将显示的数据,通过取模获得一个包含字体信息的数组,把数据送入屏幕,然后显示出来。
墨水屏显示原理
墨水屏的显示与其他屏幕的显示原理是不同的。它本身是不发光的,而是靠外界光线的反射而显示。所以它正常显示时是几乎不耗电的,只有在刷新显示过程中才会耗电。所以比较省电,而且显示效果和纸质书籍效果相当,相比其他屏幕,是比较护眼的。
图.墨水屏的屏幕
上电时,带有不同电压的“油墨”,在不同极性电压的作用下,黑色“油墨”跑到上面,白色“油墨”跑到下面,屏幕就开始显示颜色了。
2.13寸黑白红三色墨水屏
对于黑白红三色,可以拆分为黑白图片、红白图片,然后将两张图片叠加起来就变成了黑白红图片了,所以黑白红的刷新是指是 对于黑白图片,我们可以规定,如果如果是黑色我们定义成0,如果是白色就定义成1,那么有了表示颜色的方式:
白色:□,对应1
黑色:■:对应0
一个点在图形上一般称之为像素点(pixel),而颜色不是1就是0,也就是1个位就可以标识颜色:1Pixel = 1bit,那么一个字节里面就包含了8个像素点。
以16个像素点为例,我们假设前8个像素点为黑,后8个像素点为白色,那么可以这么认为,像素点1-16,对应这0位到15位,0表示黑色,1表示白色:
对于2.13inch e-paper B,是红黑白三色,我们需要把图片拆成2张图片,一张黑白图片,一张红白图片,在传输的时候因为一个寄存器是控制黑白显示的,一个寄存器是控制红白
显示。 2.13的黑白部分1个字节控制8个像素点,红白部分1个字节控制8个像素点
举个栗子,假设有8个像素点,前面4个是红色,后面4个黑色:
需要把他们拆成一个黑白图片,一个红白图片,这两个图片都是8个像素点,只不过黑白图片前四个像素为白色,后4个像素点为黑色,而红白图片前4个像素点为红色,后四个像素点为白色 。
*摘微雪的原理介绍
显示函数
我们用的是元泰给的驱动,(开发墨水屏的都知道元太吧?)在此基础上修改,以适应nordic芯片。
图片显示
在这里插入代码片
`void dis_img(unsigned char num)
{unsigned int wide, high;unsigned int pcnt;
/***************************************************bw image****************************************************/SPI4W_WRITECOM(0x4E); //Set RAM X address SPI4W_WRITEDATA(0x00);SPI4W_WRITECOM(0x4F); //Set RAM Y address SPI4W_WRITEDATA(0xF9);SPI4W_WRITEDATA(0x00);SPI4W_WRITECOM(0x24); //Write RAM (Black White)pcnt = 0; // 复位或保存提示字节序号for(wide=0; wide<250; wide++) {for(high=0; high<16; high++) /{switch (num){case PIC_A://SPI4W_WRITEDATA(gImage_YB02[pcnt]);SPI4W_WRITEDATA(gImage_1_bw[pcnt]);break; case PIC_B:SPI4W_WRITEDATA(gImage_2d13_CSDL_bw[pcnt]);break;case PIC_C:SPI4W_WRITEDATA(gImage_WYJTEST_BW3[pcnt]);break;case PIC_R:SPI4W_WRITEDATA(0x00);break;case PIC_E:SPI4W_WRITEDATA(gImage_H213TEST[pcnt]);break; case PIC_VLINE:if(col<80)SPI4W_WRITEDATA(0x00);elseSPI4W_WRITEDATA(0xff);break;case PIC_HLINE:if(row<5)SPI4W_WRITEDATA(0x00);elseSPI4W_WRITEDATA(0xff);break; case PIC_WHITE:SPI4W_WRITEDATA(0xff);break; case PIC_BLACK:SPI4W_WRITEDATA(0x00);break; default:break;}pcnt++;}}/***************************************************bw image****************************************************/SPI4W_WRITECOM(0x4E); // set RAM x address count to 0;SPI4W_WRITEDATA(0x00);SPI4W_WRITECOM(0x4F); // set RAM y address count to 296; 2D9SPI4W_WRITEDATA(0xF9);SPI4W_WRITEDATA(0x00);SPI4W_WRITECOM(0x26);pcnt = 0; // 复位或保存提示字节序号for(wide=0; wide<250; wide++) // 总共250列 {for(high=0; high<16; high++) // 总共122行,每个像素1bit,即 122/8 字节{switch (num){case PIC_A://SPI4W_WRITEDATA(gImage_YB03[pcnt]);SPI4W_WRITEDATA(gImage_1_red[pcnt]);break; case PIC_B:SPI4W_WRITEDATA(gImage_2d13_CSDL_r[pcnt]);break;case PIC_C:SPI4W_WRITEDATA(gImage_WYJTEST_RED3[pcnt]);break;case PIC_R:SPI4W_WRITEDATA(0xFF);break;case PIC_VLINE:if(col>160)SPI4W_WRITEDATA(0xFF);elseSPI4W_WRITEDATA(0x00);break;case PIC_HLINE:if(row>9)SPI4W_WRITEDATA(0xff);elseSPI4W_WRITEDATA(0x00);break; case PIC_E:SPI4W_WRITEDATA(0x00);break;case PIC_WHITE:SPI4W_WRITEDATA(0x00);break; case PIC_BLACK:SPI4W_WRITEDATA(0x00);break; default:break;}pcnt++;}}SPI4W_WRITECOM(0x18);SPI4W_WRITEDATA(0x80); SPI4W_WRITECOM(0x22);SPI4W_WRITEDATA(0xF7); //Load LUT from MCU(0x32), Display updateSPI4W_WRITECOM(0x20);DELAY_mS(1);READBUSY();}
``
简单分析一下,首先设置了两个for循环,一个是屏幕的长,一个是屏幕的宽。两个for循环下来,刚好把屏幕的每个像素点都数了一遍。所以这个for循环里面就是打点,每执行一下,显示出一个像素点,执行了(widehigh)次.这里屏幕的高设为16,是因为一个数据(0x00)占八位,即八个像素点。
gImage_1_red[pcnt]这个数组里面放的是整个屏幕的显示数据,总共400个字节(25016),pcnt=0,从第0个字节开始放,执行一次循环,pcnt++,放入下一个,直到把整屏的数据全放进去。
显示效果:
这是图片,不是写的字
文字显示
文字显示跟图片显示原理一样的,只不过你放入的不是整屏的数据,而是一个一个的文字数据,
你可以简单粗暴的指定位置放入文字数据
Draw_char(200,224,0,2,0);//0 ,黑色;1,红色。其他 ,黑底白字
..
//省略了驱动,只写显示for(wide=0; wide<250; wide++) {for(high=0; high<16; high++)
{if(x_start<wide && wide<x_end && y_start<= high && high <= y_end)SPI4W_WRITEDATA (hz_bw[pcnt++]);//放入文字elseSPI4W_WRITEDATA (0XFF);}
也可以再优化一下,指定位置显示想要的文字
Draw_String(100,11,"蓝")void Draw_String(uint32_t x, uint32_t y, const unsigned char *chs){Display_init();SPI4W_WRITECOM(0X24);uint32_t i = 0;unsigned int high, wide;unsigned int pcnt=0;while (*chs != '\0') //非空字符{if(*chs >= 0xa0) //汉字{for(i=0;i < GB16_NUM();i++)if ((*chs == hz_index[i*2]) && (*(chs+1) == hz_index[i*2+1]))//if ((*chs == hz_index[i])){pcnt=(32)*i;//LCD_Draw(x,y,&hz[32*(i)],16,16); for(wide=0; wide<250; wide++) { for(high=0; high<16; high++) {if(x<wide && wide<x+16 && y<= high && high <= y+1)SPI4W_WRITEDATA(hz[pcnt++]);elseSPI4W_WRITEDATA (0xFF);}}
// pcnt++;x+=16;
}chs+=2;}else{for (i=0 ;i < ASCII_NUM();i++){if (*chs == zf_index[i]){pcnt=(16)*i;for(wide=0; wide<250; wide++) {for(high=0; high<16; high++) if(x<wide && wide<x+8 && y<= high && high <= y+1)SPI4W_WRITEDATA(zf[pcnt++]); elseSPI4W_WRITEDATA(0xFF);
//
}x += 8;break;}}chs++;} }}
显示效果:
下期说一下数据格式,取模方式,和数据的调整。
这篇关于#基于NRF52832的墨水屏移植与GUI设计(2)的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!