本文介绍了联盛德 WM-IoT-SDK 2. X 工程结合 W803-Pico 板实现 TFT 屏幕驱动的项目设计, 包括原理介绍, 代码解析, 效果展示等.
TFT 彩色液晶屏在日常生活和工作中十分常见且应用广泛, 如便携式显示, 车载显示, 计算机显示 (笔记本电脑, 监视器) , 家电和办公室显示 (电视, 互联网络终端) , 手机, 游戏机, 医疗设备等.
因此了解和学习使用 TFT 显示屏一直是嵌入式开发中的热点话题, 同时驱动 TFT 屏也是考验 MCU 综合性能的极佳指标和参照.
参考: TFT .
GPIO 序号 | 引脚编号 | TFT 引脚 |
---|---|---|
WM_GPIO_NUM_22 | PB6 | CLK (SCL) |
WM_GPIO_NUM_23 | PB7 | MOSI (SDA) |
WM_GPIO_NUM_27 | PB11 | CS |
WM_GPIO_NUM_26 | PB10 | RESET |
WM_GPIO_NUM_25 | PB9 | DC |
WM_GPIO_NUM_24 | PB8 | BLK |
参考: TFT_LCD_DMA — WinnerMicro 在线文档
介绍了 WM-IoT-SDK 2. X 实现 TFT 屏驱动显示的主要流程.
这里我们使用 W803-Pico 开发板驱动 TFT 显示屏, 因此 SoC 选择 W803, 组件 - 外设驱动 - TFT LCD - st7735_spi ;
在相应的文件路径下打开例程 wm_iot_sdk/examples/peripheral/tft_lcd/tft_lcd_dma
, 右键 menuconfig
配置 SoC (W803) 和 LCD Device (st7735_spi) ;
右键 build 构建工程, 点击 flash 并选择开发板串口对应的端口号, 实现固件上传.
#include "stdio. h"
#include "wmsdk_config. h"
#include "freertos/FreeRTOS. h"
#include "freertos/task. h"
#include "freertos/semphr. h"
#include "wm_drv_tft_lcd. h"
#include "wm_drv_sdh_spi. h"
#include "picture. h"
#include "wm_utils. h"
#define LOG_TAG "lcd_example"
#include "wm_log. h"
static void wm_lcd_demo (void *arg)
{
int ret = WM_ERR_FAILED;
int id = 0;
wm_device_t *dev = NULL;
image_attr_t img = { 0 };
uint8_t *app_buf = NULL;
uint32_t block_size = 0;
uint16_t width = 0, high = 0;
wm_lcd_capabilitys_t cap = { 0 };
lcd_demo_sem = xSemaphoreCreateCounting (1, 1) ;
/*TODO: add more initial methods for other interfaces (like RGB/MIPI. . . ) in future on new chip*/
/*use sdio (spi mode) for lcd demo as it's support high speed */
dev = wm_drv_sdh_spi_init (LCD_SPI_CONTROLLER_DEVICE_NAME) ;
if (dev == NULL) {
wm_log_error ("init sdspi fail. ") ;
}
/* initial the lcd device, and use the same device name which defined in device table*/
dev = wm_drv_tft_lcd_init (LCD_DEVICE_NAME) ;
if (dev == NULL) {
wm_log_info ("init lcd fail. ") ;
}
/* turn on the backlight*/
ret = wm_drv_tft_lcd_set_backlight (dev, true) ;
if (ret ! = WM_ERR_SUCCESS) {
wm_log_info ("lcd bl set fail. ") ;
}
/* show LCD capability */
wm_drv_tft_lcd_get_capability (dev, &cap) ;
wm_log_info ("LCD x_resolution = %d", cap. x_resolution) ;
wm_log_info ("LCD y_resolution = %d", cap. y_resolution) ;
wm_log_info ("LCD rotation = %d\n", cap. rotation) ;
//NOTE: when color mode change , the byte width could be adjusted too.
/* malloc an application buffer to refresh the screen*/
width = cap. x_resolution;
high = cap. y_resolution;
block_size = (LCD_DATA_DRAW_LINE_UNIT * width * WM_CFG_TFT_LCD_PIXEL_WIDTH) ;
wm_log_info ("DEMO: block_size=%d", block_size) ;
app_buf = malloc (block_size) ;
if (app_buf == NULL) {
wm_log_error ("mem err\n") ;
}
/* set image and the image width, height depend on selected LCD device */
#if CONFIG_COMPONENT_DRIVER_LCD_NV3041A_SPI
img. image_buf = image_bluesky_480x272;
img. image_width = 480;
img. image_high = 272;
#else
img. image_buf = gImage_pic_winner_micro_logo_93x93;
img. image_width = 93;
img. image_high = 93;
#endif
if (img. image_width " width || img. image_high " high) {
wm_log_error ("image unmatch") ;
}
/* Registers a callback function that gets triggered after the transmission of a bitmap is complete */
ret = wm_drv_tft_lcd_register_tx_callback (dev, lcd_demo_tx_cb, NULL) ;
if (ret ! = WM_ERR_SUCCESS) {
wm_log_info ("register tx callback error (%d) ", ret) ;
}
while (1) {
/* demo scenario 1 - show blue screen by dma*/
wm_log_info ("wm_lcd_demo show blue background") ;
ret = lcd_demo_clean_screen_with_dma (dev, app_buf, block_size, LCD_RGB565_BLUE) ;
if (ret ! = WM_ERR_SUCCESS) {
wm_log_info ("wm_lcd_demo_show_image ret=%d", ret) ;
}
vTaskDelay (pdMS_TO_TICKS (2000) ) ;
/* demo scenario 2 - rotation the image once lcd_demo_show_image () be invoked*/
if (id++ % 2) {
ret = wm_drv_tft_lcd_set_rotation (dev, LCD_ROTATION_NONE) ;
} else {
ret = wm_drv_tft_lcd_set_rotation (dev, LCD_ROTATION_180_DEGREE) ;
}
/* demo scenario 3 - show image by dma*/
wm_log_info ("wm_lcd_demo show image (w=%d, h=%d) ", img. image_width, img. image_high) ;
ret = lcd_demo_show_image_with_dma (dev, app_buf, block_size, img) ;
if (ret ! = WM_ERR_SUCCESS) {
wm_log_info ("wm_lcd_demo_show_image ret=%d", ret) ;
}
vTaskDelay (pdMS_TO_TICKS (2000) ) ;
}
free (app_buf) ;
vSemaphoreDelete ( (QueueHandle_t) lcd_demo_sem) ;
vTaskDelete (NULL) ;
}
int main (void)
{
xTaskCreate (wm_lcd_demo, "wm_lcd_demo_task", WM_LCD_TFT_DEMO_TASK_STACK, NULL, WM_LCD_TFT_DEMO_TASK_PRIO, NULL) ;
return 0;
}
动态
这里介绍修改工程, 添加并实现自定义图片的 TFT 显示.
这里使用 PowerPoint 绘制图文, 另存为 BMP 格式图片;
打开 Image2LCD
软件, 导入目标图片, 配置相关参数 (注意勾选 高位在前
选项) , 输出 . h
格式文件;
将取模文件存放至主函数同一文件夹, 在 picture. h
中增加取模文件 #include "pic_wm. h"
修改 void wm_lcd_demo
函数中关于图片数组的调用信息
img. image_buf = gImage_wm; // target picture array name
img. image_width = 93;
img. image_high = 93;
保存文件, 编译工程, 上传固件.
动态
本文介绍了联盛德 WM-IoT-SDK 2. X 工程 Demo 结合 W803-Pico 板实现 TFT 屏幕驱动的项目设计, 包括原理介绍, 硬件连接, 工程测试, 代码调试, 自定义效果展示等, 采用 DMA 硬件 SPI 驱动显示屏, 刷新速度快, 延迟低, 显示质量佳, 为相关驱动开发和显示屏的应用提供了参考.