|
许多项目都采用小型显示器作为用户交互的界面。 对于超低功耗的应用,这种方式通常是不行的,因为显示器需要功耗比较大。 过去我使用Kent的电子纸显示器:虽然这些电子纸显示器不需要任何电源来保持图像,但是改变显示内容很不方便,加上刷新速度很慢(大约需要1秒来刷新显示)。 所以我很长一段时间里一直在寻找低功耗和刷新快速的显示器,后来克里斯蒂安告诉我一款夏普的显示器:不仅非常低功率,并且刷新快速。
更妙的是:Adafruit有一个可用于这种显示器的分线板(https://www.adafruit.com/product/1393)。 分线板上的显示器是Sharp的LS013B4DN04,具有96×96单色像素分辨率。这种显示屏是介于电子纸和普通LCD之间。 “背光”的颜色是很好的银色。 这个显示器的像素显示像一个小镜子,看起来很酷:
显示器没有背光:在日光下可视性是很优秀的(虽然有些视角依赖);在黑暗的光线条件下,需要额外的照明。 像素之间的对比度非常好:
接线方式 Adafruit分线板带有一个电平转换器,因此可用于3.3V-5V。 我使用3.3V供电,只需要5根线连接到显示器: ■ VIN:3.3-5V ■ GND:接地 ■ CS:SPI片选,高电平有效 ■ CLK:SPI时钟(高达1 MHz) ■ DI:SPI MOSI,时钟空闲极性为低(CPOL = 0),并且数据在时钟前沿(CPHA = 0)上有效的,其中首先发送MSB位(最高有效位)。 可以不连接其他引脚。 显示屏是“只写”的,因此无法读回显示屏上的数据。 外部时钟和VCOM Sharp Memory显示器的一个特别之处是:它需要一个特殊的时钟信号来产生VCOM,一个交流信号,防止在显示面板内建立直流偏压。 根据所使用的显示器,需要提供0.5至60Hz的信号或时钟。 该信号可以由外部或由软件提供,取决于EXTMODE引脚:
在Adafruit分线板上,EXTMODE被拉低:时钟由软件提供。 使用软件将“VCOM”专用命令发送到显示器:
然后位V翻转。 - void SHM1_ToggleVCOM(void)
- {
- /* send toggle VCOM command */
- SCEpin3_SetVal();
- WriteData(SHM1_sharpmem_vcom);
- WriteData(0x00); /* 8bit trailer */
- SHM1_TOGGLE_VCOM;
- SCEpin3_ClrVal();
- }
复制代码在逻辑分析仪上,这看起来是这样的:
在下一次调用中,该位翻转:
如果没有发送其他显示命令,则只需要调用ToggleVCOM()函数,因为在写入显示时可以翻转VCOM位。
清除显示 有一个特殊的“clear”命令来清除显示:
以下代码执行了clear命令: - void SHM1_Clear(void)
- {
- /* send clear command */
- SCEpin3_SetVal();
- WriteData(SHM1_sharpmem_vcom | SHM1_BIT_CLEAR);
- WriteData(0x00);
- SHM1_TOGGLE_VCOM;
- SCEpin3_ClrVal();
- }
复制代码这里在每个命令之后VCOM位再次翻转。 下图展示了指令如何在接线上发送以及VCOM位的设置:
更新显示行 显示器的每一行可以用命令更新:发送行号,然后是字节数(96位是12个字节),后跟16个零字节:
- void SHM1_UpdateLine(uint8_t line, uint8_t *dataP)
- {
- int i;
-
- /* Send the write command */
- SCEpin3_SetVal();
- WriteData(SHM1_BIT_WRITECMD | SHM1_sharpmem_vcom);
- SHM1_TOGGLE_VCOM;
-
- /* Send the address for line */
- WriteData(SHM1_RevertBits(line+1)); /* line starts with 1 */
-
- /* Send data byte for selected line */
- for (i=0; i<(SHM1_HW_WIDTH/8); i++) {
- WriteData(*dataP);
- dataP++;
- }
- /* Send trailing 16 bits */
- WriteData(0x00);
- WriteData(0x00);
- SCEpin3_ClrVal();
- }
复制代码下面是写入行号1的示例:
多行 写多个行或所有行与写单行没有太大不同:
1. 发送写命令,然后是行号和数据,后跟8个零位结束 2. 继续发送带有数据的行号,后跟8个零位 3. 最后一行数据跟着16个零位。 - void SHM1_UpdateFull(void)
- {
- uint16_t numBytes = sizeof(SHM1_DisplayBuf);
- int i, currentline, oldline;
- uint8_t *data = (uint8_t*)SHM1_DisplayBuf;
-
- /* Send the write command */
- SCEpin3_SetVal();
- WriteData(SHM1_BIT_WRITECMD | SHM1_sharpmem_vcom);
- SHM1_TOGGLE_VCOM;
-
- /* Send the address for line 1 */
- oldline = currentline = 1;
- WriteData(SHM1_RevertBits(currentline));
-
- /* Send image buffer */
- for (i=0; i<numBytes; i++) {
- WriteData(*data);
- data++;
- currentline = ((i+1)/(SHM1_HW_WIDTH/8)) + 1;
- if(currentline != oldline) {
- WriteData(0x00); /* send 8 trailing bits to finish current line */
- if (currentline <= SHM1_HW_HEIGHT) {
- /* send new line number */
- WriteData(SHM1_RevertBits(currentline));
- }
- oldline = currentline;
- }
- }
- /* Send another trailing 8 bits for the last line */
- WriteData(0x00);
- SCEpin3_ClrVal();
- }
复制代码Processor Expert组件 当然,我已经创建了一个新的Processor Expert组件来使用该显示器。 只需几分钟的时间即可显示并运行:
使用该组件时,可以使用所有其他的图形和字体组件。 该组件支持bit banged和硬件SPI:
总结 夏普Memory显示器是一个非常酷的东西。 Adafruit分线板的价格为$39.95。 虽然我花了一段时间才能使得协议正确,但现在我的知识库中有了超低功耗的显示和驱动程序。 在GitHub上有一个示例项目,并且SharpMemDisplay组件可以在GitHub上获得。
参考链接 ■ Adafruit Sharp memory分线板模块:https://www.adafruit.com/products/1393 ■ Adafruit Git Repo:https://github.com/adafruit/Adafruit_SHARP_Memory_Display ■ Adafruit教程:https://learn.adafruit.com/adafr ... y-breakout/overview ■ Sharp应用笔记:http://www.sharpmemorylcd.com/re ... ry_lcd_app_note.pdf ■ 数据表:http://www.sharpmemorylcd.com/re ... pplication_info.pdf ■ 示例项目:https://github.com/ErichStyger/m ... nyK20/tinyK20_Sharp ■ McuOnEclipse库:https://github.com/ErichStyger/McuOnEclipseLibrary
|