嵌入式应用笔记
此系列作为产品过程中记录开源库移植和一些遇到的问题,包括有效资源、要点、函数、方法和一些使用心得。
移植
驱动
- 驱动应用(一)低功耗墨水屏硬件驱动与扫描原理
前言
- 电子墨水屏EPD,是一种革新信息显示的新方法和技术。像多数传统墨水一样,电子墨水和改变它颜色的线路是可以打印到许多表面的,从弯曲塑料、聚脂膜、纸到布。和传统纸差异是电子墨水在通电时改变颜色,并且可以像传统屏幕那样显示变化的图像。
- 其每个像素点是由单个电子墨水组成,电子墨水可以看成一个个胶囊的样子。每一个胶囊里面有液体电荷,其中正电荷染白色,负电荷染黑色。当我们在一侧给予正负电压,带有电荷的液体就会被分别吸引和排斥。这样,每一个像素点就可以显示白色或者黑色了。
- 本章用122*250像素的2.13inch墨水屏,通过实际的测试,表述其驱动中的扫描原理,该屏内部控制器采用IL3895,注:相同系列,越大的墨水屏指令相同,设置的位数却更多。
墨水屏应用
1 参考资料
2 硬件参数
参数 | 标记 | 条件 | 最小值 | 典型值 | 最大值 | 单位 |
---|---|---|---|---|---|---|
单接地 | Vss | - | - | 0 | - | V |
逻辑电源电压 | Vci | - | 2.2 | 3.0 | 3.7 | V |
逻辑高电平 | Voh | - | 0.9Vci | - | - | V |
逻辑低电平 | Vol | - | - | - | 0.1Vci | V |
典型功率 | Ptyp | Vci=3.0V | - | 9 | - | mW |
睡眠功率 | Psleep | - | - | 0.003 | - | mW |
睡眠电流 | Isleep | - | - | 20 | - | uA |
深度睡眠电流 | Idsleep | - | - | 1 | - | uA |
VCOM引脚输出 | VCOM | - | - | TBD | - | V |
3 硬件驱动
//施工
4常用SPI指令
每个指令有多个位进行设置,可以类比单片机寄存器配置
4.1通常初始化指令
4.1.1软件复位0x12
将命令参数重置为默认值,在深度睡眠模式(0x10)下不起作用,RAM不重置。
4.1.2驱动器输出控制0x01
读写权限 | D/C | D7 | D6 | D5 | D4 | D3 | D2 | D1 | D0 |
---|---|---|---|---|---|---|---|---|---|
W写 | 1 | A7 | A6 | A5 | A4 | A3 | A2 | A1 | A0 |
默认配置 | - | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 |
4.1.3边框设置0x3C
//施工
4.1.4 *扫描原理与像素点写入模式设置0x11
指令表:
读写权限 | DC | D7 | D6 | D5 | D4 | D3 | D2 | D1 | D0 |
---|---|---|---|---|---|---|---|---|---|
W写 | 1 | - | - | - | - | - | AM | ID1 | ID0 |
默认配置 | - | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 |
说明
其内部管理了一个地址计数器,自动地在某方向加减地址,通过AM设置方向;ID控制加减。
- ID[0]=“1”时,将数据写入RAM后,X地址计数器将自动增加1。
- ID[0]=“0”时,将数据写入RAM后,X地址计数器会自动减少1。
- ID[1]=“1”时,将数据写入RAM后,Y地址计数器将自动增加1。
- ID[1]=“0”时,将数据写入RAM后,Y地址计数器会自动减少1。
- AM=“0”时,地址计数器在X方向上更新。
- AM=“1”时,地址计数器在Y方向上更新。
- 当选择窗口地址后,数据将以ID[1:0]和AM位指定的方式写入由窗口地址指定的RAM区域。
4.2通常显示指令
4.2.1 扫描像素点地址设置0x44\0x45\0x4E\0x4F
指令表:
0x44 | DC | D7 | D6 | D5 | D4 | D3 | D2 | D1 | D0 |
---|---|---|---|---|---|---|---|---|---|
W写 | 1 | - | - | - | A4 | A3 | A2 | A1 | A0 |
W写 | 1 | - | - | - | B4 | B3 | B2 | B1 | B0 |
默认配置0x00 | - | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 |
默认配置0x12 | - | 0 | 0 | 0 | 1 | 0 | 0 | 1 | 0 |
0x45 | DC | D7 | D6 | D5 | D4 | D3 | D2 | D1 | D0 |
W写 | 1 | A7 | A6 | A5 | A4 | A3 | A2 | A1 | A0 |
W写 | 1 | B7 | B6 | B5 | B4 | B3 | B2 | B1 | B0 |
默认配置0x00 | - | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 |
默认配置0xF9 | - | 1 | 1 | 1 | 1 | 1 | 0 | 0 | 1 |
0x4E | DC | D7 | D6 | D5 | D4 | D3 | D2 | D1 | D0 |
W写 | 1 | - | - | - | A4 | A3 | A2 | A1 | A0 |
默认配置0x00 | - | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 |
0x4F | DC | D7 | D6 | D5 | D4 | D3 | D2 | D1 | D0 |
W写 | 1 | A7 | A6 | A5 | A4 | A3 | A2 | A1 | A0 |
默认配置0x00 | - | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 |
说明
0x44、0x45通过地址单元指定窗口地址
- 0x44:A[4:0]设置窗口的X方向起始地址
- 0x44:B[4:0]设置窗口的X方向终止地址
- 0x45:A[7:0]设置窗口的Y方向起始地址
- 0x45:B[7:0]设置窗口的Y方向起始地址
0x4E、0x4F设置RAM地址计数器的初值
- 0x4E:A[4:0]设置当前RAM地址X方向计数器的值
- 0x4F:A[7:0]设置当前RAM地址Y方向计数器的值
5 软件驱动
5.1 初始化函数
5.2 缓冲区显示函数设计
5.2.1 扫描显示原理与指令测试
这里非常重要,由于在使用过程中发现手册可能描述的不太清楚,于是测试程序写入同一个数组条件下,更改配置,附上效果图。
屏幕坐标系
该坐标系X轴总宽为0x0f,即16字节(128像素),其中边框占6像素。
一段测试代码
墨水屏像素点为一位,0为黑色,1为白色
//实验数组,先写入一段40像素黑线,空白8像素,黑线16像素,空8像素,黑线24像素,空16像素,黑线56像素,
uint8_t einkbmp[]={
0X00,0X00,0X00,0X00,0X00,0XFF,0X00,0X00,0XFF,0X00,0X00,0X00,0XFF,0XFF,0X00,0X00,
0X00,0X00,0X00,0X00,0X00,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,
0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,
0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,
/* 省略 */}
//初始化函数中调整配置
void EINK_INIT(void)
{
/* 省略初始化函数 */
EINK_WRITECOM(0x11); // 写入扫描方向控制指令
EINK_WRITEDATA(0x01); // 0b0000 0001写入配置,调整该设置
/* 省略初始化函数 */
}
//实验函数
void TEST_IMG()
{
uint16_t pcnt = 0;// 复位或保存提示字节序号
READBUSY();//判忙,显示屏BUSY线不占线才往下执行,否则报错
SetpointXY(0,0x0f,0xf9,0);//设置起始、终点坐标
EINK_WRITECOM(0x24);// 复位或保存提示字节序号
for(uint16_t col=0; col<250; col++) // 总共250 GATE列 // send 128x250bits ram 2D13
for(uint16_t row=0; row<16; row++,pcnt++) // 总共128 SOURCE行,每个像素1bit,即 128/8=16 字节
EINK_WRITEDATA(einkbmp[pcnt]);
//此处省略显示刷屏函数
}
实际效果程序写入显示效果
实践得真知
扫描设置\窗口坐标 | (0.0) | (0.F9) | (0F.0) | (0F.F9) |
AM+ID[0:1] =000,窗口设置为(0F,F9)到(0,0) | ![]() | ![]() | ![]() | ![]() |
AM+ID[0:1] =001,窗口设置为(0,F9)到(0F,0) | ![]() | ![]() | ![]() | ![]() |
AM+ID[0:1] =010 | ![]() | ![]() | ![]() | ![]() |
AM+ID[0:1] =011 | row 2, cell 2 | row 2, cell 1 | row 2, cell 2 | row 2, cell 1 |
AM+ID[0:1] =100 | row 2, cell 2 | row 2, cell 1 | row 2, cell 2 | row 2, cell 1 |
AM+ID[0:1] =101 | row 2, cell 2 | row 2, cell 1 | row 2, cell 2 | row 2, cell 1 |
AM+ID[0:1] =110 | row 2, cell 2 | row 2, cell 1 | row 2, cell 2 | row 2, cell 1 |
AM+ID[0:1] =111 | ![]() |
5.3 刷屏函数设计
//施工