ESP32-DevKitC 开发板 + ESP32-LCDKit + 16位并口屏 st7796
Moderator: ESP_Bob
ESP32-DevKitC 开发板 + ESP32-LCDKit + 16位并口屏 st7796
hi,大家好!
我手上有ESP32-DevKitC 开发板 + ESP32-LCDKit + 16位并口屏 st7796,按照SCH_ESP32-LCDKit_V1.1_20190218.pdf图纸连接,使用esp-iot-solution\examples\screen例子做测试,LCD为3.5寸,320X480,menuconfig里面也配置了相应的驱动。代码修改如下:
/* Screen Example
For other examples please check:
https://github.com/espressif/esp-iot-so ... r/examples
This example code is in the Public Domain (or CC0 licensed, at your option.)
Unless required by applicable law or agreed to in writing, this
software is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
CONDITIONS OF ANY KIND, either express or implied.
*/
#include <stdio.h>
#include <string.h>
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "freertos/queue.h"
#include "esp_log.h"
#include "esp_task_wdt.h"
#include "board.h"
#include "screen_driver.h"
#include "img_array.h"
static const char *TAG = "screen example";
/**
* @brief Draw Mandelbrot Set on screen, A helpful site http://usefuljs.net/fractals/
*/
/** If you use a spi interface screen, set the USE_SPI_SCREEN to 1, otherwise use 8080 interface. */
#define USE_SPI_SCREEN 0
#define MAX_ZOOM 2500
#define ITERATION 128
static uint16_t g_color_table[ITERATION];
static scr_driver_t g_lcd;
static scr_info_t g_lcd_info;
static void generate_mandelbrot(scr_driver_t *lcd, uint16_t size_x, uint16_t size_y, int32_t offset_x, int32_t offset_y, uint16_t zoom, uint16_t *line_buffer)
{
uint8_t i;
uint16_t x, y;
float tmp1, tmp2;
float p_r, p_i;
float num_real, num_img;
float radius;
ESP_LOGI(TAG, "zoom = %d", zoom);
for (y = 0; y < size_y; y++) {
for (x = 0; x < size_x; x++) {
num_real = x - offset_x;
p_r = num_real = num_real / zoom;
num_img = y - offset_y;
p_i = num_img = num_img / zoom;
i = 0;
radius = 0;
if (0 == x && 0 == y) {
ESP_LOGI(TAG, "start(%f, %f)", num_real, num_img);
}
if (size_x - 1 == x && size_y - 1 == y) {
ESP_LOGI(TAG, "end (%f, %f)", num_real, num_img);
}
while ((i < ITERATION - 1) && (radius < 16)) {
// z = z^2 + c
tmp1 = num_real * num_real;
tmp2 = num_img * num_img;
num_img = 2 * num_real * num_img + p_i;
num_real = tmp1 - tmp2 + p_r;
radius = tmp1 + tmp2; // Modulus^2
i++;
}
if (NULL != line_buffer) {
line_buffer[x] = g_color_table;
} else {
lcd->draw_pixel(x, y, g_color_table);
}
}
if (NULL != line_buffer) {
lcd->draw_bitmap(0, y, g_lcd_info.width, 1, line_buffer);
}
}
}
static uint16_t rgb888_to_rgb565(uint8_t r, uint8_t g, uint8_t b)
{
return ((r & 0xF8) << 8) | ((g & 0xFC) << 3) | (b >> 3);
}
static void init_CLUT(uint16_t *clut)
{
uint32_t i = 0x00;
uint16_t red = 0, green = 0, blue = 0;
for (i = 0; i < ITERATION; i++) {
red = (i * 6 * 256 / ITERATION) % 256;
green = (i * 4 * 256 / ITERATION) % 256;
blue = (i * 8 * 256 / ITERATION) % 256;
clut = rgb888_to_rgb565(red, green, blue);
}
}
static void screen_clear(scr_driver_t *lcd, int color)
{
scr_info_t lcd_info;
lcd->get_info(&lcd_info);
uint16_t *buffer = malloc(lcd_info.width * sizeof(uint16_t));
if (NULL == buffer) {
for (size_t y = 0; y < lcd_info.height; y++) {
for (size_t x = 0; x < lcd_info.width; x++) {
lcd->draw_pixel(x, y, color);
}
}
} else {
for (size_t i = 0; i < lcd_info.width; i++) {
buffer = color;
}
for (int y = 0; y < lcd_info.height; y++) {
lcd->draw_bitmap(0, y, lcd_info.width, 1, buffer);
}
free(buffer);
}
}
static void lcd_bitmap_test(scr_driver_t *lcd)
{
scr_info_t lcd_info;
lcd->get_info(&lcd_info);
uint16_t *pixels = heap_caps_malloc((img_width * img_height) * sizeof(uint16_t), MALLOC_CAP_8BIT | MALLOC_CAP_INTERNAL);
if (NULL == pixels) {
ESP_LOGE(TAG, "Memory for bitmap is not enough");
return;
}
memcpy(pixels, img_array, (img_width * img_height) * sizeof(uint16_t));
lcd->draw_bitmap(0, 0, img_width, img_height, (uint16_t *)pixels);
heap_caps_free(pixels);
}
static void lcd_speed_test(scr_driver_t *lcd)
{
scr_info_t lcd_info;
lcd->get_info(&lcd_info);
uint32_t w = 240, h = 240;
w = lcd_info.width < w ? lcd_info.width : w;
h = lcd_info.height < h ? lcd_info.height : h;
const uint32_t buffer_size = w * h;
uint16_t *pixels = heap_caps_malloc(buffer_size * sizeof(uint16_t), MALLOC_CAP_8BIT | MALLOC_CAP_INTERNAL);
if (NULL == pixels) {
ESP_LOGE(TAG, "Memory for bitmap is not enough");
return;
}
esp_task_wdt_delete(xTaskGetIdleTaskHandleForCPU(xPortGetCoreID()));
const uint16_t color_table[] = {COLOR_RED, COLOR_GREEN, COLOR_BLUE, COLOR_YELLOW};
uint32_t times = 256;
uint64_t s;
uint64_t t1 = 0;
for (int i = 0; i < times; i++) {
for (int j = 0; j < buffer_size; j++) {
pixels[j] = color_table[i % 4];
}
s = esp_timer_get_time();
lcd->draw_bitmap(0, 0, w, h, pixels);
t1 += (esp_timer_get_time() - s);
}
t1 = t1 / 1000;
float time_per_frame = (float)t1 / (float)times;
float fps = (float)times * 1000.f / (float)t1;
float write_speed = sizeof(uint16_t) * buffer_size * times / 1024.0f / 1.0240f / (float)t1;
float factor = ((float)w * (float)h) / ((float)lcd_info.width * (float)lcd_info.height);
ESP_LOGI(TAG, "-------%s Test Result------", lcd_info.name);
if (w != lcd_info.width || h != lcd_info.height) {
ESP_LOGI(TAG, "@resolution 240x240 [time per frame=%.2fMS, fps=%.2f, speed=%.2fMB/s]", time_per_frame, fps, write_speed);
ESP_LOGI(TAG, "@resolution %ux%u infer to [time per frame=%.2fMS, fps=%.2f]",
lcd_info.width, lcd_info.height,
time_per_frame / factor, factor * fps);
} else {
ESP_LOGI(TAG, "@resolution %ux%u [time per frame=%.2fMS, fps=%.2f, speed=%.2fMB/s]", lcd_info.width, lcd_info.height, time_per_frame, fps, write_speed);
}
ESP_LOGI(TAG, "-------------------------------------");
esp_task_wdt_add(xTaskGetIdleTaskHandleForCPU(xPortGetCoreID()));
heap_caps_free(pixels);
}
void app_main(void)
{
esp_err_t ret = ESP_OK;
#if USE_SPI_SCREEN
iot_board_init();
spi_bus_handle_t spi_bus = iot_board_get_handle(BOARD_SPI2_ID);
scr_interface_spi_config_t spi_lcd_cfg = {
.spi_bus = spi_bus,
.pin_num_cs = BOARD_LCD_SPI_CS_PIN,
.pin_num_dc = BOARD_LCD_SPI_DC_PIN,
.clk_freq = BOARD_LCD_SPI_CLOCK_FREQ,
.swap_data = true,
};
scr_interface_driver_t *iface_drv;
scr_interface_create(SCREEN_IFACE_SPI, &spi_lcd_cfg, &iface_drv);
ret = scr_find_driver(SCREEN_CONTROLLER_ILI9341, &g_lcd);
if (ESP_OK != ret) {
return;
ESP_LOGE(TAG, "screen find failed");
}
scr_controller_config_t lcd_cfg = {
.interface_drv = iface_drv,
.pin_num_rst = BOARD_LCD_SPI_RESET_PIN,
.pin_num_bckl = BOARD_LCD_SPI_BL_PIN,
.rst_active_level = 0,
.bckl_active_level = 1,
.offset_hor = 0,
.offset_ver = 0,
.width = 240,
.height = 320,
.rotate = SCR_DIR_BTRL,
};
ret = g_lcd.init(&lcd_cfg);
#else
//iot_board_init();
i2s_lcd_config_t i2s_lcd_cfg = {
.data_width = BOARD_LCD_I2S_BITWIDTH,
.pin_data_num = {
BOARD_LCD_I2S_D0_PIN,
BOARD_LCD_I2S_D1_PIN,
BOARD_LCD_I2S_D2_PIN,
BOARD_LCD_I2S_D3_PIN,
BOARD_LCD_I2S_D4_PIN,
BOARD_LCD_I2S_D5_PIN,
BOARD_LCD_I2S_D6_PIN,
BOARD_LCD_I2S_D7_PIN,
BOARD_LCD_I2S_D8_PIN,
BOARD_LCD_I2S_D9_PIN,
BOARD_LCD_I2S_D10_PIN,
BOARD_LCD_I2S_D11_PIN,
BOARD_LCD_I2S_D12_PIN,
BOARD_LCD_I2S_D13_PIN,
BOARD_LCD_I2S_D14_PIN,
BOARD_LCD_I2S_D15_PIN,
},
.pin_num_cs = BOARD_LCD_I2S_CS_PIN,
.pin_num_wr = BOARD_LCD_I2S_WR_PIN,
.pin_num_rs = BOARD_LCD_I2S_RS_PIN,
.clk_freq = 20000000,
.i2s_port = I2S_NUM_0,
.buffer_size = 32000,
.swap_data = true,
};
scr_interface_driver_t *iface_drv;
scr_interface_create(SCREEN_IFACE_8080, &i2s_lcd_cfg, &iface_drv);
ret = scr_find_driver(SCREEN_CONTROLLER_ST7796, &g_lcd);
if (ESP_OK != ret) {
return;
ESP_LOGE(TAG, "screen find failed");
}
scr_controller_config_t lcd_cfg = {
.interface_drv = iface_drv,
.pin_num_rst = BOARD_LCD_I2S_RESET_PIN,
.pin_num_bckl = BOARD_LCD_I2S_BL_PIN,
.rst_active_level = 0,
.bckl_active_level = 1,
.offset_hor = 0,
.offset_ver = 0,
.width = 320,
.height = 480,
.rotate = SCR_SWAP_XY | SCR_MIRROR_Y, /** equal to SCR_DIR_BTLR */
};
ret = g_lcd.init(&lcd_cfg);
#endif
if (ESP_OK != ret) {
return;
ESP_LOGE(TAG, "screen initialize failed");
}
g_lcd.get_info(&g_lcd_info);
ESP_LOGI(TAG, "Screen name:%s | width:%d | height:%d", g_lcd_info.name, g_lcd_info.width, g_lcd_info.height);
screen_clear(&g_lcd, COLOR_ESP_BKGD);
vTaskDelay(pdMS_TO_TICKS(500));
/** Run test */
lcd_bitmap_test(&g_lcd);
vTaskDelay(pdMS_TO_TICKS(2000));
lcd_speed_test(&g_lcd);
vTaskDelay(pdMS_TO_TICKS(2000));
init_CLUT(g_color_table); /** Initialize color look up table */
/** Define an interesting point on the complex plane */
float real = -0.68481 + (g_lcd_info.width / 2 / (float)MAX_ZOOM);
float img = 0.380584 + (g_lcd_info.height / 2 / (float)MAX_ZOOM);
uint16_t *pixels = heap_caps_malloc(g_lcd_info.width * sizeof(uint16_t), MALLOC_CAP_8BIT | MALLOC_CAP_INTERNAL);
if (NULL == pixels) {
ESP_LOGE(TAG, "Memory for bitmap is not enough");
return;
}
float zoom;
while (1) {
for (zoom = 50; zoom <= MAX_ZOOM; zoom *= 1.1f) {
int32_t off_x = (real) * zoom;
int32_t off_y = (img) * zoom;
generate_mandelbrot(&g_lcd, g_lcd_info.width, g_lcd_info.height, g_lcd_info.width / 2 - off_x, g_lcd_info.height / 2 - off_y, zoom, pixels);
vTaskDelay(1); /** Delay one tick for feed task watchdog */
}
for (; zoom > 50; zoom /= 1.1f) {
int32_t off_x = (real) * zoom;
int32_t off_y = (img) * zoom;
generate_mandelbrot(&g_lcd, g_lcd_info.width, g_lcd_info.height, g_lcd_info.width / 2 - off_x, g_lcd_info.height / 2 - off_y, zoom, pixels);
vTaskDelay(1);
}
}
}
从运行日志情况看:
--- WARNING: GDB cannot open serial ports accessed as COMx
--- Using \\.\COM33 instead...
--- idf_monitor on \\.\COM33 115200 ---
--- Quit: Ctrl+] | Menu: Ctrl+T | Help: Ctrl+T followed by Ctrl+H ---
ets Jul 29 2019 12:21:46
rst:0x1 (POWERON_RESET),boot:0x17 (SPI_FAST_FLASH_BOOT)
configsip: 0, SPIWP:0xee
clk_drv:0x00,q_drv:0x00,d_drv:0x00,cs0_drv:0x00,hd_drv:0x00,wp_drv:0x00
mode:DIO, clock div:2
load:0x3fff0030,len:6896
load:0x40078000,len:14292
ho 0 tail 12 room 4
load:0x40080400,len:3688
0x40080400: _init at ??:?
entry 0x40080678
I (29) boot: ESP-IDF v4.3 2nd stage bootloader
I (29) boot: compile time 23:04:34
I (29) boot: chip revision: 3
I (32) boot_comm: chip revision: 3, min. bootloader chip revision: 0
I (39) boot.esp32: SPI Speed : 40MHz
I (43) boot.esp32: SPI Mode : DIO
I (48) boot.esp32: SPI Flash Size : 2MB
I (53) boot: Enabling RNG early entropy source...
I (58) boot: Partition Table:
I (62) boot: ## Label Usage Type ST Offset Length
I (69) boot: 0 nvs WiFi data 01 02 00009000 00006000
I (76) boot: 1 phy_init RF data 01 01 0000f000 00001000
I (84) boot: 2 factory factory app 00 00 00010000 00100000
I (91) boot: End of partition table
I (95) boot_comm: chip revision: 3, min. application chip revision: 0
I (103) esp_image: segment 0: paddr=00010020 vaddr=3f400020 size=19934h (104756) map
I (151) esp_image: segment 1: paddr=0002995c vaddr=3ffb0000 size=02a00h ( 10752) load
I (155) esp_image: segment 2: paddr=0002c364 vaddr=40080000 size=03cb4h ( 15540) load
I (163) esp_image: segment 3: paddr=00030020 vaddr=400d0020 size=19cd0h (105680) map
I (205) esp_image: segment 4: paddr=00049cf8 vaddr=40083cb4 size=09c04h ( 39940) load
I (222) esp_image: segment 5: paddr=00053904 vaddr=50000000 size=00010h ( 16) load
I (230) boot: Loaded app from partition at offset 0x10000
I (230) boot: Disabling RNG early entropy source...
I (242) cpu_start: Pro cpu up.
I (242) cpu_start: Starting app cpu, entry point is 0x400811dc
0x400811dc: call_start_cpu1 at D:/esp/esp-idf/components/esp_system/port/cpu_start.c:141
I (0) cpu_start: App cpu up.
I (257) cpu_start: Pro cpu start user code
I (257) cpu_start: cpu freq: 240000000
I (257) cpu_start: Application information:
I (261) cpu_start: Project name: screen
I (266) cpu_start: App version: 87e76fd-dirty
I (271) cpu_start: Compile time: Oct 9 2021 23:03:55
I (278) cpu_start: ELF file SHA256: 32c61b9041962e0f...
I (283) cpu_start: ESP-IDF: v4.3
I (288) heap_init: Initializing. RAM available for dynamic allocation:
I (295) heap_init: At 3FFAE6E0 len 00001920 (6 KiB): DRAM
I (301) heap_init: At 3FFB33E0 len 0002CC20 (179 KiB): DRAM
I (308) heap_init: At 3FFE0440 len 00003AE0 (14 KiB): D/IRAM
I (314) heap_init: At 3FFE4350 len 0001BCB0 (111 KiB): D/IRAM
I (321) heap_init: At 4008D8B8 len 00012748 (73 KiB): IRAM
I (328) spi_flash: detected chip: generic
I (331) spi_flash: flash io: dio
W (335) spi_flash: Detected size(8192k) larger than the size in the binary image header(2048k). Using the size in the binary image header.
I (349) cpu_start: Starting scheduler on PRO CPU.
I (0) cpu_start: Starting scheduler on APP CPU.
I (364) ESP32_I2S_LCD: Enable I2S0
I (368) ESP32_I2S_LCD: lcd_buffer_size: 32000, lcd_dma_size: 4000, lcd_dma_node_cnt: 8
I (376) ESP32_I2S_LCD: i2s lcd driver init ok
I (493) lcd st7796: MADCTL=a8
I (493) screen example: Screen name:ST7796 | width:480 | height:320
I (5526) screen example: -------ST7796 Test Result------
I (5527) screen example: @resolution 240x240 [time per frame=4.48MS, fps=223.19, speed=24.52MB/s]
I (5532) screen example: @resolution 480x320 infer to [time per frame=11.95MS, fps=83.70]
I (5541) screen example: -------------------------------------
I (7547) screen example: zoom = 50
I (7547) screen example: start(-5.380000, -2.760000)
I (7852) screen example: end (4.200000, 3.620000)
I (7853) screen example: zoom = 55
I (7853) screen example: start(-4.945455, -2.472727)
I (8179) screen example: end (3.763636, 3.327273)
I (8180) screen example: zoom = 60
I (8180) screen example: start(-4.583333, -2.233333)
I (8525) screen example: end (3.400000, 3.083333)
I (8526) screen example: zoom = 66
I (8526) screen example: start(-4.227273, -1.984848)
I (8894) screen example: end (3.030303, 2.848485)
I (8896) screen example: zoom = 73
I (8896) screen example: start(-3.876712, -1.753425)
I (9294) screen example: end (2.684932, 2.616438)
I (9295) screen example: zoom = 80
I (9295) screen example: start(-3.587500, -1.562500)
I (9726) screen example: end (2.400000, 2.425000)
I (9727) screen example: zoom = 88
I (9727) screen example: start(-3.318182, -1.375000)
I (10197) screen example: end (2.125000, 2.250000)
I (10199) screen example: zoom = 97
I (10199) screen example: start(-3.061856, -1.206186)
I (10718) screen example: end (1.876289, 2.082474)
I (10719) screen example: zoom = 107
I (10719) screen example: start(-2.831776, -1.056075)
I (11298) screen example: end (1.644860, 1.925234)
I (11299) screen example: zoom = 117
I (11299) screen example: start(-2.641026, -0.923077)
也没有出现错误,但是屏没有正常显示
我手上有ESP32-DevKitC 开发板 + ESP32-LCDKit + 16位并口屏 st7796,按照SCH_ESP32-LCDKit_V1.1_20190218.pdf图纸连接,使用esp-iot-solution\examples\screen例子做测试,LCD为3.5寸,320X480,menuconfig里面也配置了相应的驱动。代码修改如下:
/* Screen Example
For other examples please check:
https://github.com/espressif/esp-iot-so ... r/examples
This example code is in the Public Domain (or CC0 licensed, at your option.)
Unless required by applicable law or agreed to in writing, this
software is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
CONDITIONS OF ANY KIND, either express or implied.
*/
#include <stdio.h>
#include <string.h>
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "freertos/queue.h"
#include "esp_log.h"
#include "esp_task_wdt.h"
#include "board.h"
#include "screen_driver.h"
#include "img_array.h"
static const char *TAG = "screen example";
/**
* @brief Draw Mandelbrot Set on screen, A helpful site http://usefuljs.net/fractals/
*/
/** If you use a spi interface screen, set the USE_SPI_SCREEN to 1, otherwise use 8080 interface. */
#define USE_SPI_SCREEN 0
#define MAX_ZOOM 2500
#define ITERATION 128
static uint16_t g_color_table[ITERATION];
static scr_driver_t g_lcd;
static scr_info_t g_lcd_info;
static void generate_mandelbrot(scr_driver_t *lcd, uint16_t size_x, uint16_t size_y, int32_t offset_x, int32_t offset_y, uint16_t zoom, uint16_t *line_buffer)
{
uint8_t i;
uint16_t x, y;
float tmp1, tmp2;
float p_r, p_i;
float num_real, num_img;
float radius;
ESP_LOGI(TAG, "zoom = %d", zoom);
for (y = 0; y < size_y; y++) {
for (x = 0; x < size_x; x++) {
num_real = x - offset_x;
p_r = num_real = num_real / zoom;
num_img = y - offset_y;
p_i = num_img = num_img / zoom;
i = 0;
radius = 0;
if (0 == x && 0 == y) {
ESP_LOGI(TAG, "start(%f, %f)", num_real, num_img);
}
if (size_x - 1 == x && size_y - 1 == y) {
ESP_LOGI(TAG, "end (%f, %f)", num_real, num_img);
}
while ((i < ITERATION - 1) && (radius < 16)) {
// z = z^2 + c
tmp1 = num_real * num_real;
tmp2 = num_img * num_img;
num_img = 2 * num_real * num_img + p_i;
num_real = tmp1 - tmp2 + p_r;
radius = tmp1 + tmp2; // Modulus^2
i++;
}
if (NULL != line_buffer) {
line_buffer[x] = g_color_table;
} else {
lcd->draw_pixel(x, y, g_color_table);
}
}
if (NULL != line_buffer) {
lcd->draw_bitmap(0, y, g_lcd_info.width, 1, line_buffer);
}
}
}
static uint16_t rgb888_to_rgb565(uint8_t r, uint8_t g, uint8_t b)
{
return ((r & 0xF8) << 8) | ((g & 0xFC) << 3) | (b >> 3);
}
static void init_CLUT(uint16_t *clut)
{
uint32_t i = 0x00;
uint16_t red = 0, green = 0, blue = 0;
for (i = 0; i < ITERATION; i++) {
red = (i * 6 * 256 / ITERATION) % 256;
green = (i * 4 * 256 / ITERATION) % 256;
blue = (i * 8 * 256 / ITERATION) % 256;
clut = rgb888_to_rgb565(red, green, blue);
}
}
static void screen_clear(scr_driver_t *lcd, int color)
{
scr_info_t lcd_info;
lcd->get_info(&lcd_info);
uint16_t *buffer = malloc(lcd_info.width * sizeof(uint16_t));
if (NULL == buffer) {
for (size_t y = 0; y < lcd_info.height; y++) {
for (size_t x = 0; x < lcd_info.width; x++) {
lcd->draw_pixel(x, y, color);
}
}
} else {
for (size_t i = 0; i < lcd_info.width; i++) {
buffer = color;
}
for (int y = 0; y < lcd_info.height; y++) {
lcd->draw_bitmap(0, y, lcd_info.width, 1, buffer);
}
free(buffer);
}
}
static void lcd_bitmap_test(scr_driver_t *lcd)
{
scr_info_t lcd_info;
lcd->get_info(&lcd_info);
uint16_t *pixels = heap_caps_malloc((img_width * img_height) * sizeof(uint16_t), MALLOC_CAP_8BIT | MALLOC_CAP_INTERNAL);
if (NULL == pixels) {
ESP_LOGE(TAG, "Memory for bitmap is not enough");
return;
}
memcpy(pixels, img_array, (img_width * img_height) * sizeof(uint16_t));
lcd->draw_bitmap(0, 0, img_width, img_height, (uint16_t *)pixels);
heap_caps_free(pixels);
}
static void lcd_speed_test(scr_driver_t *lcd)
{
scr_info_t lcd_info;
lcd->get_info(&lcd_info);
uint32_t w = 240, h = 240;
w = lcd_info.width < w ? lcd_info.width : w;
h = lcd_info.height < h ? lcd_info.height : h;
const uint32_t buffer_size = w * h;
uint16_t *pixels = heap_caps_malloc(buffer_size * sizeof(uint16_t), MALLOC_CAP_8BIT | MALLOC_CAP_INTERNAL);
if (NULL == pixels) {
ESP_LOGE(TAG, "Memory for bitmap is not enough");
return;
}
esp_task_wdt_delete(xTaskGetIdleTaskHandleForCPU(xPortGetCoreID()));
const uint16_t color_table[] = {COLOR_RED, COLOR_GREEN, COLOR_BLUE, COLOR_YELLOW};
uint32_t times = 256;
uint64_t s;
uint64_t t1 = 0;
for (int i = 0; i < times; i++) {
for (int j = 0; j < buffer_size; j++) {
pixels[j] = color_table[i % 4];
}
s = esp_timer_get_time();
lcd->draw_bitmap(0, 0, w, h, pixels);
t1 += (esp_timer_get_time() - s);
}
t1 = t1 / 1000;
float time_per_frame = (float)t1 / (float)times;
float fps = (float)times * 1000.f / (float)t1;
float write_speed = sizeof(uint16_t) * buffer_size * times / 1024.0f / 1.0240f / (float)t1;
float factor = ((float)w * (float)h) / ((float)lcd_info.width * (float)lcd_info.height);
ESP_LOGI(TAG, "-------%s Test Result------", lcd_info.name);
if (w != lcd_info.width || h != lcd_info.height) {
ESP_LOGI(TAG, "@resolution 240x240 [time per frame=%.2fMS, fps=%.2f, speed=%.2fMB/s]", time_per_frame, fps, write_speed);
ESP_LOGI(TAG, "@resolution %ux%u infer to [time per frame=%.2fMS, fps=%.2f]",
lcd_info.width, lcd_info.height,
time_per_frame / factor, factor * fps);
} else {
ESP_LOGI(TAG, "@resolution %ux%u [time per frame=%.2fMS, fps=%.2f, speed=%.2fMB/s]", lcd_info.width, lcd_info.height, time_per_frame, fps, write_speed);
}
ESP_LOGI(TAG, "-------------------------------------");
esp_task_wdt_add(xTaskGetIdleTaskHandleForCPU(xPortGetCoreID()));
heap_caps_free(pixels);
}
void app_main(void)
{
esp_err_t ret = ESP_OK;
#if USE_SPI_SCREEN
iot_board_init();
spi_bus_handle_t spi_bus = iot_board_get_handle(BOARD_SPI2_ID);
scr_interface_spi_config_t spi_lcd_cfg = {
.spi_bus = spi_bus,
.pin_num_cs = BOARD_LCD_SPI_CS_PIN,
.pin_num_dc = BOARD_LCD_SPI_DC_PIN,
.clk_freq = BOARD_LCD_SPI_CLOCK_FREQ,
.swap_data = true,
};
scr_interface_driver_t *iface_drv;
scr_interface_create(SCREEN_IFACE_SPI, &spi_lcd_cfg, &iface_drv);
ret = scr_find_driver(SCREEN_CONTROLLER_ILI9341, &g_lcd);
if (ESP_OK != ret) {
return;
ESP_LOGE(TAG, "screen find failed");
}
scr_controller_config_t lcd_cfg = {
.interface_drv = iface_drv,
.pin_num_rst = BOARD_LCD_SPI_RESET_PIN,
.pin_num_bckl = BOARD_LCD_SPI_BL_PIN,
.rst_active_level = 0,
.bckl_active_level = 1,
.offset_hor = 0,
.offset_ver = 0,
.width = 240,
.height = 320,
.rotate = SCR_DIR_BTRL,
};
ret = g_lcd.init(&lcd_cfg);
#else
//iot_board_init();
i2s_lcd_config_t i2s_lcd_cfg = {
.data_width = BOARD_LCD_I2S_BITWIDTH,
.pin_data_num = {
BOARD_LCD_I2S_D0_PIN,
BOARD_LCD_I2S_D1_PIN,
BOARD_LCD_I2S_D2_PIN,
BOARD_LCD_I2S_D3_PIN,
BOARD_LCD_I2S_D4_PIN,
BOARD_LCD_I2S_D5_PIN,
BOARD_LCD_I2S_D6_PIN,
BOARD_LCD_I2S_D7_PIN,
BOARD_LCD_I2S_D8_PIN,
BOARD_LCD_I2S_D9_PIN,
BOARD_LCD_I2S_D10_PIN,
BOARD_LCD_I2S_D11_PIN,
BOARD_LCD_I2S_D12_PIN,
BOARD_LCD_I2S_D13_PIN,
BOARD_LCD_I2S_D14_PIN,
BOARD_LCD_I2S_D15_PIN,
},
.pin_num_cs = BOARD_LCD_I2S_CS_PIN,
.pin_num_wr = BOARD_LCD_I2S_WR_PIN,
.pin_num_rs = BOARD_LCD_I2S_RS_PIN,
.clk_freq = 20000000,
.i2s_port = I2S_NUM_0,
.buffer_size = 32000,
.swap_data = true,
};
scr_interface_driver_t *iface_drv;
scr_interface_create(SCREEN_IFACE_8080, &i2s_lcd_cfg, &iface_drv);
ret = scr_find_driver(SCREEN_CONTROLLER_ST7796, &g_lcd);
if (ESP_OK != ret) {
return;
ESP_LOGE(TAG, "screen find failed");
}
scr_controller_config_t lcd_cfg = {
.interface_drv = iface_drv,
.pin_num_rst = BOARD_LCD_I2S_RESET_PIN,
.pin_num_bckl = BOARD_LCD_I2S_BL_PIN,
.rst_active_level = 0,
.bckl_active_level = 1,
.offset_hor = 0,
.offset_ver = 0,
.width = 320,
.height = 480,
.rotate = SCR_SWAP_XY | SCR_MIRROR_Y, /** equal to SCR_DIR_BTLR */
};
ret = g_lcd.init(&lcd_cfg);
#endif
if (ESP_OK != ret) {
return;
ESP_LOGE(TAG, "screen initialize failed");
}
g_lcd.get_info(&g_lcd_info);
ESP_LOGI(TAG, "Screen name:%s | width:%d | height:%d", g_lcd_info.name, g_lcd_info.width, g_lcd_info.height);
screen_clear(&g_lcd, COLOR_ESP_BKGD);
vTaskDelay(pdMS_TO_TICKS(500));
/** Run test */
lcd_bitmap_test(&g_lcd);
vTaskDelay(pdMS_TO_TICKS(2000));
lcd_speed_test(&g_lcd);
vTaskDelay(pdMS_TO_TICKS(2000));
init_CLUT(g_color_table); /** Initialize color look up table */
/** Define an interesting point on the complex plane */
float real = -0.68481 + (g_lcd_info.width / 2 / (float)MAX_ZOOM);
float img = 0.380584 + (g_lcd_info.height / 2 / (float)MAX_ZOOM);
uint16_t *pixels = heap_caps_malloc(g_lcd_info.width * sizeof(uint16_t), MALLOC_CAP_8BIT | MALLOC_CAP_INTERNAL);
if (NULL == pixels) {
ESP_LOGE(TAG, "Memory for bitmap is not enough");
return;
}
float zoom;
while (1) {
for (zoom = 50; zoom <= MAX_ZOOM; zoom *= 1.1f) {
int32_t off_x = (real) * zoom;
int32_t off_y = (img) * zoom;
generate_mandelbrot(&g_lcd, g_lcd_info.width, g_lcd_info.height, g_lcd_info.width / 2 - off_x, g_lcd_info.height / 2 - off_y, zoom, pixels);
vTaskDelay(1); /** Delay one tick for feed task watchdog */
}
for (; zoom > 50; zoom /= 1.1f) {
int32_t off_x = (real) * zoom;
int32_t off_y = (img) * zoom;
generate_mandelbrot(&g_lcd, g_lcd_info.width, g_lcd_info.height, g_lcd_info.width / 2 - off_x, g_lcd_info.height / 2 - off_y, zoom, pixels);
vTaskDelay(1);
}
}
}
从运行日志情况看:
--- WARNING: GDB cannot open serial ports accessed as COMx
--- Using \\.\COM33 instead...
--- idf_monitor on \\.\COM33 115200 ---
--- Quit: Ctrl+] | Menu: Ctrl+T | Help: Ctrl+T followed by Ctrl+H ---
ets Jul 29 2019 12:21:46
rst:0x1 (POWERON_RESET),boot:0x17 (SPI_FAST_FLASH_BOOT)
configsip: 0, SPIWP:0xee
clk_drv:0x00,q_drv:0x00,d_drv:0x00,cs0_drv:0x00,hd_drv:0x00,wp_drv:0x00
mode:DIO, clock div:2
load:0x3fff0030,len:6896
load:0x40078000,len:14292
ho 0 tail 12 room 4
load:0x40080400,len:3688
0x40080400: _init at ??:?
entry 0x40080678
I (29) boot: ESP-IDF v4.3 2nd stage bootloader
I (29) boot: compile time 23:04:34
I (29) boot: chip revision: 3
I (32) boot_comm: chip revision: 3, min. bootloader chip revision: 0
I (39) boot.esp32: SPI Speed : 40MHz
I (43) boot.esp32: SPI Mode : DIO
I (48) boot.esp32: SPI Flash Size : 2MB
I (53) boot: Enabling RNG early entropy source...
I (58) boot: Partition Table:
I (62) boot: ## Label Usage Type ST Offset Length
I (69) boot: 0 nvs WiFi data 01 02 00009000 00006000
I (76) boot: 1 phy_init RF data 01 01 0000f000 00001000
I (84) boot: 2 factory factory app 00 00 00010000 00100000
I (91) boot: End of partition table
I (95) boot_comm: chip revision: 3, min. application chip revision: 0
I (103) esp_image: segment 0: paddr=00010020 vaddr=3f400020 size=19934h (104756) map
I (151) esp_image: segment 1: paddr=0002995c vaddr=3ffb0000 size=02a00h ( 10752) load
I (155) esp_image: segment 2: paddr=0002c364 vaddr=40080000 size=03cb4h ( 15540) load
I (163) esp_image: segment 3: paddr=00030020 vaddr=400d0020 size=19cd0h (105680) map
I (205) esp_image: segment 4: paddr=00049cf8 vaddr=40083cb4 size=09c04h ( 39940) load
I (222) esp_image: segment 5: paddr=00053904 vaddr=50000000 size=00010h ( 16) load
I (230) boot: Loaded app from partition at offset 0x10000
I (230) boot: Disabling RNG early entropy source...
I (242) cpu_start: Pro cpu up.
I (242) cpu_start: Starting app cpu, entry point is 0x400811dc
0x400811dc: call_start_cpu1 at D:/esp/esp-idf/components/esp_system/port/cpu_start.c:141
I (0) cpu_start: App cpu up.
I (257) cpu_start: Pro cpu start user code
I (257) cpu_start: cpu freq: 240000000
I (257) cpu_start: Application information:
I (261) cpu_start: Project name: screen
I (266) cpu_start: App version: 87e76fd-dirty
I (271) cpu_start: Compile time: Oct 9 2021 23:03:55
I (278) cpu_start: ELF file SHA256: 32c61b9041962e0f...
I (283) cpu_start: ESP-IDF: v4.3
I (288) heap_init: Initializing. RAM available for dynamic allocation:
I (295) heap_init: At 3FFAE6E0 len 00001920 (6 KiB): DRAM
I (301) heap_init: At 3FFB33E0 len 0002CC20 (179 KiB): DRAM
I (308) heap_init: At 3FFE0440 len 00003AE0 (14 KiB): D/IRAM
I (314) heap_init: At 3FFE4350 len 0001BCB0 (111 KiB): D/IRAM
I (321) heap_init: At 4008D8B8 len 00012748 (73 KiB): IRAM
I (328) spi_flash: detected chip: generic
I (331) spi_flash: flash io: dio
W (335) spi_flash: Detected size(8192k) larger than the size in the binary image header(2048k). Using the size in the binary image header.
I (349) cpu_start: Starting scheduler on PRO CPU.
I (0) cpu_start: Starting scheduler on APP CPU.
I (364) ESP32_I2S_LCD: Enable I2S0
I (368) ESP32_I2S_LCD: lcd_buffer_size: 32000, lcd_dma_size: 4000, lcd_dma_node_cnt: 8
I (376) ESP32_I2S_LCD: i2s lcd driver init ok
I (493) lcd st7796: MADCTL=a8
I (493) screen example: Screen name:ST7796 | width:480 | height:320
I (5526) screen example: -------ST7796 Test Result------
I (5527) screen example: @resolution 240x240 [time per frame=4.48MS, fps=223.19, speed=24.52MB/s]
I (5532) screen example: @resolution 480x320 infer to [time per frame=11.95MS, fps=83.70]
I (5541) screen example: -------------------------------------
I (7547) screen example: zoom = 50
I (7547) screen example: start(-5.380000, -2.760000)
I (7852) screen example: end (4.200000, 3.620000)
I (7853) screen example: zoom = 55
I (7853) screen example: start(-4.945455, -2.472727)
I (8179) screen example: end (3.763636, 3.327273)
I (8180) screen example: zoom = 60
I (8180) screen example: start(-4.583333, -2.233333)
I (8525) screen example: end (3.400000, 3.083333)
I (8526) screen example: zoom = 66
I (8526) screen example: start(-4.227273, -1.984848)
I (8894) screen example: end (3.030303, 2.848485)
I (8896) screen example: zoom = 73
I (8896) screen example: start(-3.876712, -1.753425)
I (9294) screen example: end (2.684932, 2.616438)
I (9295) screen example: zoom = 80
I (9295) screen example: start(-3.587500, -1.562500)
I (9726) screen example: end (2.400000, 2.425000)
I (9727) screen example: zoom = 88
I (9727) screen example: start(-3.318182, -1.375000)
I (10197) screen example: end (2.125000, 2.250000)
I (10199) screen example: zoom = 97
I (10199) screen example: start(-3.061856, -1.206186)
I (10718) screen example: end (1.876289, 2.082474)
I (10719) screen example: zoom = 107
I (10719) screen example: start(-2.831776, -1.056075)
I (11298) screen example: end (1.644860, 1.925234)
I (11299) screen example: zoom = 117
I (11299) screen example: start(-2.641026, -0.923077)
也没有出现错误,但是屏没有正常显示
Last edited by iincity on Sun Oct 10, 2021 9:50 am, edited 2 times in total.
Re: 我买了ESP32-DevKitC 开发板,我想知道 board.h 里面定义对应关系
data sheet 里显示的是外设的默认管脚配置,显示 NC 的是连接了内部 flash ,已经设置好了用途,不再拉出供用户自由配置。
Re: ESP32-DevKitC 开发板 + ESP32-LCDKit + 16位并口屏 st7796
你的意思是,例子里面的16位并口配置本身就不对吗?
Re: ESP32-DevKitC 开发板 + ESP32-LCDKit + 16位并口屏 st7796
我这套开发板上接了一个1.54的spi屏测试。测试还是选的screen例子。后面那个测试用例generate_mandelbrot,显示速度很慢,是正常吗
Re: ESP32-DevKitC 开发板 + ESP32-LCDKit + 16位并口屏 st7796
你的log里显示I (5532) screen example: @resolution 480x320 infer to [time per frame=11.95MS, fps=83.70] 帧率83.7,挺快的,显示慢是因为计算消耗了时间,是正常现象
Re: ESP32-DevKitC 开发板 + ESP32-LCDKit + 16位并口屏 st7796
上面那个日志是测试并口的日志,后面我问的是spi,是两个问题 。
spi 测试日志
(18463) screen example: @resolution 240x240 [time per frame=54.47MS, fps=18.36, speed=2.02MB/s]
spi的例子里面screen定义
#define BOARD_LCD_SPI_CLOCK_FREQ 20000000
这个速度我修改成更高的频率。运行会提示错误。这个速率可以提高吗。看menuconfig里面也没有配置,看到网上有人用4.2版本,menuconfig里面是可以配置80M的。什么地方配置错了呢。还有那个并口的问题是什么问题?
我现在用的4.3,例子是 esp-iot-solution里面的例子。
Re: ESP32-DevKitC 开发板 + ESP32-LCDKit + 16位并口屏 st7796
是不是报的这个错误 “In full-duplex mode, only support cs pretrans delay = 1 and without address_bits and command_bits”如果是这个错误,根据提示修改dev_config->flags SPI_DEVICE_HALFDUPLEX 变量
Re: ESP32-DevKitC 开发板 + ESP32-LCDKit + 16位并口屏 st7796
不是,报的设置的频率不符合,我设置
#define BOARD_LCD_SPI_CLOCK_FREQ 80000000
报错信息:
W (338) spi_flash: Detected size(8192k) larger than the size in the binary image header(2048k). Using the size in the binary image header.
I (352) cpu_start: Starting scheduler on PRO CPU.
I (0) cpu_start: Starting scheduler on APP CPU.
I (367) spi_bus: SPI2 bus created
I (371) Board: Board Info: ESP32-LCDKit
I (375) Board: Board Init Done ...
E (380) spi_hal: spi_hal_cal_clock_conf(101): When work in full-duplex mode at frequency > 26.7MHz, device cannot read correct data.
Try to use IOMUX pins to increase the frequency limit, or use the half duplex mode.
Please note the SPI master can only work at divisors of 80MHz, and the driver always tries to find the closest frequency to your configuration.
Specify ``SPI_DEVICE_NO_DUMMY`` to ignore this checking. Then you can output data at higher speed, or read data at your own risk.
E (423) spi_master: spi_bus_add_device(368): assigned clock speed not supported
E (431) spi_bus: D:/esp/esp-iot-solution/components/bus/spi_bus.c:122 (spi_bus_device_create):add spi device failed
E (442) screen interface: D:/esp/esp-iot-solution/components/display/screen/interface_driver/scr_interface_driver.c:180 (spi_lcd_driver_init):spi device initialize failed
E (458) screen interface: D:/esp/esp-iot-solution/components/display/screen/interface_driver/scr_interface_driver.c:306 (scr_interface_create):screen spi interface create failed
E (475) lcd st7789: D:/esp/esp-iot-solution/components/display/screen/controller_driver/st7789/st7789.c:160 (lcd_st7789_init):Interface driver invalid
#define BOARD_LCD_SPI_CLOCK_FREQ 80000000
报错信息:
W (338) spi_flash: Detected size(8192k) larger than the size in the binary image header(2048k). Using the size in the binary image header.
I (352) cpu_start: Starting scheduler on PRO CPU.
I (0) cpu_start: Starting scheduler on APP CPU.
I (367) spi_bus: SPI2 bus created
I (371) Board: Board Info: ESP32-LCDKit
I (375) Board: Board Init Done ...
E (380) spi_hal: spi_hal_cal_clock_conf(101): When work in full-duplex mode at frequency > 26.7MHz, device cannot read correct data.
Try to use IOMUX pins to increase the frequency limit, or use the half duplex mode.
Please note the SPI master can only work at divisors of 80MHz, and the driver always tries to find the closest frequency to your configuration.
Specify ``SPI_DEVICE_NO_DUMMY`` to ignore this checking. Then you can output data at higher speed, or read data at your own risk.
E (423) spi_master: spi_bus_add_device(368): assigned clock speed not supported
E (431) spi_bus: D:/esp/esp-iot-solution/components/bus/spi_bus.c:122 (spi_bus_device_create):add spi device failed
E (442) screen interface: D:/esp/esp-iot-solution/components/display/screen/interface_driver/scr_interface_driver.c:180 (spi_lcd_driver_init):spi device initialize failed
E (458) screen interface: D:/esp/esp-iot-solution/components/display/screen/interface_driver/scr_interface_driver.c:306 (scr_interface_create):screen spi interface create failed
E (475) lcd st7789: D:/esp/esp-iot-solution/components/display/screen/controller_driver/st7789/st7789.c:160 (lcd_st7789_init):Interface driver invalid
Re: ESP32-DevKitC 开发板 + ESP32-LCDKit + 16位并口屏 st7796
在spi中增加 flag SPI_DEVICE_NO_DUMMY可以避免这个错误
Who is online
Users browsing this forum: No registered users and 68 guests