电子墨水屏又被称为电子纸显示技术。电子纸显示技术(简称EPD),由美国麻省理工大学教授约瑟夫.雅各布森及其研发团队,经历30余年研发成功。
墨水屏的原理很简单,电子墨水屏是由许多电子墨水组成,电子墨水可以看成一个个胶囊的样子。每一个胶囊里面有液体电荷,其中正电荷染白色,负电荷染黑色。当我们在一侧给予正负电压,带有电荷的液体就会被分别吸引和排斥。这样,每一个像素点就可以显示白色或者黑色了。
因为电子墨水的刷新是不连续的,每一次刷新完成就可以保持现在的图形,即使拔掉电池也依旧保存。可能有人会问,为何电池没电,墨水屏也会一直显示最后的画面,那是因为电子墨水具有双稳态磁滞效应,所以即便电池没电,小球也不会回复原状或者进入随机的混沌状态,而是保持最后画面的状态,此时耗电量为0。
本次使用墨水屏型号为QYEG0420BNS19A,外形尺寸为91.0 x77.0x 1.2mm,显示区域尺寸为84.8 x 63.6mm,分辨率为400 x 300,支持显示黑色和白色两种颜色,支持全屏刷新和局部刷新两种模式,刷新功耗为12.6mW。
这里给开发者介绍一下全刷和局部刷的区别
1)全刷:电子纸刷新需要画面闪烁多次后,最终显示所需要的画面,其中闪烁的目的是清除显示残影,以达到最佳的显示效果。
2)局刷:电子纸刷新无画面闪烁,局刷需要用户在使用的时候,刷新几次后,进行一次全刷操作,以清除显示残影。
另外,墨水屏正常使用的温度范围:0~50℃ ,湿度范围:35%~65%RH,要避免阳光长时间直射显示屏表面。
它有如下特性
● 内置驱动器IC,无需另配驱动器,仅需少量外围器件,即可通过MCU控制显示,节省资源。
● 超宽视角 将近180°
● 超低功耗(断电可以继续保持显示内容)
● 纯反射模式
● 防眩硬涂层前表面
● 低电流深度睡眠模式
● 采用COG封装, IC厚度300um
● 使用寿命(无故障刷新次数):100万次以上
开发者可以参考下面的电路原理图
其中主要引脚功能如下
Name | Description |
---|---|
GDR | N勾道场效应管的栅极驱动控制脚 |
RESE | 控制回路的电流检测输入脚 |
VSH2 | 正源极驱动电压 |
TSCL | I2C数字温度传感器的时钟信号接口 |
TSDA | I2C数字温度传感器的数据信号接口 |
BS1 | 总线接口选择引脚 |
BUSY | 繁忙状态输出引脚 |
RES# | 复位信号输入脚, 低电平有效 |
D/C# | 数据/命令控制引脚 |
CS# | 芯片片选引脚 |
SCL | SPI接口的时钟引脚 |
SDA | SPI接口的数据引脚 |
VDDIO | 逻辑接口的电源引脚, 应与VCI脚连接 |
VCI | 芯片电源引脚 |
VSS | 参考地 |
VDD | 核心逻辑电源引脚 |
VPP | 测试脚 , 保持开路 |
VSH1 | 正源极驱动电压 |
VGH | 正门极驱动电压和VSH1的电源引脚 |
VSL | 负源极驱动电压 |
VGL | 负门极驱动电压,VCOM和VSL的电源引脚 |
VCOM | VCOM驱动电压 |
翻阅数据手册如下,可知源极驱动电压VSH引脚和门极驱动电压VGH引脚电压典型值都远大于芯片电源引脚,因此对该引脚还需要进行一个升压的处理。
如原理图所示,3.3V输入源,电感L1,MOS管Q1,电容C1,二极管D3,电阻R2构成了一个最基本的boost升压电路,MOS管Q1的导通或截止状态,由E_GDR控制。
当MOS管Q1导通时,输入电压经过电感L1后直接通过限流电阻R2返回到GND,这导致通过电感L1的电流线性的增大,此时输出滤波电容C1向负载放电。
当MOS管Q1截止时,由于电感L1的电流不能在瞬间发生突变,因此在电感L1上产生反向电动势Vs以维持通过电流不变。此时二极管D3导通,3.3V和Vs两电压串联后,以超过3.3V大小的电压向负载供电,并对输出滤波电容C1充电,如此循环,由此实现对E_PREVGH引脚的升压操作。
同样的,对于E_PREVGL引脚,
当MOS管Q1截止时,电容C2充电,二极管D1导通,D2截止,电流经过D1流向GND,理想情况下电容C2两端的电压差为3.3V+Vs。
当MOS管Q1导通时,Q1的漏极接近0V,由于电容C2电压不能突变,可认为二极管D2的K极电势为-(3.3V+Vs),电容C2放电,二极管D1截止,D2导通,电流经过D2流向C2,由此实现对E_PREVGL引脚负电压“升压”操作。
介绍完墨水屏的驱动电路,再和开发者们介绍一下墨水屏的使用方法。
墨水屏的操作流程整体也是比较简单的,大致流程如下。
墨水屏采用SPI通讯,这部分程序大家自行完成,小编主要给大家介绍一下应用端的程序。
首先是初始化函数
初始化过程中涉及全屏刷新和局部刷新两种
全屏刷新:整个页面全部刷新一次,整个屏幕要闪几次。 优势是没有残影,缺点是要多刷几下屏。
局部刷新:每一次刷新显示内容时,不会整个屏幕都刷新,仅刷新那些有画面和字的地方。优势是屏幕不会闪烁,但会有残影。(残影问题多刷几次白屏就能清除掉或者执行一次全刷也可以清掉)
在实现墨水屏的全局刷新与局部刷新功能时, 从局刷转到全刷时休眠后一定要先进入初始化再刷新。
// refresh_mode = Full 全屏刷新
// refresh_mode = Partial 局部刷新
void EPD_HW_Init(const unsigned char refresh_mode)
{
EPD_W21_Init(); //hard reset
Epaper_READBUSY();
Epaper_Write_Command(0x12); // soft reset
Epaper_READBUSY();
Epaper_Write_Command(0x01); //Driver output control
Epaper_Write_Data(0x2B);
Epaper_Write_Data(0x01);
Epaper_Write_Data(0x00);
Epaper_Write_Command(0x11); //data entry mode
Epaper_Write_Data(0x03); //Y increment, X increment
Epaper_Write_Command(0x44); //set Ram-X address start/end position
Epaper_Write_Data(0x00); //0x00-->0
Epaper_Write_Data(0x31); //0x31-->(49+1)*8=400
Epaper_Write_Command(0x45); //set Ram-Y address start/end position
Epaper_Write_Data(0x00);
Epaper_Write_Data(0x00);
Epaper_Write_Data(0x2B); //0x012B-->(299+1)=300
Epaper_Write_Data(0x01);
Epaper_Write_Command(0x3C); //BorderWavefrom
Epaper_Write_Data(0x01);
Epaper_Write_Command(0x18); //Temperature Sensor Selection
Epaper_Write_Data(0x80); //Internal temperature sensor
Epaper_Write_Command(0x22);
if(refresh_mode==Full)
Epaper_Write_Data(0xB1);//调用全刷LUT
if(refresh_mode==Partial)
Epaper_Write_Data(0xB9);//调用局刷LUT
Epaper_Write_Command(0x20);
Epaper_READBUSY();
Epaper_Write_Command(0x4E); // set RAM x address count
Epaper_Write_Data(0x00);
Epaper_Write_Command(0x4F); // set RAM y address count
Epaper_Write_Data(0x00);
Epaper_Write_Data(0x00);
Epaper_READBUSY();
}
EPD_W21_Init的功能就是对墨水屏的复位引脚拉低再拉高处理
可以参考如下
void EPD_W21_Init(void)
{
EPD_W21_RST_0;
driver_delay_xms(100);
EPD_W21_RST_1; //hard reset
driver_delay_xms(100);
}
程序中的Epaper_READBUSY函数可以如下定义
uint8_t Epaper_READBUSY(void)
{
uint8_t ret=1;
uint16_t timeout=0xFFFF;
LED2_SET;
while(isEPD_W21_BUSY)
{
timeout--;
if( 0 == timeout )
{
ret = 0;
break;
}
}
LED2_RESET;
return ret;
}
接下来就是显示的例程,如下
void EPD_Dis_Part(unsigned int xstart,unsigned int ystart,const unsigned char * datas,unsigned int PART_LINE,unsigned int PART_COLUMN,unsigned char mode)
{
unsigned int i;
int xend,ystart_H,ystart_L,yend,yend_H,yend_L;
xstart=xstart/8;//转换为字节
xend=xstart+PART_LINE/8-1;
ystart_H=ystart/256;
ystart_L=ystart%256;
yend=ystart+PART_COLUMN-1;
yend_H=yend/256;
yend_L=yend%256;
Epaper_Write_Command(0x44); // set RAM x address start/end
Epaper_Write_Data(xstart); // RAM x address start;
Epaper_Write_Data(xend); // RAM x address end
Epaper_Write_Command(0x45); // set RAM y address start/end
Epaper_Write_Data(ystart_L); // RAM y address start Low
Epaper_Write_Data(ystart_H); // RAM y address start High
Epaper_Write_Data(yend_L); // RAM y address end Low
Epaper_Write_Data(yend_H); // RAM y address end High
Epaper_Write_Command(0x4E); // set RAM x address count
Epaper_Write_Data(xstart);
Epaper_Write_Command(0x4F); // set RAM y address count
Epaper_Write_Data(ystart_L);
Epaper_Write_Data(ystart_H);
Epaper_Write_Command(0x24); //Write Black and White image to RAM
for(i=0;i<PART_COLUMN*PART_LINE/8;i++)
{
if (mode==POS)
{
Epaper_Write_Data(*datas);
datas++;
}
if (mode==NEG)
{
Epaper_Write_Data(~*datas);
datas++;
}
if (mode==OFF)
{
Epaper_Write_Data(0xFF);
}
}
}
其中
- xstart,ystart是起始坐标。
- *datas是传入的显示数组数据。
- PART_LINE可以认为是显示区域的长度,必须是8的整数倍(一个字节8位)
- PART_COLUMN可以认为是显示区域的宽度
- mode是模式,mode位POS , 正显;mode为NEG , 负显;mode为OFF , 清除;
数据写入之后,就是更新显示墨水屏
void EPD_Part_Update(void)
{
Epaper_Write_Command(0x22);
Epaper_Write_Data(0xCF);
Epaper_Write_Command(0x20);
Epaper_READBUSY();
}
这样就完成显示了,如果想降低功耗,可以再执行睡眠的函数
void EPD_DeepSleep(void)
{
Epaper_Write_Command(0x10); //enter deep sleep
Epaper_Write_Data(0x01);
driver_delay_xms(100);
}
整体流程可以如下
void EPD(void)
{
EPD_HW_Init(Full);
EPD_Dis_Part(0,0,gImage_num,8,8,NEG);
EPD_Part_Update();
EPD_DeepSleep();
}
另外再和开发者强调以下几点:
- 墨水屏刷新频率建议开发刷新时间间隔至少180秒(支持局刷功能的产品除外)。
- 墨水屏若有在低功耗场景中使用需求,如果显示画面不经常刷新,建议开发者将墨水屏设置为睡眠模式或者将墨水屏驱动供电部分通过模拟开关断开,这样操作既可以降低功耗,同时也可以延长墨水屏的使用寿命。
- 使用场所要求:墨水屏显示屏建议在室内使用,若在户外使用,需要让墨水屏避免长时间阳光直射,同时做好紫外线防护措施。开发者在设计产品的时候,要首先考虑使用环境是否满足墨水屏正常工作的温湿度要求。
有疑问,大家底下留言评论哦