From 919a9ed1a7cb74b70a9fbb8e1d7ca795fa859bfe Mon Sep 17 00:00:00 2001 From: JiXieShi Date: Sat, 21 Sep 2024 12:48:44 +0800 Subject: [PATCH] UP tft SIM --- CMakeLists.txt | 13 +-- demo/lvgl/t_lvgl.h | 10 +++ demo/lvgl/test.c | 29 ++++++ demo/tft/t_tft.h | 4 - demo/tft/test.c | 170 ++++++++++++++++++++++++++++++++---- lib/oled/inc/oled.h | 2 +- lib/tft/inc/tft.h | 11 +++ lib/tft/tft.cpp | 13 ++- main.c | 17 ++-- sim/display/sim_display.cpp | 40 ++++++++- sim/display/sim_display.h | 12 +++ 11 files changed, 279 insertions(+), 42 deletions(-) create mode 100644 demo/lvgl/t_lvgl.h create mode 100644 demo/lvgl/test.c diff --git a/CMakeLists.txt b/CMakeLists.txt index 4d83736..30a6858 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -6,10 +6,12 @@ SET(CMAKE_CXX_FLAGS "-O3") set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++23") set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -std=c99") -file(GLOB DEMO_SUBDIRS "demo/*") -foreach (DEMO_SUBDIR ${DEMO_SUBDIRS}) - include_directories(${DEMO_SUBDIR}) -endforeach () +#file(GLOB DEMO_SUBDIRS "demo/tft/*") +#foreach (DEMO_SUBDIR ${DEMO_SUBDIRS}) +# include_directories(${DEMO_SUBDIR}) +#endforeach () + +include_directories("demo/tft") file(GLOB SIM_SUBDIRS "sim/*") foreach (SIM_SUBDIR ${SIM_SUBDIRS}) @@ -23,7 +25,8 @@ endforeach () include_directories(easyx/include) link_directories(easyx/lib64) -file(GLOB_RECURSE SOURCES "demo/*/*.*" "sim/*/*.*" "lvgl/src/*/*.*" "lvgl/demos/*/*.*") +#file(GLOB_RECURSE SOURCES "demo/*/*.*" "sim/*/*.*" "lvgl/src/*/*.*" "lvgl/demos/*/*.*") +file(GLOB_RECURSE SOURCES "demo/tft/*.*" "sim/*/*.*" "lvgl/src/*/*.*") link_libraries(libeasyx.a libgdi32.a libole32.a) add_executable(HW_Lib main.c ${SOURCES}) diff --git a/demo/lvgl/t_lvgl.h b/demo/lvgl/t_lvgl.h new file mode 100644 index 0000000..ab6f397 --- /dev/null +++ b/demo/lvgl/t_lvgl.h @@ -0,0 +1,10 @@ +// +// Created by lydxh on 2024/5/10. +// + +#ifndef HW_LIB_T_LVGL_H +#define HW_LIB_T_LVGL_H + +void Test_lvgl(); + +#endif //HW_LIB_T_LVGL_H diff --git a/demo/lvgl/test.c b/demo/lvgl/test.c new file mode 100644 index 0000000..6ecabcc --- /dev/null +++ b/demo/lvgl/test.c @@ -0,0 +1,29 @@ +#include "stdio.h" +#include "lv_port_disp.h" +#include "lv_port_indev.h" +#include "lvgl.h" +#include "lv_demo_widgets.h" +#include +#include "t_lvgl.h" + +void Test_lvgl() { + lv_init(); + lv_port_disp_init(); + lv_port_indev_init(); + +// lv_obj_t * bar1 = lv_bar_create(lv_scr_act()); +// lv_obj_set_size(bar1, 200, 20); +// lv_obj_center(bar1); +// lv_bar_set_value(bar1, 70, LV_ANIM_OFF); +// lv_demo_widgets(); +// printf("\nTEST Widgets\n"); + + while (1) { + /* Periodically call the lv_task handler. + * It could be done in a timer interrupt or an OS task too.*/ + lv_timer_handler(); + lv_tick_inc(5); + Sleep(5); + } + +} diff --git a/demo/tft/t_tft.h b/demo/tft/t_tft.h index b4a33a6..789a8e9 100644 --- a/demo/tft/t_tft.h +++ b/demo/tft/t_tft.h @@ -1,7 +1,3 @@ -// -// Created by lydxh on 2024/5/10. -// - #ifndef HW_LIB_T_TFT_H #define HW_LIB_T_TFT_H diff --git a/demo/tft/test.c b/demo/tft/test.c index f9068ad..56bfaa3 100644 --- a/demo/tft/test.c +++ b/demo/tft/test.c @@ -1,28 +1,162 @@ #include "stdio.h" -#include "lv_port_disp.h" -#include "lv_port_indev.h" -#include "lvgl.h" -#include "lv_demo_widgets.h" +#include "tft.h" #include #include "t_tft.h" +#include "sim_display.h" +#include "tool.h" +#include "log.h" + +TFT_T demo_tft; +uint16_t xs = 0, ys = 0, xe = 0, ye = 0; +bool fill; + +//屏幕指令 +#define WGRAM_CMD 0x5C +#define SETXCMD 0x2A +#define SETYCMD 0x2B + +//硬件实现区 +uint8_t tft_writereg(uint8_t reg, uint8_t *pdata, size_t ldata) { + uint8_t result; + fill = false; + Data16_t data16; + if (reg == SETXCMD) { + if (ldata >= 4) { + data16.u8[1] = *pdata; + pdata++; + data16.u8[0] = *pdata; + pdata++; + xs = data16.u16; + data16.u8[1] = *pdata; + pdata++; + data16.u8[0] = *pdata; + xe = data16.u16; + } else if (ldata >= 2) { + data16.u8[1] = *pdata; + pdata++; + data16.u8[0] = *pdata; + xs = data16.u16; + } +// LOGT("SETX","X_S:%d,X_E:%d,len:%d",xs,xe,ldata); + } else if (reg == SETYCMD) { + if (ldata >= 4) { + data16.u8[1] = *pdata; + pdata++; + data16.u8[0] = *pdata; + pdata++; + ys = data16.u16; + + + data16.u8[1] = *pdata; + pdata++; + data16.u8[0] = *pdata; + ye = data16.u16; + } else if (ldata >= 2) { + data16.u8[1] = *pdata; + pdata++; + data16.u8[0] = *pdata; + ys = data16.u16; + } +// LOGT("SETY","Y_S:%d,Y_E:%d,len:%d",ys,ye,ldata); + } else if (reg == WGRAM_CMD) { + fill = true; + } + if (result > 0) { + result = -1; + } else { + result = 0; + } + return result; +} + + +//硬件实现 +uint8_t tft_senddata(uint8_t *data, size_t len) { + uint8_t result; + uint32_t color[len / 2]; + TFT_Color_t color_u; + if (!fill || len == 0)return -1; + if (len == 2) { + color_u.u8[1] = *data; + color_u.u8[0] = *data++; + SIM_Color_DrawPiexl(RGB565_to_RGB888(color_u.u16, true), xs, ys); +// LOGT("Piexl","color:%x,x:%d,y:%d,len:%d",color_u.u16,xs,ys,len); +// SIM_Color_ImgFromBuffer(color,xs, ys, uint16_t width, 1) + } else { + for (int i = 0; i < len / 2; i++) { + color_u.u8[1] = *data; + data++; + color_u.u8[0] = *data; + data++; + color[i] = RGB565_to_RGB888(color_u.u16, true); + } +// SIM_Color_ImgFromBuffer(color, xs, ys, len / 2 - 1, 1); + SIM_Color_DrawHLineBuffer(color, xs, ys, len / 2); +// LOGT("Img","x:%d,y:%d,len:%d",xs,ys,len); + } + + if (result > 0) { + result = -1; + } else { + result = 0; + } + return result; +} void Test_tft() { - lv_init(); - lv_port_disp_init(); - lv_port_indev_init(); -// lv_obj_t * bar1 = lv_bar_create(lv_scr_act()); -// lv_obj_set_size(bar1, 200, 20); -// lv_obj_center(bar1); -// lv_bar_set_value(bar1, 70, LV_ANIM_OFF); -// lv_demo_widgets(); -// printf("\nTEST Widgets\n"); + demo_tft.width = 480; + demo_tft.height = 320; + demo_tft.wgramcmd = WGRAM_CMD; + demo_tft.setycmd = SETYCMD; + demo_tft.setxcmd = SETXCMD; + demo_tft.writeReg = tft_writereg; + demo_tft.sendData = tft_senddata; + demo_tft.dir = HORIZONTAL; + SIM_Display_INIT(demo_tft.width, demo_tft.height, 0xFFFF, 0x0000, 2, 0); + SIM_Display_START(); + +// SIM_Color_DrawPiexl(RGB565_to_RGB888(0xFFFFF),0,0); + Sleep(2000); + TFT_Init(&demo_tft); + TFT_Color_t t; + t.color = 0XFFFF; + TFT_Fill(&demo_tft, 0, 0, demo_tft.width, demo_tft.height, t); + + t.color = 0XFFFF; + TFT_SetColor(0xFFFF, 0x0000); + + TFT_Fill(&demo_tft, 0, 0, demo_tft.width, demo_tft.height, t); + + + TFT_SetColor(0x7D7C, 0x0000); + TFT_DrawRect(&demo_tft, 0, 0, 50, 50); + + + t.color = 0X01CF; + TFT_Fill(&demo_tft, 1, 1, 49, 49, t); + + + TFT_SetColor(0x7D7C, 0x0000); + TFT_ShowCHString(&demo_tft, 0, 60, "星海科技机械师", 1); + + + TFT_DrawCircle(&demo_tft, 25, 25, 10); + + + TFT_DrawCross(&demo_tft, 25, 25, 10); + + + TFT_ShowString(&demo_tft, 60, 20, "JiXieShi", 16, 1); + + + TFT_ShowString(&demo_tft, 0, 160, + "abcdefghigklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ<>(){}[]\\/?.,;:'\"!@#$%^&*-=_+~|", 16, 1); + for (float p = 0; p < 1; p += 0.0001) { + TFT_ShowBar(&demo_tft, 0, 100, demo_tft.width, 24, p); + } + while (1) { - while(1) { - /* Periodically call the lv_task handler. - * It could be done in a timer interrupt or an OS task too.*/ - lv_timer_handler(); - lv_tick_inc(5); Sleep(5); } diff --git a/lib/oled/inc/oled.h b/lib/oled/inc/oled.h index 8d752f0..006f4dc 100644 --- a/lib/oled/inc/oled.h +++ b/lib/oled/inc/oled.h @@ -10,7 +10,7 @@ extern "C" { #define REFRESH_CALL_ENABLE 1 //使用DMA或者整体刷新函数 #define HZK_FONT //使用HZK 12/16 字体 tools下可自由生成 -#define UTF8_TO_UNICODE //启用UTF8转换显示 +//#define UTF8_TO_UNICODE //启用UTF8转换显示 //#define LVGL_FONT //启用LVGL字体 /** diff --git a/lib/tft/inc/tft.h b/lib/tft/inc/tft.h index 59310f8..c8d36d7 100644 --- a/lib/tft/inc/tft.h +++ b/lib/tft/inc/tft.h @@ -348,6 +348,17 @@ void TFT_ShowNum(TFT_T *dev, uint16_t x, uint16_t y, uint32_t num, uint16_t len, **/ void TFT_ShowPic(TFT_T *dev, uint16_t x0, uint16_t y0, uint16_t w, uint16_t h, TFT_Color_t *bmp); +/** + * @brief 在屏幕上绘制一个十字交叉线 + * @param dev: [输入] TFT设备指针 + * @param x: [输入] 十字交叉线中心点x坐标 + * @param y: [输入] 十字交叉线中心点y坐标 + * @param r: [输入] 十字交叉线长度的一半(即从中心点到横竖线的长度) + * @return void + * @example TFT_DrawCross(&tft_dev, 100, 80, 5); +**/ +void TFT_DrawCross(TFT_T *dev, uint16_t x, uint16_t y, uint8_t r); + /** * @brief 在屏幕上显示进度条 * @param dev: [输入] TFT设备指针 diff --git a/lib/tft/tft.cpp b/lib/tft/tft.cpp index 0b5fa11..05f92cf 100644 --- a/lib/tft/tft.cpp +++ b/lib/tft/tft.cpp @@ -14,7 +14,7 @@ #include "ST7796.h" #endif - +const uint8_t initcmd[] = {0}; TFT_Color_t POINT_COLOR; TFT_Color_t BACK_COLOR; uint8_t *cmdIndex; @@ -24,6 +24,7 @@ void TFT_Init(TFT_T *dev) { return; } uint8_t count, temp; + cmdIndex = (uint8_t *) initcmd; #ifdef TFT_ST7735 if (dev->id==ST7735_ID) { cmdIndex= (uint8_t *) st7735initcmd; @@ -440,6 +441,11 @@ void TFT_ShowPic(TFT_T *dev, uint16_t x, uint16_t y, uint16_t width, uint16_t he } } +void TFT_DrawCross(TFT_T *dev, uint16_t x, uint16_t y, uint8_t r) { + TFT_DrawLine(dev, x - r, y, x + r, y); + TFT_DrawLine(dev, x, y - r, x, y + r); +} + uint16_t invertRGB565(uint16_t color) { // 分离颜色分量 uint8_t r = (color >> 11) & 0x1F; // 取出红色分量 @@ -462,13 +468,12 @@ void TFT_ShowBar(TFT_T *dev, uint16_t x, uint16_t y, uint16_t width, uint16_t he if (progress < 1)TFT_Fill(dev, xp, y, width, height, BACK_COLOR); if (height >= 12 && height < 32) { uint8_t tmp[7]; - uint16_t sp = (width - x) / 2 - 30; + uint16_t sp = (width - x) / 2 - 3 * ((height >= 24) ? 24 : (height >= 16) ? 16 : 12) / 2; TFT_Color_t temp = POINT_COLOR; POINT_COLOR.u16 = invertRGB565(POINT_COLOR.u16); - sprintf(tmp, "%05.2f%%", progress * 100); + sprintf((char *) tmp, "%05.2f%%", progress * 100); if (xp < sp)TFT_ShowString(dev, sp, y, tmp, (height >= 24) ? 24 : (height >= 16) ? 16 : 12, 0); else TFT_ShowString(dev, sp, y, tmp, (height >= 24) ? 24 : (height >= 16) ? 16 : 12, 1); POINT_COLOR = temp; - } } diff --git a/main.c b/main.c index b08d0c2..91b21cd 100644 --- a/main.c +++ b/main.c @@ -1,13 +1,14 @@ #include #include #include -#include "t_spi.h" -#include "t_iic.h" -#include "t_task.h" -#include "t_arg.h" -#include "t_list.h" -#include "t_key.h" -#include "t_oled.h" +//#include "t_spi.h" +//#include "t_iic.h" +//#include "t_task.h" +//#include "t_arg.h" +//#include "t_list.h" +//#include "t_key.h" +//#include "t_oled.h" +//#include "t_lvgl.h" #include "t_tft.h" #include "tool.h" #include @@ -29,6 +30,6 @@ int main() { // Test_RunTime("Queue", Test_Queue); // Test_RunTime("Task", Test_task); // Test_RunTime("OLED", Test_OLED); -// Test_RunTime("OLED", Test_tft); + Test_RunTime("TFT", Test_tft); return 0; } diff --git a/sim/display/sim_display.cpp b/sim/display/sim_display.cpp index 677030e..e1f7ad3 100644 --- a/sim/display/sim_display.cpp +++ b/sim/display/sim_display.cpp @@ -9,6 +9,23 @@ uint8_t border; #define GET_BIT(x, bit) ((x & (1 << bit)) >> bit) +uint32_t RGB565_to_RGB888(uint16_t rgb565, bool isBGR) { + uint8_t r5 = (rgb565 >> 11) & 0x1F; + uint8_t g6 = (rgb565 >> 5) & 0x3F; + uint8_t b5 = rgb565 & 0x1F; + + uint8_t r8 = (r5 * 527 + 23) >> 6; + uint8_t g8 = (g6 * 259 + 33) >> 6; + uint8_t b8 = (b5 * 527 + 23) >> 6; + + if (isBGR) { + return (b8 << 16) | (g8 << 8) | r8; + } else { + return (r8 << 16) | (g8 << 8) | b8; + } +} + + void SIM_Display_INIT(int width, int height, uint32_t pixcolor, uint32_t backcolor, int scale, uint8_t b) { w = width * scale; @@ -60,6 +77,25 @@ void SIM_OneColor_DrawFromBuffer(uint8_t* buf, uint16_t width, uint16_t height) EndBatchDraw(); } +void SIM_Color_DrawPiexl(uint32_t buf, uint16_t x, uint16_t y) { + BeginBatchDraw(); +// cleardevice(); + setfillcolor(buf); + drawPixel(x, y); + EndBatchDraw(); +} + +void SIM_Color_DrawHLineBuffer(uint32_t *buf, uint16_t x, uint16_t y, uint16_t width) { + BeginBatchDraw(); +// cleardevice(); + for (int x_ = 0; x_ < width; x_++) { + setfillcolor(*buf); + drawPixel(x + x_, y); + buf++; + } + EndBatchDraw(); +} + void SIM_Color_DrawFromBuffer(uint32_t* buf, uint16_t width, uint16_t height) { BeginBatchDraw(); @@ -79,7 +115,7 @@ void SIM_Color_DrawFromBuffer(uint32_t* buf, uint16_t width, uint16_t height) void SIM_Color_ImgFromBuffer(uint32_t* buf, uint16_t x, uint16_t y, uint16_t width, uint16_t height) { BeginBatchDraw(); - cleardevice(); +// cleardevice(); for (int y_i = 0; y_i < height; y_i++) { for (int x_i = 0; x_i < width; x_i++) @@ -95,7 +131,7 @@ void SIM_Color_ImgFromBuffer(uint32_t* buf, uint16_t x, uint16_t y, uint16_t wid void SIM_Color_FillFromBuffer(uint32_t* buf, uint16_t xs, uint16_t ys, uint16_t xe, uint16_t ye) { BeginBatchDraw(); - cleardevice(); +// cleardevice(); for (int y_i = ys; y_i < ye; y_i++) { for (int x_i = xs; x_i < xe; x_i++) diff --git a/sim/display/sim_display.h b/sim/display/sim_display.h index 73f2ed9..46f7415 100644 --- a/sim/display/sim_display.h +++ b/sim/display/sim_display.h @@ -68,6 +68,16 @@ void SIM_Display_STOP(); **/ void SIM_OneColor_DrawFromBuffer(uint8_t *buf, uint16_t width, uint16_t height); +/** + * @brief 在指定的坐标位置绘制一个像素点 + * @param color 颜色 + * @param x x坐标 + * @param y y坐标 + */ +void SIM_Color_DrawPiexl(uint32_t color, uint16_t x, uint16_t y); + +void SIM_Color_DrawHLineBuffer(uint32_t *buf, uint16_t x, uint16_t y, uint16_t width); + /** * @brief 从缓冲区绘制到显示 * @param buf: [输入] 缓冲区指针 @@ -102,6 +112,8 @@ void SIM_Color_ImgFromBuffer(uint32_t* buf, uint16_t x, uint16_t y, uint16_t wid **/ void SIM_Color_FillFromBuffer(uint32_t* buf, uint16_t xs, uint16_t ys, uint16_t xe, uint16_t ye); +uint32_t RGB565_to_RGB888(uint16_t rgb565, bool isBGR); + #ifdef __cplusplus } #endif