#include #include #include "freertos/FreeRTOS.h" #include "freertos/task.h" #include "esp_timer.h" #include "esp_lcd_panel_io_i80_hub75.h" #include "esp_lcd_panel_ops.h" #include "driver/gpio.h" #include "esp_err.h" #include "esp_log.h" #include "esp_rom_sys.h" static const char *TAG = "led matrix"; #define HUB75_CLOCK_HZ (10 * 1000 * 1000) #define HUB75_MAX_SCAN_TIMES (8) /* 扫描次数是8次,也就是每一行会被扫8次,用于全彩显示 */ #define HUB75_MAX_SCAN_LINE (8) /* 最多扫描行 */ #define HUB75_MAX_TRANSFER_DATA_NUM (128) /* 最多发送128个uint16数据 */ #define HUB75_MAX_TRANSFER_BUTES (HUB75_MAX_TRANSFER_DATA_NUM * 2) #define HUB75_LINE_ADDR_A_PIN_NUM 33 #define HUB75_LINE_ADDR_B_PIN_NUM 34 #define HUB75_LINE_ADDR_C_PIN_NUM 35 #define HUB75_LINE_ADDR_D_PIN_NUM 36 #define HUB75_LAT_PIN_NUM 8 #define HUB75_OE_PIN_NUM 21 #define HUB75_CLK_PIN_NUM 7 #define HUB75_G0 1 #define HUB75_R0 2 #define HUB75_B0 3 #define HUB75_G1 4 #define HUB75_R1 5 #define HUB75_B1 6 #define HUB75_G2 37 #define HUB75_R2 38 #define HUB75_B2 39 #define HUB75_G3 40 #define HUB75_R3 41 #define HUB75_B3 42 #define PSRAM_DATA_ALIGNMENT 64 typedef unsigned char uint8_t; typedef unsigned short int uint16_t; static int line = 0; /* 本次扫描行,32行16扫,一次显示两行 */ esp_lcd_i80_hub75_bus_handle_t i80_bus = NULL; esp_lcd_panel_io_handle_t io_handle = NULL; void led_matrix_i80_hub75_bus_init(void) { /* 8080总线配置 */ ESP_LOGI(TAG, "Initialize Intel 8080 bus"); esp_lcd_i80_hub75_bus_config_t bus_config = { .clk_src = HUB75_CLK_PIN_NUM, .wr_gpio_num = HUB75_CLK_PIN_NUM, .data_gpio_nums = { HUB75_R0, HUB75_G0, HUB75_B0, HUB75_R1, HUB75_G1, HUB75_B1, HUB75_R2, HUB75_G2, HUB75_B2, HUB75_R3, HUB75_G3, HUB75_B3, -1, -1, -1, -1, }, .bus_width = 16, .max_transfer_bytes = HUB75_MAX_TRANSFER_BUTES, /* 每次发一行 */ .max_scan_line = HUB75_MAX_SCAN_LINE, .max_scan_times = HUB75_MAX_SCAN_TIMES, .psram_trans_align = PSRAM_DATA_ALIGNMENT, .sram_trans_align = 4, }; ESP_ERROR_CHECK(esp_lcd_new_i80_hub75_bus(&bus_config, &i80_bus)); /* 8080IO设备申请 */ esp_lcd_panel_io_i80_hub75_config_t io_config = { .cs_gpio_num = -1, .pclk_hz = HUB75_CLOCK_HZ, .trans_queue_depth = 10, .flags = { .pclk_idle_low = 1, }, .on_color_trans_done = NULL, .user_ctx = NULL, .lcd_cmd_bits = 0, .lcd_param_bits = 0, }; ESP_ERROR_CHECK(esp_lcd_new_panel_io_i80_hub75(i80_bus, &io_config, &io_handle)); } void led_matrix_addr_gpio_init(void) { gpio_config_t io_conf = { .mode = GPIO_MODE_OUTPUT, .pin_bit_mask = (1ULL << HUB75_LAT_PIN_NUM) | (1ULL << HUB75_OE_PIN_NUM) | (1ULL << HUB75_LINE_ADDR_A_PIN_NUM) | (1ULL << HUB75_LINE_ADDR_B_PIN_NUM) | (1ULL << HUB75_LINE_ADDR_C_PIN_NUM) | (1ULL << HUB75_LINE_ADDR_D_PIN_NUM), }; ESP_ERROR_CHECK(gpio_config(&io_conf)); } void app_main(void) { led_matrix_i80_hub75_bus_init(); led_matrix_addr_gpio_init(); test_init_buf(i80_bus); while (1) { /* 测试,发送一次数据 */ ESP_LOGI(TAG, "Test send data to LCD"); /* HUB75_COL_COUNT */ int i = 0; hub75_send_line(io_handle, 0, 0); vTaskDelay(pdMS_TO_TICKS(1000)); ESP_LOGI(TAG, "line trans done"); gpio_set_level(HUB75_OE_PIN_NUM, 1); /* 失能显示 */ gpio_set_level(HUB75_LAT_PIN_NUM, 1); /* 锁存拉高 */ vTaskDelay(pdMS_TO_TICKS(1)); gpio_set_level(HUB75_LAT_PIN_NUM, 0); /* 拉低锁存,下降沿锁存 */ gpio_set_level(HUB75_LINE_ADDR_A_PIN_NUM, line & 1); /* 行地址,A是低位(待求证) */ gpio_set_level(HUB75_LINE_ADDR_B_PIN_NUM, (line >> 1) & 1); gpio_set_level(HUB75_LINE_ADDR_C_PIN_NUM, (line >> 2) & 1); gpio_set_level(HUB75_LINE_ADDR_D_PIN_NUM, (line >> 3) & 1); line ++; gpio_set_level(HUB75_OE_PIN_NUM, 0); /* 使能显示 */ vTaskDelay(pdMS_TO_TICKS(1000)); } }