Nokia 5110可谓是相~ 当~ 经典了,你可以用它来打电话、砸核桃、挡子弹、锤钉子,居家防身,良心佳品~= ̄ω ̄=
它的屏幕因为某宝上只买八块八,八块八啊~ 物美价廉,受到广大青少年的追捧~
技术参数
- 分辨率: 84 * 48
- 通信协议: SPI
- 液晶模块: LPH7366
- 主控芯片: PCD8544
- 传送速率: 最高4Mbits/s
- 工作电压: 3.3v ~5.0v
- 工作电流: ≤ 200μA
电路连接
Nokia 5110的屏幕使用的是SPI协议,但使用我图片中的屏幕模块,除了需要连接SPI的4条信号线外,还需要另外连接一个RST(重置)和BL(背光)。
Nokia 5110屏幕模块有下列引脚:
- VCC,电源,输入3.3v ~5v
- GND,公共接地,提供参考低电平
- BL,屏幕背光,高电平时点亮,低电平时熄灭
- DIN,SPI的MISO脚,向
- DC,DATA/CMD,数据/指令选择,高电平时总线上传送数据,低电平时总线上传送控制指令
- CLK,SPI的时钟脚
- CE,SPI的片选脚,低电平时,单片机可对此设备读写,高电平时挂起此设备的通信
- RST,重置屏幕
上面的电路图太乱太难看,要理清的话,一半脑细胞都可以住进精神病院了。总之Nokia 5110的屏幕是SPI通信的,参考SPI的连接方法就对了。
指令集
-
空操作
操作位 Bit7 Bit6 Bit5 Bit4 Bit3 Bit2 Bit1 Bit0 DC 位值 0 0 0 0 0 0 0 0 0 用于延时的空操作指令,没有任何作用
-
写像素数据
操作位 Bit7 Bit6 Bit5 Bit4 Bit3 Bit2 Bit1 Bit0 DC 位值 D7 D6 D5 D4 D3 D2 D1 D0 1 填充像素数据块,直接把数据写入液晶屏的GRAM中
-
功能设置
操作位 Bit7 Bit6 Bit5 Bit4 Bit3 Bit2 Bit1 Bit0 DC 位值 0 0 1 0 0 EN VH IS 0 - EN为屏幕开启开关:1 = 开启屏幕, 0 = 关闭屏幕
- VH,寻址方式选择: 1 = 使用垂直寻址, 0 = 使用水平寻址
- IS,指令集选择:1 = 使用扩展指令集, 0 = 使用扩基本指令集
-
基本指令集
-
显示设置
操作位 Bit7 Bit6 Bit5 Bit4 Bit3 Bit2 Bit1 Bit0 DC 位值 0 0 0 0 1 D 0 E 0 - (D, E),显示方式枚举:(0, 0) = 显示空白, (0, 1) = 显示全黑,(1, 0) = 普通模式,(1, 1) = 翻色显示
-
游标设置:GRAM写入起点X坐标,这里的X是以列(COLUMN)为单位
操作位 Bit7 Bit6 Bit5 Bit4 Bit3 Bit2 Bit1 Bit0 DC 位值 0 1 D5 D4 D3 D2 D1 D0 0 -
游标设置:GRAM写入起点Y坐标,这里的Y是以页面(PAGE)为单位
操作位 Bit7 Bit6 Bit5 Bit4 Bit3 Bit2 Bit1 Bit0 DC 位值 0 1 0 0 0 D2 D1 D0 0
-
-
扩展指令集
-
温度系数
操作位 Bit7 Bit6 Bit5 Bit4 Bit3 Bit2 Bit1 Bit0 DC 位值 0 0 1 0 0 1 D1 D0 0 - (D1, D0),显示方式枚举:(0, 0) = 温度系数0, (0, 1) = 温度系数1,(1, 0) = 温度系数2,(1, 1) = 温度系数3
- 这是用来干嘛用的~(←_←)
-
偏置混合率
操作位 Bit7 Bit6 Bit5 Bit4 Bit3 Bit2 Bit1 Bit0 DC 位值 0 0 0 1 0 D2 D1 D0 0 - (D2, D1, D0), 偏置混合率:
- (0, 0, 0) = 1:100
- (0, 0, 1) = 1:80
- (0, 1, 0) = 1:65
- (0, 1, 1) = 1:48
- (1, 0, 0) = 1:40/1:34
- (1, 0, 1) = 1:24
- (1, 1, 0) = 1:18/1:16
- (1, 1, 1) = 1:10/1:9/1:8
- (D2, D1, D0), 偏置混合率:
-
操作电压
操作位 Bit7 Bit6 Bit5 Bit4 Bit3 Bit2 Bit1 Bit0 DC 位值 0 D6 D5 D4 D3 D2 D1 D0 0 - (D6, D5, D4, D3, D2, D1, D0)为操作电压的系数
- LCD偏置电压根据(D6, D5, D4, D3, D2, D1, D0)计算得值为
VLCD = 3.06 + 0.06 * VOP = 3.06 + 0.06 * (D6, D5, D4, D3, D2, D1, D0)2
-
初始化流程
- 拉低RST脚500ms,以重置屏幕
- 使用扩展指令
- 设置偏置混合率为4 = (1, 0, 0)2 = 1:40/1:34
- 设置操作电压VOP为40 = 5.46v,用以调节对比度
- 使用基本指令集
- 设置显示模式为普通模式
- 设置游标X到0
- 设置游标Y到0
- 写84 * 48 / 8个字节的0x00,以清屏
上面的初始化流程中给出了一些默认值,在实际使用的过程中,因为模块的不同,这些参数可能需要重新调整才能获得理想的显示效果
编码实现
我们使用Arduino的硬件SPI接口来和屏幕通信,所以我们需要使用Arduino内建的SPI库
初始化
#include <SPI.h>
#defineRST 15
#defineCE 10
#defineDC 12
#defineDIN 11
#defineCLK 13
#defineBL 16
#define INSTRUCTIONSET 0x20
#define INST_NORMAL 0x00
#define INST_EXTENDED 0x01
#define SETBIAS 0x10
#define SETVOP 0x80
#define DISPLAYCONTROL 0x08
#define DISP_BLANK 0x00
#define DISP_BLACK 0x01
#define DISP_NORMAL 0x04
#define DISP_INVERT 0x05
#define SET_CURSOR_X 0x08
#define SET_CURSOR_Y 0x04
const int bias = 4;
const int contrast = 40;
byte buffer[84 * 48 / 8];
void setup() {
// 初始化SPI
SPI.begin();
SPI.setClockDivider(SPI_CLOCK_DIV4); // 4MHz
SPI.setDataMode(SPI_MODE0);
SPI.setBitOrder(MSBFIRST);
// 初始化其他控制引脚
pinMode(DC, OUTPUT);
pinMode(RST, OUTPUT);
pinMode(CE, OUTPUT);
// 重置屏幕
digitalWrite(RST, LOW);
delay(500);
digitalWrite(RST, HIGH);
// 进入扩展指令集
command(INSTRUCTIONSET | EXTENDED);
// 设置偏置混合率
command(SETBIAS | bias);
// 设置偏置电压V~OP~
command(SETVOP | contrast);
// 进入基础指令
command(INSTRUCTIONSET | NORMAL);
// 设置正常显示模式
command(DISPLAYCONTROL | DISPLAYNORMAL);
// 设置游标(0, 0) = (column, page)
command(SET_CURSOR_X | 0);
command(SET_CURSOR_Y | 0);
// 写入清屏数据
memset(buffer, 0, 84 * 48 / 8);
writeGram(buffer, 84 * 48 / 8);
}
写指令
#include <SPI.h>
#define RST 15
#define CE 10
#define DC 12
#define DIN 11
#define CLK 13
#define BL 16
void command(byte cmd) {
digitalWrite(DC, LOW);
digitalWrite(CE, LOW);
SPI.transfer(cmd);
digitalWrite(CE, HIGH);
}
写数据
#include <SPI.h>
#define RST 15
#define CE 10
#define DC 12
#define DIN 11
#define CLK 13
#define BL 16
void data(byte data) {
digitalWrite(DC, HIGH);
digitalWrite(CE, LOW);
SPI.transfer(cmd);
digitalWrite(CE, HIGH);
}
void writeGram(byte* buffer, int size) {
digitalWrite(DC, HIGH);
digitalWrite(CE, LOW);
for (int i = 0; i < size; i++) {
SPI.transfer(buffer[i]);
}
digitalWrite(CE, HIGH);
}