spi驱动,用stm32、esp32试了
好看是好看,就是缺点也多,下面抄几个产品的说明:
刷新一次需要二十几秒。
理想情况下,正常使用,可以刷新1000000次(100万次)。这还是足够的
建议客户设置电子墨水屏的刷新间隔至少为180秒=3分钟(支持局刷功能的产品除外)。
三色电子墨水屏在使用的过程中,建议客户至少每24小时更新一次显示画面,如果屏幕长时间保持同一个画面,会出现烧屏情况难以修复。我问了客服,七色也一样
Displayer.h
#ifndef _MY_DISPLAYER_H_
#define _MY_DISPLAYER_H_
#include <Arduino.h>
#include <lvgl.h>
#define WIDTH (600)
#define HEIGHT (448)
#define CANVAS_WIDTH (WIDTH>>1)
#define CANVAS_HEIGHT (HEIGHT)
#define CANVAS_SIZE (CANVAS_WIDTH*CANVAS_HEIGHT)
//微秒to秒的转换系数ULL :unsiged long long 64bit
#define S_TO_uS_FACTOR 1000000ULL
#define BLACK lv_color_hex(0x0<<3)
#define WHITE lv_color_hex(0x1<<3)
#define GREEN lv_color_hex(0x2<<3)
#define BLUE lv_color_hex(0x3<<3)
#define RED lv_color_hex(0x4<<3)
#define YELLO lv_color_hex(0x5<<3)
#define ORANG lv_color_hex(0x6<<3)
LV_FONT_DECLARE(lv_font_simsun_26);
void DisplayerInit();
void DisplayerLoop();
void DisplayerPrint();
void DisplayerSleep();
#endif
Displayer.cpp
#include "Displayer.h"
#include <esp_heap_caps.h>
#include "../epd/EpdManage.h"
#define BUF_TIMES (CANVAS_HEIGHT)
static lv_disp_draw_buf_t draw_buf;
lv_color_t* buf1;
lv_color_t* buf2;
uint32_t flush_time=0;
uint8_t* canvas;
void my_print(const char *buf0)
{
Serial.printf(buf0);
Serial.flush();
}
void DrawPixel(int16_t x, int16_t y, uint16_t clr)
{
if(x<0 || x>=WIDTH || y<0 || y>=HEIGHT){
Serial.println("DrawPixel err");
return;
}
uint8_t k=(x&0x01);
x/=2;
if(k==0){
canvas[y*CANVAS_WIDTH+x]&=0x0f;
canvas[y*CANVAS_WIDTH+x]|=(clr&0xf)<<4;
}else{
canvas[y*CANVAS_WIDTH+x]&=0xf0;
canvas[y*CANVAS_WIDTH+x]|=(clr&0xf);
}
}
void DrawIcon(uint16_t *datas, int16_t x, int16_t y, int16_t module_cols, int16_t module_rows)
{
int16_t i, j;
flush_time=millis();
for (i = 0; i < module_rows; i++)
{
for (j = 0; j < module_cols; j++)
{
DrawPixel(x + j, y + i, datas[i * module_cols + j]);
}
}
flush_time=millis();
}
void my_disp_flush(lv_disp_drv_t *disp, const lv_area_t *area, lv_color_t *color_p)
{
Serial.printf("my_disp_flush %d,%d - %d,%d\r\n",area->x1,area->y1,area->x2,area->y2);
DrawIcon((uint16_t *)&color_p->full,
area->x1,area->y1, (area->x2 - area->x1 + 1), (area->y2 - area->y1 + 1));
lv_disp_flush_ready(disp);
Serial.printf("my_disp_flush end\r\n" );
}
void DisplayerInit(){
//从PSRAM分配
canvas = (uint8_t*) heap_caps_malloc(CANVAS_HEIGHT*CANVAS_WIDTH, MALLOC_CAP_SPIRAM);
Serial.printf("ps_calloc canvas %d\r\n",canvas);
buf1 = (lv_color_t*) heap_caps_malloc(WIDTH * BUF_TIMES, MALLOC_CAP_SPIRAM);
Serial.printf("ps_calloc buf1 %d\r\n",buf1);
buf2 = (lv_color_t*) heap_caps_malloc(WIDTH * BUF_TIMES, MALLOC_CAP_SPIRAM);
Serial.printf("ps_calloc buf2 %d\r\n",buf2);
lv_init();
//lv_log_register_print_cb(my_print);
lv_disp_draw_buf_init(&draw_buf, buf1, buf2, WIDTH * BUF_TIMES);
static lv_disp_drv_t disp_drv;
lv_disp_drv_init(&disp_drv);
disp_drv.hor_res = WIDTH;
disp_drv.ver_res = HEIGHT;
disp_drv.flush_cb = my_disp_flush;
disp_drv.draw_buf = &draw_buf;
lv_disp_drv_register(&disp_drv);
lv_obj_set_style_bg_color(lv_scr_act(), WHITE, 0);
lv_obj_set_style_bg_opa(lv_scr_act(), LV_OPA_COVER, 0);
lv_obj_set_scrollbar_mode(lv_scr_act(), LV_SCROLLBAR_MODE_OFF);
}
void DisplayerSleep(){
Serial.println("Sleep");
Serial.flush();
uint32_t sleeptime=1*60*60;//s
//使能唤醒定时器,使用定时器启用深度睡眠唤醒
esp_sleep_enable_timer_wakeup(sleeptime * S_TO_uS_FACTOR);
//进入睡眠
esp_deep_sleep_start();
}
void DisplayerLoop(){
lv_timer_handler();
if(flush_time>0 && (millis()-flush_time>5000)){
flush_time=0;
Serial.println("epd_user.DrawStart");
EpdManage.Draw(canvas);
//DisplayerPrint();
DisplayerSleep();
}
}
void DisplayerPrint(){
uint8_t* d=canvas;
Serial.println("piexl:");
for (size_t i = 0; i < CANVAS_SIZE; i++)
{
Serial.printf("0x%02x,",*d);
d++;
}
Serial.println("END");
}