代码
esp32_lcd9648.ino
#include "LCD9648.h"
#define LOGO_E835568_HEIGHT 48
#define LOGO_E835568_WIDTH 96
// array size is 360
const uint8_t logo_e835568[] = {
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0x87, 0xc3, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0x03, 0x83, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0x03, 0x81, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0x03, 0x81, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0x03, 0x81, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0x03, 0x81, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0x87, 0xc3, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xe1, 0xc7, 0xc7, 0x0f, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xc1, 0xff, 0xff, 0x07, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xc0, 0xff, 0xfe, 0x07, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xc0, 0xff, 0xfe, 0x07, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xc0, 0xf8, 0x3e, 0x07, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xc0, 0xf0, 0x1e, 0x07, 0xff, 0xff, 0xff, 0xff,
0x00, 0x1f, 0xff, 0xf1, 0xc1, 0xe0, 0x0f, 0x0f, 0xf0, 0x33, 0x9c, 0x01,
0x00, 0x0f, 0xff, 0xf1, 0xf3, 0xc0, 0x07, 0x9e, 0x03, 0x13, 0x9c, 0x01,
0x0f, 0x87, 0xff, 0xff, 0xff, 0xc4, 0x07, 0xfe, 0x0b, 0x33, 0xff, 0xf3,
0x1f, 0xc7, 0xff, 0xff, 0xff, 0x0e, 0x03, 0xfe, 0x00, 0x03, 0xfe, 0x67,
0x1f, 0xc7, 0x00, 0xf1, 0xfe, 0x0e, 0x00, 0xfe, 0x00, 0x03, 0xff, 0x0f,
0x1f, 0xc7, 0x00, 0x31, 0xfc, 0x7e, 0xc6, 0x7f, 0x02, 0x03, 0xff, 0x0f,
0x00, 0x0f, 0xfe, 0x31, 0xf8, 0xfe, 0xc6, 0x3f, 0x4a, 0x03, 0x1c, 0x21,
0x00, 0x0f, 0xff, 0x31, 0xf1, 0xfe, 0xce, 0x1e, 0xcc, 0x03, 0x9f, 0xff,
0x00, 0x07, 0xc0, 0x31, 0xf1, 0xce, 0xce, 0x1e, 0x00, 0x03, 0xdf, 0x9f,
0x1f, 0xc7, 0x00, 0x31, 0xe1, 0x8e, 0xce, 0x0e, 0x00, 0x03, 0xdc, 0x01,
0x1f, 0xc2, 0x3e, 0x31, 0xe1, 0xce, 0xce, 0x0e, 0x48, 0x03, 0xdc, 0x01,
0x1f, 0xc2, 0x3f, 0x31, 0xe1, 0xfe, 0xfe, 0x1e, 0x00, 0x03, 0xdf, 0x9f,
0x00, 0x06, 0x3e, 0x31, 0xf0, 0xfe, 0xfe, 0x1e, 0x01, 0x9b, 0xdf, 0x0f,
0x00, 0x07, 0x00, 0x31, 0xf0, 0x00, 0x00, 0x1e, 0x00, 0x03, 0xc8, 0x01,
0x00, 0x1f, 0x80, 0x31, 0xf8, 0x00, 0x00, 0x3e, 0x02, 0x23, 0xcf, 0x9f,
0xff, 0xff, 0xff, 0xff, 0xfe, 0x0f, 0xe0, 0xff, 0xff, 0xff, 0xff, 0xff
};
LCD9648 lcd = LCD9648(13, 15, 14, 2, 12);
void setup() {
Serial.begin(115200);
lcd.init();
}
void loop() {
lcd.fillRect(0, 0, 96, 48, 0);
lcd.setCursor(0, 8);
lcd.setTextColor(0);
lcd.drawBitmap(0, 10, logo_e835568, 96, 30, 1);
lcd.println("hello world");
lcd.println("white");
lcd.display();
delay(1000);
lcd.fillScreen(1);
lcd.setCursor(0, 8);
lcd.setTextColor(1);
lcd.println("hello world");
lcd.println("black");
lcd.display();
delay(1000);
}
LCD9648.h
namespace lcd9648{
#define min(a, b) (a < b ? a : b)
#define max(a, b) (a > b ? a : b)
String font_bitmap_str = " !\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~";
const uint8_t font_bitmap[][8] = {
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, // " "
{ 0x00, 0x00, 0x00, 0x2f, 0x00, 0x00, 0x00, 0x00 }, // "!"
{ 0x00, 0x00, 0x07, 0x00, 0x07, 0x00, 0x00, 0x00 }, // """
{ 0x00, 0x14, 0x7f, 0x14, 0x7f, 0x14, 0x00, 0x00 }, // "#"
{ 0x00, 0x24, 0x2a, 0x7f, 0x2a, 0x12, 0x00, 0x00 }, // "$"
{ 0x00, 0x23, 0x13, 0x08, 0x64, 0x62, 0x00, 0x00 }, // "%"
{ 0x00, 0x36, 0x49, 0x55, 0x22, 0x50, 0x00, 0x00 }, // "&"
{ 0x00, 0x00, 0x05, 0x03, 0x00, 0x00, 0x00, 0x00 }, // "'"
{ 0x00, 0x00, 0x1c, 0x22, 0x41, 0x00, 0x00, 0x00 }, // "("
{ 0x00, 0x00, 0x41, 0x22, 0x1c, 0x00, 0x00, 0x00 }, // ")"
{ 0x00, 0x14, 0x08, 0x3E, 0x08, 0x14, 0x00, 0x00 }, // "*"
{ 0x00, 0x08, 0x08, 0x3E, 0x08, 0x08, 0x00, 0x00 }, // "+"
{ 0x00, 0x00, 0x50, 0x30, 0x00, 0x00, 0x00, 0x00 }, // ","
{ 0x00, 0x08, 0x08, 0x08, 0x08, 0x08, 0x00, 0x00 }, // "-"
{ 0x00, 0x00, 0x60, 0x60, 0x00, 0x00, 0x00, 0x00 }, // "."
{ 0x00, 0x20, 0x10, 0x08, 0x04, 0x02, 0x00, 0x00 }, // "/"
{ 0x00, 0x3E, 0x51, 0x49, 0x45, 0x3E, 0x00, 0x00 }, // "0"
{ 0x00, 0x00, 0x42, 0x7F, 0x40, 0x00, 0x00, 0x00 }, // "1"
{ 0x00, 0x42, 0x61, 0x51, 0x49, 0x46, 0x00, 0x00 }, // "2"
{ 0x00, 0x21, 0x41, 0x45, 0x4B, 0x31, 0x00, 0x00 }, // "3"
{ 0x00, 0x18, 0x14, 0x12, 0x7F, 0x10, 0x00, 0x00 }, // "4"
{ 0x00, 0x27, 0x45, 0x45, 0x45, 0x39, 0x00, 0x00 }, // "5"
{ 0x00, 0x3C, 0x4A, 0x49, 0x49, 0x30, 0x00, 0x00 }, // "6"
{ 0x00, 0x01, 0x71, 0x09, 0x05, 0x03, 0x00, 0x00 }, // "7"
{ 0x00, 0x36, 0x49, 0x49, 0x49, 0x36, 0x00, 0x00 }, // "8"
{ 0x00, 0x06, 0x49, 0x49, 0x29, 0x1E, 0x00, 0x00 }, // "9"
{ 0x00, 0x00, 0x36, 0x36, 0x00, 0x00, 0x00, 0x00 }, // ":"
{ 0x00, 0x00, 0x56, 0x36, 0x00, 0x00, 0x00, 0x00 }, // ";"
{ 0x00, 0x08, 0x14, 0x22, 0x41, 0x00, 0x00, 0x00 }, // "<"
{ 0x00, 0x14, 0x14, 0x14, 0x14, 0x14, 0x00, 0x00 }, // "="
{ 0x00, 0x00, 0x41, 0x22, 0x14, 0x08, 0x00, 0x00 }, // ">"
{ 0x00, 0x02, 0x01, 0x51, 0x09, 0x06, 0x00, 0x00 }, // "?"
{ 0x00, 0x32, 0x49, 0x79, 0x41, 0x3E, 0x00, 0x00 }, // "@"
{ 0x00, 0x7E, 0x11, 0x11, 0x11, 0x7E, 0x00, 0x00 }, // "A"
{ 0x00, 0x7F, 0x49, 0x49, 0x49, 0x36, 0x00, 0x00 }, // "B"
{ 0x00, 0x3E, 0x41, 0x41, 0x41, 0x22, 0x00, 0x00 }, // "C"
{ 0x00, 0x7F, 0x41, 0x41, 0x22, 0x1C, 0x00, 0x00 }, // "D"
{ 0x00, 0x7F, 0x49, 0x49, 0x49, 0x41, 0x00, 0x00 }, // "E"
{ 0x00, 0x7F, 0x09, 0x09, 0x09, 0x01, 0x00, 0x00 }, // "F"
{ 0x00, 0x3E, 0x41, 0x49, 0x49, 0x7A, 0x00, 0x00 }, // "G"
{ 0x00, 0x7F, 0x08, 0x08, 0x08, 0x7F, 0x00, 0x00 }, // "H"
{ 0x00, 0x00, 0x7f, 0x09, 0x09, 0x06, 0x00, 0x00 }, // "I"
{ 0x00, 0x00, 0x3e, 0x41, 0x41, 0x22, 0x00, 0x00 }, // "J"
{ 0x00, 0x00, 0x7f, 0x08, 0x14, 0x63, 0x00, 0x00 }, // "K"
{ 0x00, 0x00, 0x7f, 0x41, 0x41, 0x40, 0x00, 0x00 }, // "L"
{ 0x00, 0x00, 0x7f, 0x02, 0x0c, 0x02, 0x7f, 0x00 }, // "M"
{ 0x00, 0x00, 0x7f, 0x04, 0x08, 0x7f, 0x00, 0x00 }, // "N"
{ 0x00, 0x00, 0x3e, 0x41, 0x41, 0x3e, 0x00, 0x00 }, // "O"
{ 0x00, 0x00, 0x7f, 0x09, 0x09, 0x06, 0x00, 0x00 }, // "P"
{ 0x00, 0x00, 0x3e, 0x41, 0x41, 0xbe, 0x00, 0x00 }, // "Q"
{ 0x00, 0x00, 0x7f, 0x09, 0x19, 0x66, 0x00, 0x00 }, // "R"
{ 0x00, 0x00, 0x26, 0x49, 0x49, 0x32, 0x00, 0x00 }, // "S"
{ 0x00, 0x00, 0x01, 0x01, 0x7f, 0x01, 0x01, 0x00 }, // "T"
{ 0x00, 0x00, 0x3f, 0x40, 0x40, 0x3f, 0x00, 0x00 }, // "U"
{ 0x00, 0x00, 0x1f, 0x20, 0x40, 0x20, 0x1f, 0x00 }, // "V"
{ 0x7f, 0x20, 0x10, 0x08, 0x10, 0x20, 0x7f, 0x00 }, // "W"
{ 0x00, 0x00, 0x77, 0x08, 0x08, 0x77, 0x00, 0x00 }, // "X"
{ 0x00, 0x00, 0x0f, 0x10, 0x10, 0x7f, 0x00, 0x00 }, // "Y"
{ 0x00, 0x00, 0x71, 0x49, 0x45, 0x43, 0x00, 0x00 }, // "Z"
{ 0x00, 0x00, 0x3f, 0x21, 0x00, 0x00, 0x00, 0x00 }, // "["
{ 0x00, 0x00, 0x02, 0x04, 0x08, 0x10, 0x20, 0x00 }, // "\"
{ 0x00, 0x00, 0x21, 0x3f, 0x00, 0x00, 0x00, 0x00 }, // "]"
{ 0x00, 0x00, 0x04, 0x02, 0x01, 0x02, 0x04, 0x00 }, // "^"
{ 0x00, 0x00, 0x40, 0x40, 0x40, 0x40, 0x40, 0x00 }, // "_"
{ 0x00, 0x00, 0x01, 0x02, 0x00, 0x00, 0x00, 0x00 }, // "`"
{ 0x00, 0x00, 0x20, 0x54, 0x54, 0x78, 0x00, 0x00 }, // "a"
{ 0x00, 0x00, 0x7f, 0x48, 0x44, 0x38, 0x00, 0x00 }, // "b"
{ 0x00, 0x00, 0x38, 0x44, 0x44, 0x28, 0x00, 0x00 }, // "c"
{ 0x00, 0x00, 0x38, 0x44, 0x48, 0x7f, 0x00, 0x00 }, // "d"
{ 0x00, 0x00, 0x38, 0x54, 0x54, 0x18, 0x00, 0x00 }, // "e"
{ 0x00, 0x00, 0x08, 0x7e, 0x09, 0x02, 0x00, 0x00 }, // "f"
{ 0x00, 0x00, 0x0c, 0x52, 0x52, 0x3e, 0x00, 0x00 }, // "g"
{ 0x00, 0x00, 0x7f, 0x08, 0x04, 0x78, 0x00, 0x00 }, // "h"
{ 0x00, 0x00, 0x44, 0x7d, 0x40, 0x00, 0x00, 0x00 }, // "i"
{ 0x00, 0x00, 0x20, 0x40, 0x44, 0x3d, 0x00, 0x00 }, // "j"
{ 0x00, 0x00, 0x7f, 0x10, 0x28, 0x44, 0x00, 0x00 }, // "k"
{ 0x00, 0x00, 0x41, 0x7f, 0x40, 0x00, 0x00, 0x00 }, // "l"
{ 0x7c, 0x04, 0x18, 0x04, 0x7c, 0x04, 0x78, 0x00 }, // "m"
{ 0x00, 0x00, 0x7c, 0x08, 0x04, 0x78, 0x00, 0x00 }, // "n"
{ 0x00, 0x00, 0x38, 0x44, 0x44, 0x38, 0x00, 0x00 }, // "o"
{ 0x00, 0x00, 0x7c, 0x14, 0x14, 0x08, 0x00, 0x00 }, // "p"
{ 0x00, 0x00, 0x08, 0x14, 0x14, 0x7c, 0x00, 0x00 }, // "q"
{ 0x00, 0x00, 0x7c, 0x08, 0x04, 0x04, 0x00, 0x00 }, // "r"
{ 0x00, 0x00, 0x38, 0x54, 0x54, 0x18, 0x00, 0x00 }, // "s"
{ 0x00, 0x00, 0x04, 0x3f, 0x44, 0x24, 0x00, 0x00 }, // "t"
{ 0x00, 0x00, 0x3c, 0x40, 0x20, 0x7c, 0x00, 0x00 }, // "u"
{ 0x00, 0x00, 0x1c, 0x20, 0x40, 0x20, 0x1c, 0x00 }, // "v"
{ 0x3c, 0x20, 0x10, 0x08, 0x10, 0x20, 0x3c, 0x00 }, // "w"
{ 0x00, 0x00, 0x6c, 0x10, 0x10, 0x6c, 0x00, 0x00 }, // "x"
{ 0x00, 0x00, 0x0c, 0x50, 0x50, 0x3c, 0x00, 0x00 }, // "y"
{ 0x00, 0x00, 0x64, 0x54, 0x4c, 0x44, 0x00, 0x00 }, // "z"
{ 0x00, 0x00, 0x08, 0x36, 0x41, 0x00, 0x00, 0x00 }, // "{"
{ 0x00, 0x00, 0x00, 0x7f, 0x00, 0x00, 0x00, 0x00 }, // "|"
{ 0x00, 0x00, 0x41, 0x36, 0x08, 0x00, 0x00, 0x00 }, // "}"
{ 0x00, 0x00, 0x08, 0x04, 0x0c, 0x08, 0x10, 0x00 }, // "~"
};
}
class LCD9648 {
private:
uint8_t SCL;
uint8_t SDA;
uint8_t RS;
uint8_t CS;
uint8_t RST;
bool* map;
int textx, texty;
bool textcolor;
void SCLp(int v) {
digitalWrite(SCL, v);
}
void SDAp(int v) {
digitalWrite(SDA, v);
}
void RSp(int v) {
digitalWrite(RS, v);
}
void CSp(int v) {
digitalWrite(CS, v);
}
void RSTp(int v) {
digitalWrite(RST, v);
}
void PIN_init() {
pinMode(SCL, OUTPUT);
pinMode(SDA, OUTPUT);
pinMode(RS, OUTPUT);
pinMode(CS, OUTPUT);
pinMode(RST, OUTPUT);
}
bool getBit(uint8_t n, uint8_t i) {
uint8_t mask = 1 << (i - 1);
return (n >> (i - 1)) & 1;
}
bool getPixel(const uint8_t* bitmap, int w, int h, int x, int y) {
int id = y * w + x;
return getBit(bitmap[id / 8], 8 - id % 8);
}
void SendDataSPI(unsigned char dat) {
unsigned char i;
for (i = 0; i < 8; i++) {
if ((dat & 0x80) != 0)
SDAp(1);
else
SDAp(0);
dat <<= 1;
SCLp(0);
SCLp(1);
}
}
void WriteComm(unsigned char i) {
CSp(0);
RSp(0);
SendDataSPI(i);
CSp(1);
}
void WriteData(unsigned char i) {
CSp(0);
RSp(1);
SendDataSPI(i);
CSp(1);
}
void LCD_Init() {
RSTp(1);
delay(10);
RSTp(0);
delay(10);
RSTp(1);
delay(10);
WriteComm(0xe2); //软件复位
WriteComm(0xc8); //0xC8普通方向选择选择反向,0xC0为正常方向
WriteComm(0xa0); //0xA0段方向选择正常方向(0xA1为反方向
WriteComm(0x2f);
WriteComm(0x26);
WriteComm(0x81); //背景光对比度
WriteComm(0x10); //0x10设置列高地址
WriteComm(0xaf); //开启显示
WriteComm(0x40);
for (uint8_t i = 0; i < 9; i++) //一共九页
{
WriteComm(0xb0 + i); //页地址
WriteComm(0x10); //列地址
WriteComm(0x00); //列地址
for (uint8_t j = 0; j < 96; j++) {
WriteData(0x00);
}
}
}
void drawChar(int x_, int y_, const char c) {
int id = lcd9648::font_bitmap_str.indexOf(c);
for (uint16_t y = 0; y < 8; y++) {
for (uint16_t x = 0; x < 8; x++) {
drawPixel(x_ + y, 8 - x + y_, getPixel(lcd9648::font_bitmap[id], 8, 8, x, y) != textcolor);
}
}
}
public:
LCD9648(uint8_t _SCL, uint8_t _SDA, uint8_t _RS, uint8_t _CS, uint8_t _RST) {
SCL = _SCL;
SDA = _SDA;
RS = _RS;
CS = _CS;
RST = _RST;
}
void drawPixel(int16_t x, int16_t y, bool color) {
if (x < 0 || x >= 96 || y < 0 || y >= 48) {
// 坐标越界,不进行操作
return;
}
int id = y * 96 + x;
map[id] = color;
}
bool getPixel(int16_t x, int16_t y) {
if (x < 0 || x >= 96 || y < 0 || y >= 48) {
// 坐标越界,不进行操作
return 0;
}
int id = y * 96 + x;
if (map[id] != 0) {
}
return map[id];
}
void drawBitmap(int16_t x_, int16_t y_, const uint8_t* bitmap, int16_t w, int16_t h, uint8_t color) {
for (uint16_t y = 0; y < h; y++) {
for (uint16_t x = 0; x < w; x++) {
drawPixel(x_ + x, y_ + y, getPixel(bitmap, w, h, x, y) != color);
}
}
}
void setCursor(int x, int y) {
textx = x;
texty = y;
if (textx + 8 >= 96) {
textx = 0;
texty += 8;
}
}
void setTextColor(bool color) {
textcolor = color;
}
void print(String str) {
for (int i = 0; i < str.length(); i++) {
if (str[i] == '\n') setCursor(0, texty + 8);
else if (str[i] == '\0') {
} else if (lcd9648::font_bitmap_str.indexOf(str[i]) == -1) drawChar(textx, texty, '?');
else {
drawChar(textx, texty, str[i]);
setCursor(textx + 8, texty);
}
}
}
void println(String str) {
print(str + "\n");
}
void display() {
for (uint8_t i = 0; i < (48 / 8); i++) {
WriteComm(0x40); //set scroll line 设置滚动一行
WriteComm(0xb0 + i); //set page address 设置页地址
WriteComm(0x10); //column msb 列最高位
WriteComm(0x00); //column lsb 列最低位
for (uint8_t k = 0; k < 96; k++) {
uint8_t data = 0;
uint8_t wei = 1;
for (uint8_t m = 0; m < 8; m++) {
data += wei * getPixel(k, m + i * 8);
wei *= 2;
}
WriteData(data);
//delay(1);
}
}
}
void drawFastHLine(int32_t x_, int32_t y_, int32_t w, bool color) {
for (uint16_t x = 0; x < w; x++) {
drawPixel(x + x_, y_, color);
}
}
void drawFastVLine(int32_t x_, int32_t y_, int32_t h, bool color) {
for (uint16_t y = 0; y < h; y++) {
drawPixel(x_, y + y_, color);
}
}
void fillRect(int16_t x_, int16_t y_, int16_t w, int16_t h, bool color) {
for (uint16_t y = 0; y < h; y++) {
for (uint16_t x = 0; x < w; x++) {
drawPixel(x + x_, y + y_, color);
}
}
}
void fillScreen(bool color){
fillRect(0, 0, 96, 48, color);
}
void drawRect(int32_t x, int32_t y, int32_t w, int32_t h, uint32_t color) {
drawFastHLine(x, y, w, color);
drawFastHLine(x, y + h - 1, w, color);
drawFastVLine(x, y, h, color);
drawFastVLine(x + w - 1, y, h, color);
}
void init() {
map = new bool[96 * 48];
PIN_init();
LCD_Init();
fillRect(0, 0, 96, 48, 0);
display();
}
void begin() {
init();
}
};
效果
参考
LCD9648驱动https://blog.csdn.net/CSDN17884809754/article/details/122820849