From 39654926bed1c0d6bda6ff65a4fd035788939fff Mon Sep 17 00:00:00 2001 From: JiXieShi Date: Tue, 17 Sep 2024 16:32:06 +0800 Subject: [PATCH] UP tft form st7796 --- lib/font/font.cpp | 2 +- lib/font/inc/{font.h => font_t.h} | 4 +- lib/oled/oled.cpp | 2 +- lib/tft/inc/ST7735.h | 131 ++++++------ lib/tft/inc/ST7796.h | 190 ++++++++++++++++++ lib/tft/inc/tft.h | 286 ++++++++++++++++++++++---- lib/tft/tft.cpp | 324 +++++++++++++++++------------- 7 files changed, 701 insertions(+), 238 deletions(-) rename lib/font/inc/{font.h => font_t.h} (95%) create mode 100644 lib/tft/inc/ST7796.h diff --git a/lib/font/font.cpp b/lib/font/font.cpp index 1cda69c..8f332ba 100644 --- a/lib/font/font.cpp +++ b/lib/font/font.cpp @@ -1,6 +1,6 @@ #include "lvgl_font.h" -#include "font.h" +#include "font_t.h" uint8_t Font_utf8_to_unicode(uint8_t *pInput, uint32_t *unicode_letter) { uint8_t outputSize = 0; diff --git a/lib/font/inc/font.h b/lib/font/inc/font_t.h similarity index 95% rename from lib/font/inc/font.h rename to lib/font/inc/font_t.h index af67866..495d245 100644 --- a/lib/font/inc/font.h +++ b/lib/font/inc/font_t.h @@ -1,8 +1,8 @@ #pragma once -#ifndef HW_LIB_FONT_H -#define HW_LIB_FONT_H +#ifndef HW_LIB_FONT_T_H +#define HW_LIB_FONT_T_H #ifdef __cplusplus extern "C" { diff --git a/lib/oled/oled.cpp b/lib/oled/oled.cpp index 3cc13a3..524948d 100644 --- a/lib/oled/oled.cpp +++ b/lib/oled/oled.cpp @@ -263,7 +263,7 @@ void OLED_ShowCHChr(OLED_T *dev, uint8_t x, uint8_t y, Chinese_t *hzk) { #ifdef UTF8_TO_UNICODE -#include "font.h" +#include "font_t.h" #define GET_LOW_BYTE0(x) ((x >> 0) & 0x000000ff) /* 获取第0个字节 */ #define GET_LOW_BYTE1(x) ((x >> 8) & 0x000000ff) /* 获取第1个字节 */ diff --git a/lib/tft/inc/ST7735.h b/lib/tft/inc/ST7735.h index f46d981..272a952 100644 --- a/lib/tft/inc/ST7735.h +++ b/lib/tft/inc/ST7735.h @@ -102,10 +102,10 @@ extern "C" { * @brief LCD_OrientationTypeDef * Possible values of Display Orientation */ -#define ST7735_ORIENTATION_PORTRAIT 0x00U /* Portrait orientation choice of LCD screen */ -#define ST7735_ORIENTATION_PORTRAIT_ROT180 0x01U /* Portrait rotated 180° orientation choice of LCD screen */ -#define ST7735_ORIENTATION_LANDSCAPE 0x02U /* Landscape orientation choice of LCD screen */ -#define ST7735_ORIENTATION_LANDSCAPE_ROT180 0x03U /* Landscape rotated 180° orientation choice of LCD screen */ +#define ST7735_ORIENTATION_PORTRAIT 0x00U /* 液晶屏纵向选择 */ +#define ST7735_ORIENTATION_PORTRAIT_ROT180 0x01U /* 纵向旋转 180° 方向 液晶屏选择 */ +#define ST7735_ORIENTATION_LANDSCAPE 0x02U /* 液晶屏横向选择 */ +#define ST7735_ORIENTATION_LANDSCAPE_ROT180 0x03U /* 横向旋转 180° 方向 液晶屏选择 */ /** * @brief Possible values of pixel data format (ie color coding) @@ -130,42 +130,36 @@ extern "C" { /** * @brief LCD RGB or BGR */ -#define LCD_RGB 0x00U -#define LCD_BGR 0x08U +#define ST7735_RGB 0x00U +#define ST7735_BGR 0x08U -#define TFT_DELAY 120 -#define TFT_PANEL HannStar_Panel -#define TFT_TYPE ST7735_0_9_inch_screen +#define ST7735_DELAY 120 +#define ST7735_PANEL HannStar_Panel +#define ST7735_TYPE ST7735_0_9_inch_screen -#if TFT_TYPE == ST7735_0_9_inch_screen //0.96 ST7735 -#if TFT_PANEL == HannStar_Panel -#define TFT_X_OFFSET 26 -#define TFT_Y_OFFSET 1 +#if ST7735_TYPE == ST7735_0_9_inch_screen //0.96 ST7735 +#if ST7735_PANEL == HannStar_Panel +#define ST7735_X_OFFSET 26 +#define ST7735_Y_OFFSET 1 #else //BOE Panel -#define TFT_X_OFFSET 24 -#define TFT_Y_OFFSET 0 +#define ST7735_X_OFFSET 24 +#define ST7735_Y_OFFSET 0 #endif #endif -#if TFT_TYPE == ST7735_1_8a_inch_screen -#if TFT_PANEL == BOE_Panel -#define TFT_X_OFFSET 2 -#define TFT_Y_OFFSET 1 +#if ST7735_TYPE == ST7735_1_8a_inch_screen +#if ST7735_PANEL == BOE_Panel +#define ST7735_X_OFFSET 2 +#define ST7735_Y_OFFSET 1 #endif #endif -#define TFT_XPOS_CMD ST7735_CASET -#define TFT_YPOS_CMD ST7735_RASET -#define TFT_DIR_CMD ST7735_MADCTL -#define TFT_WRITE_RAM ST7735_WRITE_RAM -#define TFT_READ_RAM ST7735_READ_RAM - -#if TFT_PANEL == HannStar_Panel -#define DIR_MASK(dir) (uint8_t)OrientationTab[dir][1] | LCD_BGR; +#if ST7735_PANEL == HannStar_Panel +#define ST7735_DIR_MASK(dir) st7735dirTab[dir][1] | ST7735_BGR; #else -#define DIR_MASK(dir) (uint8_t)OrientationTab[dir][1] | LCD_RGB; +#define ST7735_DIR_MASK(dir) st7735dirTab[dir][1] | ST7735_RGB; #endif const uint8_t st7735initcmd[] = { @@ -192,7 +186,7 @@ const uint8_t st7735initcmd[] = { 2, ST7735_DISPLAY_OFF, 0x00, 2, ST7735_DISPLAY_ON, 0x00 }; -const uint32_t OrientationTab[4][2] = +const uint8_t st7735dirTab[4][2] = { {0x40U, 0xC0U}, /* 液晶屏纵向选择 */ {0x80U, 0x00U}, /* 液晶屏纵向旋转 180° 方向选择 */ @@ -200,20 +194,17 @@ const uint32_t OrientationTab[4][2] = {0xE0U, 0xA0U}, /* 液晶屏横向旋转 180° 方向选择 */ }; -#define ST7735_ReadID(dev, Id) do{\ - uint8_t tmp[3] = {ST7735_READ_ID1, ST7735_READ_ID2, ST7735_READ_ID3};\ - dev->cmd(&tmp[0],1);\ - dev->read( &tmp[0], 1);\ - dev->cmd(&tmp[1],1);\ - dev->read( &tmp[1], 1);\ - dev->cmd(&tmp[2],1);\ - dev->read( &tmp[2], 1);\ - Id = ((uint32_t) tmp[2]) << 0 | ((uint32_t) tmp[1]) << 8 | ((uint32_t) tmp[0]) << 16;\ +#define ST7735_ReadID(dev, id) do{\ + if (dev->id==ST7735_ID){ \ + uint8_t tmp[3] = {};\ + dev->writeReg(ST7735_READ_ID1,&tmp[0],1);\ + dev->writeReg(ST7735_READ_ID2,&tmp[1],1);\ + dev->writeReg(ST7735_READ_ID3,&tmp[2],1);\ + id = ((uint32_t) tmp[2]) << 0 | ((uint32_t) tmp[1]) << 8 | ((uint32_t) tmp[0]) << 16;}\ }while(0) - - -#if TFT_TYPE == ST7735_0_9_inch_screen -#define ST7735_SetDir(dev, dir) do{\ +#if ST7735_TYPE == ST7735_0_9_inch_screen +#define ST7735_SetDir(dev, dir) do{\ + if (dev->id==ST7735_ID){ \ if((dir == ST7735_ORIENTATION_PORTRAIT) || (dir == ST7735_ORIENTATION_PORTRAIT_ROT180))\ {\ dev->width = ST7735_0_9_WIDTH;\ @@ -223,24 +214,50 @@ const uint32_t OrientationTab[4][2] = {\ dev->width = ST7735_0_9_HEIGHT;\ dev->height = ST7735_0_9_WIDTH;\ + } \ + tmp = ST7735_DIR_MASK(dir);\ + dev->writeReg(ST7735_MADCTL,&tmp,1);} \ +}while(0) +#endif +#if ST7735_TYPE == ST7735_1_8_inch_screen || ST7735_TYPE == ST7735_1_8a_inch_screen +#define ST7735_SetDir(dev,dir) do{\ + if (dev->id==ST7735_ID){\ + if((dir == ST7735_ORIENTATION_PORTRAIT) || (dir == ST7735_ORIENTATION_PORTRAIT_ROT180))\ + {\ + dev->width = ST7735_1_8_WIDTH;\ + dev->height = ST7735_1_8_HEIGHT;\ }\ -}while(0); -#endif -#if TFT_TYPE == ST7735_1_8_inch_screen || TFT_TYPE == ST7735_1_8a_inch_screen -inline void ST7735_SetDir(TFT_T *dev,TFT_DIR_T dir){ - if((dir == ST7735_ORIENTATION_PORTRAIT) || (dir == ST7735_ORIENTATION_PORTRAIT_ROT180)) - { - dev->width = ST7735_1_8_WIDTH; - dev->height = ST7735_1_8_HEIGHT; - } - else - { - dev->width = ST7735_1_8_HEIGHT; - dev->height = ST7735_1_8_WIDTH; - } -} + else\ + {\ + dev->width = ST7735_1_8_HEIGHT;\ + dev->height = ST7735_1_8_WIDTH;\ + }\ + }\ +}while(0) #endif +#define ST7735_OFFSET(dev, x, y) do{ \ + if (dev->id==ST7735_ID){\ + if (dev->dir <= LONGITUDINAL_180) { \ + x += ST7735_X_OFFSET;\ + y += ST7735_Y_OFFSET;\ + } else {\ + x += ST7735_Y_OFFSET;\ + y += ST7735_X_OFFSET;\ + }\ + }\ +}while(0) + +#define ST7735_ReadRam(dev, rec) do{ \ + if(dev->id==ST7735_ID){ \ + dev->readReg(ST7735_READ_RAM,&tmp,1);\ + dev->recvData(&tmp,1);\ + dev->recvData(&pixel_lsb,1);\ + dev->recvData(&pixel_msb,1);\ + rec.color=((uint32_t)(pixel_lsb)) + ((uint32_t)(pixel_msb) << 8);\ + }\ +}while(0) + #ifdef __cplusplus } #endif diff --git a/lib/tft/inc/ST7796.h b/lib/tft/inc/ST7796.h new file mode 100644 index 0000000..4f9ff0d --- /dev/null +++ b/lib/tft/inc/ST7796.h @@ -0,0 +1,190 @@ +#ifndef HW_LIB_ST7796_H +#define HW_LIB_ST7796_H +#ifdef __cplusplus +extern "C" { +#endif +#include + +/** + * @brief ST7796 Registers + */ +#define ST7796_NOP 0x00U /* No Operation: NOP */ +#define ST7796_SW_RESET 0x01U /* Software reset: SWRESET */ +#define ST7796_READ_ID 0x04U /* Read Display ID: RDDID */ +#define ST7796_READ_STATUS 0x09U /* Read Display Statu: RDDST */ +#define ST7796_READ_POWER_MODE 0x0AU /* Read Display Power: RDDPM */ +#define ST7796_READ_MADCTL 0x0BU /* Read Display: RDDMADCTL */ +#define ST7796_READ_PIXEL_FORMAT 0x0CU /* Read Display Pixel: RDDCOLMOD */ +#define ST7796_READ_IMAGE_MODE 0x0DU /* Read Display Image: RDDIM */ +#define ST7796_READ_SIGNAL_MODE 0x0EU /* Read Display Signal: RDDSM */ +#define ST7796_SLEEP_IN 0x10U /* Sleep in & booster off: SLPIN */ +#define ST7796_SLEEP_OUT 0x11U /* Sleep out & booster on: SLPOUT */ +#define ST7796_PARTIAL_DISPLAY_ON 0x12U /* Partial mode on: PTLON */ +#define ST7796_NORMAL_DISPLAY_OFF 0x13U /* Partial off (Normal): NORON */ +#define ST7796_DISPLAY_INVERSION_OFF 0x20U /* Display inversion off: INVOFF */ +#define ST7796_DISPLAY_INVERSION_ON 0x21U /* Display inversion on: INVON */ +#define ST7796_GAMMA_SET 0x26U /* Gamma curve select: GAMSET */ +#define ST7796_DISPLAY_OFF 0x28U /* Display off: DISPOFF */ +#define ST7796_DISPLAY_ON 0x29U /* Display on: DISPON */ +#define ST7796_CASET 0x2AU /* Column address set: CASET */ +#define ST7796_RASET 0x2BU /* Row address set: RASET */ +#define ST7796_WRITE_RAM 0x2CU /* Memory write: RAMWR */ +#define ST7796_RGBSET 0x2DU /* LUT for 4k,65k,262k color: RGBSET */ +#define ST7796_READ_RAM 0x2EU /* Memory read: RAMRD */ +#define ST7796_PTLAR 0x30U /* Partial start/end address set: PTLAR */ +#define ST7796_TE_LINE_OFF 0x34U /* Tearing effect line off: TEOFF */ +#define ST7796_TE_LINE_ON 0x35U /* Tearing effect mode set & on: TEON */ +#define ST7796_MADCTL 0x36U /* Memory data access control: MADCTL */ +#define ST7796_IDLE_MODE_OFF 0x38U /* Idle mode off: IDMOFF */ +#define ST7796_IDLE_MODE_ON 0x39U /* Idle mode on: IDMON */ +#define ST7796_COLOR_MODE 0x3AU /* Interface pixel format: COLMOD */ +#define ST7796_FRAME_RATE_CTRL1 0xB1U /* In normal mode (Full colors): FRMCTR1 */ +#define ST7796_FRAME_RATE_CTRL2 0xB2U /* In Idle mode (8-colors): FRMCTR2 */ +#define ST7796_FRAME_RATE_CTRL3 0xB3U /* In partial mode + Full colors: FRMCTR3 */ +#define ST7796_FRAME_INVERSION_CTRL 0xB4U /* Display inversion control: INVCTR */ +#define ST7796_DISPLAY_SETTING 0xB6U /* Display function setting */ +#define ST7796_ENTRY_MODE_SET 0xB7U /* Entry Mode Set: EM */ +#define ST7796_PWR_CTRL1 0xC0U /* Power control setting: PWCTR1 */ +#define ST7796_PWR_CTRL2 0xC1U /* Power control setting: PWCTR2 */ +#define ST7796_PWR_CTRL3 0xC2U /* In normal mode (Full colors): PWCTR3 */ +#define ST7796_PWR_CTRL4 0xC3U /* In Idle mode (8-colors): PWCTR4 */ +#define ST7796_PWR_CTRL5 0xC4U /* In partial mode + Full colors: PWCTR5 */ +#define ST7796_VCOMH_VCOML_CTRL1 0xC5U /* VCOM control 1: VMCTR1 */ +#define ST7796_VMOF_CTRL 0xC7U /* Set VCOM offset control: VMOFCTR */ +#define ST7796_WRID2 0xD1U /* Set LCM version code: WRID2 */ +#define ST7796_WRID3 0xD2U /* Customer Project code: WRID3 */ +#define ST7796_NV_CTRL1 0xD9U /* NVM control status: NVCTR1 */ +#define ST7796_READ_ID1 0xDAU /* Read ID1: RDID1 */ +#define ST7796_READ_ID2 0xDBU /* Read ID2: RDID2 */ +#define ST7796_READ_ID3 0xDCU /* Read ID3: RDID3 */ +#define ST7796_READ_ID4 0xD3U /* Read ID4: RDID4 */ +#define ST7796_NV_CTRL2 0xDEU /* NVM Read Command: NVCTR2 */ +#define ST7796_NV_CTRL3 0xDFU /* NVM Write Command: NVCTR3 */ +#define ST7796_PV_GAMMA_CTRL 0xE0U /* Set Gamma adjustment (+ polarity): GAMCTRP1 */ +#define ST7796_NV_GAMMA_CTRL 0xE1U /* Set Gamma adjustment (- polarity): GAMCTRN1 */ +#define ST7796_DISPLAY_OUTPUT_CTRL_ADJUST 0xE8U /* Display Output Ctrl Adjust: DOCA */ +#define ST7796_EXT_CTRL 0xF0U /* Extension command control */ +#define ST7796_PWR_CTRL6 0xFCU /* In partial mode + Idle mode: PWCTR6 */ +#define ST7796_VCOM4_LEVEL 0xFFU /* VCOM 4 level control */ + +/** + * @brief ST7735 ID + */ +#define ST7796_ID 0xACU + +/** + * @brief ST7735 4.0 inch Size + */ +#define ST7796_4_0_WIDTH 320U +#define ST7796_4_0_HEIGHT 480U + +/** + * @brief LCD_OrientationTypeDef + * Possible values of Display Orientation + */ +#define ST7796_ORIENTATION_PORTRAIT 0x00U /* 液晶屏纵向选择 */ +#define ST7796_ORIENTATION_PORTRAIT_ROT180 0x01U /* 纵向旋转 180° 方向 液晶屏选择 */ +#define ST7796_ORIENTATION_LANDSCAPE 0x02U /* 液晶屏横向选择 */ +#define ST7796_ORIENTATION_LANDSCAPE_ROT180 0x03U /* 横向旋转 180° 方向 液晶屏选择 */ + +/** + * @brief Possible values of pixel data format (ie color coding) + */ +#define ST7796_FORMAT_RBG444 0x03U /* Pixel format chosen is RGB444 : 12 bpp */ +#define ST7796_FORMAT_RBG565 0x55U /* Pixel format chosen is RGB565 : 16 bpp */ +#define ST7796_FORMAT_RBG666 0x06U /* Pixel format chosen is RGB666 : 18 bpp */ +#define ST7796_FORMAT_DEFAULT ST7796_FORMAT_RBG565 + + +/** + * @brief LCD RGB or BGR + */ +#define ST7796_RGB 0x00U +#define ST7796_BGR 0x08U + +#define ST7796_X_OFFSET 0 +#define ST7796_Y_OFFSET 0 + +#define ST7796_DIR_MASK(dir) st7796dirTab[dir][0] | ST7796_BGR + +const uint8_t st7796dirTab[4][2] = + { + {0x40U, 0xC0U}, /* 液晶屏纵向选择 */ + {0x80U, 0x00U}, /* 液晶屏纵向旋转 180° 方向选择 */ + {0x20U, 0x60U}, /* 液晶屏横向选择 */ + {0xE0U, 0xA0U}, /* 液晶屏横向旋转 180° 方向选择 */ + }; + +const uint8_t st7796initcmd[] = { + 0x81, ST7796_SW_RESET, + 0x81, ST7796_SW_RESET, + 2, ST7796_SLEEP_OUT, 0x00, + 2, ST7796_EXT_CTRL, 0xc3, + 2, ST7796_EXT_CTRL, 0x96, + 2, ST7796_MADCTL, 0x48, + 2, ST7796_COLOR_MODE, ST7796_FORMAT_DEFAULT, + 2, ST7796_FRAME_INVERSION_CTRL, 0x01, + 2, ST7796_ENTRY_MODE_SET, 0xC6, + 9, ST7796_DISPLAY_OUTPUT_CTRL_ADJUST, 0x40, 0x8a, 0x00, 0x00, 0x29, 0x19, 0xa5, 0x33, + 2, ST7796_PWR_CTRL2, 0x06, + 2, ST7796_PWR_CTRL3, 0xa7, + 2, ST7796_VCOMH_VCOML_CTRL1, 0x18, + 15, ST7796_PV_GAMMA_CTRL, 0xf0, 0x09, 0x0b, 0x06, 0x04, 0x15, 0x2f, 0x54, 0x42, 0x3c, 0x17, 0x14, 0x18, 0x1b, + 15, ST7796_NV_GAMMA_CTRL, 0xf0, 0x09, 0x0b, 0x06, 0x04, 0x03, 0x2d, 0x43, 0x42, 0x3b, 0x16, 0x14, 0x17, 0x1b, + 2, ST7796_EXT_CTRL, 0x3c, + 2, ST7796_EXT_CTRL, 0x69, + 0x81, ST7796_DISPLAY_INVERSION_ON, + 0x81, ST7796_DISPLAY_ON, + 0x00 +}; + +#define ST7796_ReadID(dev, id) do{\ + if (dev->id==ST7796_ID){ \ + uint8_t tmp[3] = {};\ + dev->writeReg(ST7796_READ_ID1,&tmp[0],1);\ + dev->writeReg(ST7796_READ_ID2,&tmp[1],1);\ + dev->writeReg(ST7796_READ_ID3,&tmp[2],1);\ + id = ((uint32_t) tmp[2]) << 0 | ((uint32_t) tmp[1]) << 8 | ((uint32_t) tmp[0]) << 16;}\ +}while(0) + +#define ST7796_SetDir(dev, dir) do{\ + if (dev->id==ST7796_ID){ \ + if((dir == ST7796_ORIENTATION_PORTRAIT) || (dir == ST7796_ORIENTATION_PORTRAIT_ROT180))\ + {\ + dev->width = ST7796_4_0_WIDTH;\ + dev->height = ST7796_4_0_HEIGHT;\ + }\ + else\ + {\ + dev->width = ST7796_4_0_HEIGHT;\ + dev->height = ST7796_4_0_WIDTH;\ + } \ + tmp = ST7796_DIR_MASK(dir);\ + dev->writeReg(ST7796_MADCTL,&tmp,1);} \ +}while(0) + +#define ST7796_OFFSET(dev, x, y) do{ \ + if (dev->id==ST7735_ID){\ + if (dev->dir <= LONGITUDINAL_180) { \ + x += ST7796_X_OFFSET;\ + y += ST7796_Y_OFFSET;\ + } else {\ + x += ST7796_Y_OFFSET;\ + y += ST7796_X_OFFSET;\ + }\ + }\ +}while(0) + +#define ST7796_ReadRam(dev, rec) do{ \ + if(dev->id==ST7796_ID){ \ + dev->readReg(ST7796_READ_RAM,&tmp,1);\ + dev->recvData(&tmp,1);\ + dev->recvData(&pixel_lsb,1);\ + dev->recvData(&pixel_msb,1);\ + rec.color=((uint32_t)(pixel_lsb)) + ((uint32_t)(pixel_msb) << 8);\ + }\ +}while(0) +#ifdef __cplusplus +} +#endif +#endif //HW_LIB_ST7796_H diff --git a/lib/tft/inc/tft.h b/lib/tft/inc/tft.h index ddf44f0..cab44cd 100644 --- a/lib/tft/inc/tft.h +++ b/lib/tft/inc/tft.h @@ -3,43 +3,30 @@ #ifdef __cplusplus extern "C" { #endif + +#include #include "stdint.h" #include "stdlib.h" -#define REFRESH_CALL_ENABLE 1 //使用DMA或者整体刷新函数 +//#define REFRESH_CALL_ENABLE 1 //使用DMA或者整体刷新函数 #define HZK_FONT //使用HZK 12/16 字体 tools下可自由生成 #define UTF8_TO_UNICODE //启用UTF8转换显示 //#define LVGL_FONT //启用LVGL字体 -#define TFT_ST7735 - +#define TFT_ST7735 0x5CU +#define TFT_ST7796 0xACU typedef struct TFT_Dev TFT_T; -/** - * @brief TFT命令处理函数指针类型 - * @param data: [输入] 数据指针 - * @param len: [输入] 数据长度 - * @return uint8_t 返回值 - */ -typedef uint8_t (*TFT_CMD_t)(uint8_t *data, size_t len); -/** - * @brief TFT数据处理函数指针类型 - * @param data: [输入] 数据指针 - * @param len: [输入] 数据长度 - * @return uint8_t 返回值 - */ -typedef uint8_t (*TFT_DATA_t)(uint8_t *data, size_t len); +typedef uint8_t (*TFT_WRITE_REG_t)(uint8_t reg, uint8_t *pdata, size_t ldata); -/** - * @brief TFT数据读取函数指针类型 - * @param data: [输出] 数据指针 - * @param len: [输入] 数据长度 - * @return uint8_t 返回值 - */ -typedef uint8_t (*TFT_READ_t)(uint8_t *data, size_t len); +typedef uint8_t (*TFT_READ_REG_t)(uint8_t reg, uint8_t *pdata, size_t ldata); + +typedef uint8_t (*TFT_SEND_DATA_t)(uint8_t *data, size_t len); + +typedef uint8_t (*TFT_RECV_DATA_t)(uint8_t *data, size_t len); /** * @brief TFT背光控制函数指针类型 @@ -53,7 +40,7 @@ typedef uint8_t (*TFT_BLACKLIGHT_t)(uint8_t data); * @param ms: [输入] 毫秒延迟 * @return uint8_t 返回值 */ -typedef uint8_t (*TFT_DELAY_t)(uint32_t ms); +typedef void (*TFT_DELAY_t)(uint32_t ms); #if REFRESH_CALL_ENABLE @@ -68,13 +55,14 @@ typedef void (*TFT_REFRESH_t)(TFT_T *dev); * @brief TFT状态枚举 */ typedef enum { - IDLE, /**< 空闲状态 */ - WRITE, /**< 写入状态 */ - REFRESH, /**< 刷新状态 */ + TFT_ERROR, + TFT_IDLE, /**< 空闲状态 */ + TFT_WRITE, /**< 写入状态 */ + TFT_REFRESH, /**< 刷新状态 */ } TFT_STATE_T; typedef enum { - LONGITUDINAL,/* 液晶屏纵向选择 */ + LONGITUDINAL = 0x01U,/* 液晶屏纵向选择 */ LONGITUDINAL_180,/* 液晶屏纵向旋转 180° 方向选择 */ HORIZONTAL,/* 液晶屏横向选择 */ HORIZONTAL_180,/* 液晶屏横向旋转 180° 方向选择 */ @@ -90,29 +78,244 @@ typedef union TFT_Color { * @brief TFT设备结构体 */ struct TFT_Dev { - TFT_DIR_T dir: 4; /**< 显示方向 */ - TFT_STATE_T state: 4; /**< TFT状态 */ + uint32_t id; + uint8_t setxcmd; + uint8_t setycmd; + uint8_t wgramcmd; + TFT_DIR_T dir: 4; /**< 显示方向,占4位 */ + TFT_STATE_T state: 4; /**< TFT状态,占4位 */ uint16_t width; /**< 显示宽度 */ uint16_t height; /**< 显示高度 */ - TFT_CMD_t cmd; /**< TFT命令处理函数指针 */ - TFT_DATA_t data; /**< TFT数据处理函数指针 */ - TFT_READ_t read; /**< TFT数据读取函数指针 */ + TFT_WRITE_REG_t writeReg; /**< 写寄存器函数指针 */ + TFT_READ_REG_t readReg; /**< 读寄存器函数指针 */ + TFT_SEND_DATA_t sendData; /**< 发送数据函数指针 */ + TFT_RECV_DATA_t recvData; /**< 接收数据函数指针 */ TFT_BLACKLIGHT_t blacklight; /**< TFT背光控制函数指针 */ TFT_DELAY_t delay; /**< TFT延迟函数指针类型 */ #if REFRESH_CALL_ENABLE - TFT_REFRESH_t call; /**< TFT刷新函数指针 */ + TFT_REFRESH_t call; /**< TFT刷新函数指针,仅在REFRESH_CALL_ENABLE宏定义启用时有效 */ #endif }; +/** + * @brief 初始化TFT显示屏 + * @param dev: [输入] TFT设备结构体指针 + * @return void + * @example TFT_Init(&myTFT); +**/ +void TFT_Init(TFT_T *dev); -extern TFT_Color_t POINT_COLOR; -extern TFT_Color_t BACK_COLOR; +/** + * @brief 读取TFT显示屏ID + * @param dev: [输入] TFT设备结构体 + * @return uint32_t ID值 + * @example TFT_ReadID(myTFT); +**/ +uint32_t TFT_ReadID(TFT_T *dev); -void TFT_Init(TFT_T dev); +/** + * @brief 设置TFT显示方向 + * @param dev: [输入] TFT设备结构体指针 + * @param dir: [输入] 显示方向 + * @return void + * @example TFT_SetDir(&myTFT, TFT_DIR_LANDSCAPE); +**/ +void TFT_SetDir(TFT_T *dev, TFT_DIR_T dir); -uint32_t TFT_ReadID(TFT_T dev); +/** + * @brief 设置TFT显示当前像素位置 + * @param dev: [输入] TFT设备结构体指针 + * @param x: [输入] X坐标 + * @param y: [输入] Y坐标 + * @return void + * @example TFT_SetCur(&myTFT, 100, 50); +**/ +void TFT_SetCur(TFT_T *dev, uint16_t x, uint16_t y); -void TFT_SetDir(TFT_T dev, TFT_DIR_T dir); +/** + * @brief 设置前景色和背景色 + * @param pcolor: [输入] 前景色 + * @param bcolor: [输入] 背景色 + * @return void + * @example TFT_SetColor(0xFFFF, 0x0000); +**/ +void TFT_SetColor(uint16_t pcolor, uint16_t bcolor); +/** + * @brief 设置TFT显示窗口 + * @param dev: [输入] TFT设备结构体指针 + * @param x: [输入] 窗口起始X坐标 + * @param y: [输入] 窗口起始Y坐标 + * @param width: [输入] 窗口宽度 + * @param height: [输入] 窗口高度 + * @return void + * @example TFT_SetWindow(&myTFT, 10, 10, 100, 80); +**/ +void TFT_SetWindow(TFT_T *dev, uint16_t x, uint16_t y, uint16_t width, uint16_t height); + +/** + * @brief 获取指定像素的颜色值 + * @param dev: [输入] TFT设备结构体指针 + * @param x: [输入] X坐标 + * @param y: [输入] Y坐标 + * @return TFT_Color_t 像素颜色值 + * @example TFT_GetPixel(&myTFT, 20, 30); +**/ +TFT_Color_t TFT_GetPixel(TFT_T *dev, uint16_t x, uint16_t y); + +/** + * @brief 设置指定像素的颜色值 + * @param dev: [输入] TFT设备结构体指针 + * @param x: [输入] X坐标 + * @param y: [输入] Y坐标 + * @param color: [输入] 要设置的颜色值 + * @return void + * @example TFT_SetPixel(&myTFT, 50, 60, TFT_COLOR_RED); +**/ +void TFT_SetPixel(TFT_T *dev, uint16_t x, uint16_t y, TFT_Color_t color); + +/** + * @brief 设置TFT显示背光亮度 + * @param dev: [输入] TFT设备结构体指针 + * @param value: [输入] 背光亮度值 + * @return void + * @example TFT_SetBacklight(&myTFT, 50); +**/ +void TFT_SetBacklight(TFT_T *dev, uint8_t value); + +/** + * @brief 在TFT显示屏上填充矩形区域 + * @param dev: [输入] TFT设备结构体指针 + * @param x: [输入] 矩形起始X坐标 + * @param y: [输入] 矩形起始Y坐标 + * @param width: [输入] 矩形宽度 + * @param height: [输入] 矩形高度 + * @param color: [输入] 填充颜色数组指针 + * @return void + * @example TFT_FillRect(&myTFT, 20, 30, 100, 80, &color_array); +**/ +void TFT_FillRect(TFT_T *dev, uint16_t x, uint16_t y, uint16_t width, uint16_t height, TFT_Color_t *color); + +/** + * @brief 在TFT显示屏上填充矩形区域 + * @param dev: [输入] TFT设备结构体指针 + * @param x: [输入] 矩形起始X坐标 + * @param y: [输入] 矩形起始Y坐标 + * @param width: [输入] 矩形宽度 + * @param height: [输入] 矩形高度 + * @param color: [输入] 填充颜色 + * @return void + * @example TFT_Fill(&myTFT, 20, 30, 100, 80, TFT_COLOR_BLUE); +**/ +void TFT_Fill(TFT_T *dev, uint16_t x, uint16_t y, uint16_t width, uint16_t height, TFT_Color_t color); + +/** + * @brief 在TFT显示屏上填充整个屏幕区域 + * @param dev: [输入] TFT设备结构体指针 + * @param color: [输入] 填充颜色 + * @return void + * @example TFT_FillColor(&myTFT, TFT_COLOR_WHITE); +**/ +void TFT_FillColor(TFT_T *dev, TFT_Color_t color); + +/** + * @brief 在TFT显示屏上绘制直线 + * @param dev: [输入] TFT设备结构体指针 + * @param x1: [输入] 起始点X坐标 + * @param y1: [输入] 起始点Y坐标 + * @param x2: [输入] 结束点X坐标 + * @param y2: [输入] 结束点Y坐标 + * @return void + * @example TFT_DrawLine(&myTFT, 10, 20, 100, 120); +**/ +void TFT_DrawLine(TFT_T *dev, uint16_t x1, uint16_t y1, uint16_t x2, uint16_t y2); + +/** + * @brief 在TFT显示屏上绘制矩形 + * @param dev: [输入] TFT设备结构体指针 + * @param x1: [输入] 矩形左上角X坐标 + * @param y1: [输入] 矩形左上角Y坐标 + * @param x2: [输入] 矩形右下角X坐标 + * @param y2: [输入] 矩形右下角Y坐标 + * @return void + * @example TFT_DrawRect(&myTFT, 10, 20, 100, 80); +**/ +void TFT_DrawRect(TFT_T *dev, uint16_t x1, uint16_t y1, uint16_t x2, uint16_t y2); + +/** + * @brief 在TFT显示屏上绘制圆形 + * @param dev: [输入] TFT设备结构体指针 + * @param x: [输入] 圆心X坐标 + * @param y: [输入] 圆心Y坐标 + * @param r: [输入] 圆半径 + * @return void + * @example TFT_DrawCircle(&myTFT, 50, 50, 30); +**/ +void TFT_DrawCircle(TFT_T *dev, uint16_t x, uint16_t y, uint16_t r); + +/** + * @brief 在TFT显示屏上显示单个字符 + * @param dev: [输入] TFT设备结构体指针 + * @param x: [输入] 字符显示起始X坐标 + * @param y: [输入] 字符显示起始Y坐标 + * @param chr: [输入] 要显示的字符 + * @param size: [输入] 字体大小 + * @param mode: [输入] 显示方式 叠加(1)非叠加(0) + * @return void + * @example TFT_ShowChar(&myTFT, 30, 40, 'A', 2); +**/ +void TFT_ShowChar(TFT_T *dev, uint16_t x, uint16_t y, uint8_t chr, uint16_t size, bool mode); + +/** + * @brief 在TFT显示屏上显示字符串 + * @param dev: [输入] TFT设备结构体指针 + * @param x: [输入] 字符串显示起始X坐标 + * @param y: [输入] 字符串显示起始Y坐标 + * @param str: [输入] 要显示的字符串数组指针 + * @param size: [输入] 字体大小 + * @param mode: [输入] 显示方式 叠加(1)非叠加(0) + * @return void + * @example TFT_ShowString(&myTFT, 20, 30, "Hello", 1); +**/ +void TFT_ShowString(TFT_T *dev, uint16_t x, uint16_t y, uint8_t *str, uint16_t size, bool mode); + +#ifdef HZK_FONT +/** + * @brief 在TFT显示屏上显示中文字符串 + * @param dev: [输入] TFT设备结构体指针 + * @param x: [输入] 字符串显示起始X坐标 + * @param y: [输入] 字符串显示起始Y坐标 + * @param str: [输入] 要显示的中文字符串数组指针 + * @param mode: [输入] 显示方式 叠加(1)非叠加(0) + * @return void + * @example TFT_ShowCHString(&myTFT, 20, 30, "你好"); +**/ +void TFT_ShowCHString(TFT_T *dev, uint16_t x, uint16_t y, uint8_t *str, bool mode); +#endif +/** + * @brief 在TFT显示屏上显示数字 + * @param dev: [输入] TFT设备结构体指针 + * @param x: [输入] 数字显示起始X坐标 + * @param y: [输入] 数字显示起始Y坐标 + * @param num: [输入] 要显示的数字 + * @param len: [输入] 数字长度 + * @param size: [输入] 字体大小 + * @return void + * @example TFT_ShowNum(&myTFT, 20, 30, 12345, 5, 2); +**/ +void TFT_ShowNum(TFT_T *dev, uint16_t x, uint16_t y, uint32_t num, uint16_t len, uint8_t size); + +/** + * @brief 在TFT显示屏上显示图片 + * @param dev: [输入] TFT设备结构体指针 + * @param x0: [输入] 图片左上角X坐标 + * @param y0: [输入] 图片左上角Y坐标 + * @param w: [输入] 图片宽度 + * @param h: [输入] 图片高度 + * @param bmp: [输入] 图片数据数组指针 + * @return void + * @example TFT_ShowPic(&myTFT, 10, 20, 80, 60, &image_data); +**/ +void TFT_ShowPic(TFT_T *dev, uint16_t x0, uint16_t y0, uint16_t w, uint16_t h, TFT_Color_t *bmp); #ifdef LVGL_FONT @@ -125,8 +328,9 @@ void TFT_SetDir(TFT_T dev, TFT_DIR_T dir); * @param s: [输入] 要显示的字符串 * @param x: [输入] 字符串左上角 x 坐标 * @param y: [输入] 字符串左上角 y 坐标 + * @param mode: [输入] 显示方式 叠加(1)非叠加(0) * @return void - * @example TFT_DisplayString(&oled_device, &font_arial_16, "Hello World", 10, 20); + * @example TFT_DisplayString(&oled_device, &font_arial_16, "Hello World", 10, 20,bool mode); **/ void TFT_DisplayString(TFT_T *dev, const lv_font_t *font, uint8_t *s, uint16_t x, uint16_t y); diff --git a/lib/tft/tft.cpp b/lib/tft/tft.cpp index 3b42e12..97156a5 100644 --- a/lib/tft/tft.cpp +++ b/lib/tft/tft.cpp @@ -1,36 +1,57 @@ #include "tft.h" +#include "ascii_font.h" + #ifdef HZK_FONT - #include "font_chuc.h" - #endif #ifdef TFT_ST7735 - #include "ST7735.h" -#include "ascii_font.h" +#endif -uint8_t *cmdIndex = (uint8_t *) st7735initcmd; +#ifdef TFT_ST7796 +#include "ST7796.h" #endif +TFT_Color_t POINT_COLOR; +TFT_Color_t BACK_COLOR; +uint8_t *cmdIndex; void TFT_Init(TFT_T *dev) { + if(dev == NULL) + { + return; + } uint8_t count, temp; +#ifdef TFT_ST7735 + if (dev->id==ST7735_ID) { + cmdIndex= (uint8_t *) st7735initcmd; + dev->setxcmd = ST7735_CASET; + dev->setycmd = ST7735_RASET; + dev->wgramcmd = ST7735_WRITE_RAM; + } +#endif +#ifdef TFT_ST7735 + if (dev->id==ST7796_ID) { + cmdIndex= (uint8_t *) st7796initcmd; + dev->setxcmd = ST7796_CASET; + dev->setycmd = ST7796_RASET; + dev->wgramcmd = ST7796_WRITE_RAM; + } +#endif while (*cmdIndex) { temp = *cmdIndex++; count = temp & 0x7F; - dev->cmd(cmdIndex, 1); - if (count > 1) { - dev->data(cmdIndex + 1, count - 1); - } + dev->writeReg(*cmdIndex,cmdIndex + 1, count - 1); cmdIndex += count; if (0x81 == temp) { - dev->delay(TFT_DELAY); + dev->delay(150); } } + TFT_SetDir(dev,dev->dir); } uint32_t TFT_ReadID(TFT_T *dev) { @@ -38,131 +59,161 @@ uint32_t TFT_ReadID(TFT_T *dev) { #ifdef TFT_ST7735 ST7735_ReadID(dev, id); #endif + +#ifdef TFT_ST7796 + ST7796_ReadID(dev, id); +#endif return id; } void TFT_SetDir(TFT_T *dev, TFT_DIR_T dir) { - uint8_t tmp = TFT_DIR_CMD; - dev->cmd(&tmp, 1); - tmp = DIR_MASK(dir); - dev->data(&tmp, 1); + uint8_t tmp; +#ifdef TFT_ST7735 + ST7735_SetDir(dev, dir); +#endif +#ifdef TFT_ST7796 + ST7796_SetDir(dev, dir); +#endif } void TFT_SetCur(TFT_T *dev, uint16_t x, uint16_t y) { - if (dev->dir <= LONGITUDINAL_180) {//竖屏 - x += TFT_X_OFFSET; - y += TFT_Y_OFFSET; - } else { - x += TFT_Y_OFFSET; - y += TFT_X_OFFSET; - } +#ifdef TFT_ST7735 + ST7735_OFFSET(dev,x,y); +#endif + +#ifdef TFT_ST7796 + ST7796_OFFSET(dev,x,y); +#endif uint8_t tmp[2]; - tmp[0] = TFT_XPOS_CMD; - dev->cmd(&tmp[0], 1); tmp[0] = x >> 8U; tmp[1] = x & 0xFFU; - dev->data(tmp, 2); + dev->writeReg(dev->setxcmd,tmp, 2); - tmp[0] = TFT_YPOS_CMD; - dev->cmd(&tmp[0], 1); tmp[0] = y >> 8U; tmp[1] = y & 0xFFU; - dev->data(tmp, 2); + dev->writeReg(dev->setycmd,tmp, 2); - tmp[0] = TFT_WRITE_RAM; - dev->cmd(tmp, 1); + tmp[0] = 0; + dev->writeReg(dev->wgramcmd,tmp,0); +} + +void TFT_SetColor(uint16_t pcolor,uint16_t bcolor){ + POINT_COLOR.color=pcolor; + BACK_COLOR.color=bcolor; } void TFT_SetWindow(TFT_T *dev, uint16_t x, uint16_t y, uint16_t width, uint16_t height) { - if (dev->dir <= LONGITUDINAL_180) {//竖屏 - x += TFT_X_OFFSET; - y += TFT_Y_OFFSET; - } else { - x += TFT_Y_OFFSET; - y += TFT_X_OFFSET; - } +#ifdef TFT_ST7735 + ST7735_OFFSET(dev,x,y); +#endif + +#ifdef TFT_ST7796 + ST7796_OFFSET(dev,x,y); +#endif uint8_t tmp[4]; - tmp[0] = TFT_XPOS_CMD; - dev->cmd(&tmp[0], 1); tmp[0] = x >> 8U; tmp[1] = x & 0xFFU; tmp[2] = (x + width - 1) >> 8U; tmp[3] = (x + width - 1) & 0xFFU; - dev->data(tmp, 4); + dev->writeReg(dev->setxcmd,tmp, 4); - tmp[0] = TFT_YPOS_CMD; - dev->cmd(&tmp[0], 1); tmp[0] = y >> 8U; tmp[1] = y & 0xFFU; - tmp[0] = (y + height - 1) >> 8U; - tmp[1] = (y + height - 1) & 0xFFU; - dev->data(tmp, 4); + tmp[2] = (y + height - 1) >> 8U; + tmp[3] = (y + height - 1) & 0xFFU; + dev->writeReg(dev->setycmd,tmp, 4); - tmp[0] = TFT_WRITE_RAM; - dev->cmd(tmp, 1); + tmp[0] = 0; + dev->writeReg(dev->wgramcmd,tmp,0); } -TFT_Color_t TFT_GetPixel(TFT_T *dev, uint16_t x, uint16_t y) { +TFT_Color_t TFT_GetPixel(TFT_T *dev,uint16_t x, uint16_t y){ uint8_t pixel_lsb, pixel_msb; uint8_t tmp; TFT_Color_t rec; + rec.color=0; /* Set Cursor */ - TFT_SetCur(dev, x, y); - /* Prepare to read LCD RAM */ - tmp = TFT_READ_RAM; - dev->cmd(&tmp, 1); - /* Dummy read */ - dev->read(&tmp, 1); - /* Read first part of the RGB888 data */ - dev->read(&pixel_lsb, 1); - /* Read first part of the RGB888 data */ - dev->read(&pixel_msb, 1); - rec.color = ((uint32_t) (pixel_lsb)) + ((uint32_t) (pixel_msb) << 8); + TFT_SetCur(dev,x,y); +#ifdef TFT_ST7735 + ST7735_ReadRam(dev,rec); +#endif + +#ifdef TFT_ST7796 + ST7796_ReadRam(dev,rec); +#endif return rec; } -void TFT_SetPixel(TFT_T *dev, uint16_t x, uint16_t y, TFT_Color_t color) { - if ((x >= dev->width) || (y >= dev->height)) { return; } - TFT_SetCur(dev, x, y); - dev->data(color.u8, 2); +void TFT_SetPixel(TFT_T *dev,uint16_t x, uint16_t y,TFT_Color_t color){ + if((x>=dev->width) || (y >= dev->height)){ return;} + TFT_SetCur(dev,x,y); + dev->sendData(color.u8, 2); } -void TFT_SetBacklight(TFT_T *dev, uint8_t value) { +void TFT_SetBacklight(TFT_T *dev,uint8_t value){ dev->blacklight(value); } -void TFT_FillRect(TFT_T *dev, uint16_t x, uint16_t y, uint16_t width, uint16_t height, TFT_Color_t *color) { - if (x + width > dev->width || y + height > dev->height)return; - uint32_t size = width + height - 2; - TFT_SetWindow(dev, x, y, width, height); - dev->data(color->u8, size); +void TFT_DrawHLineColor(TFT_T *dev, uint16_t x, uint16_t y, uint16_t len,TFT_Color_t *color){ + if(x+len>dev->width)return; + TFT_SetCur(dev,x,y); + dev->sendData(color->u8,len*2); } -void TFT_Fill(TFT_T *dev, uint16_t x, uint16_t y, uint16_t width, uint16_t height, TFT_Color_t color) { - if (x + width > dev->width || y + height > dev->height)return; - uint32_t size = width + height - 2; - TFT_SetWindow(dev, x, y, width, height); - while (size--) { - dev->data(color.u8, 2); +void TFT_FillRect(TFT_T *dev, uint16_t x, uint16_t y, uint16_t width, uint16_t height,TFT_Color_t *color){ + if(x+width>dev->width||y+height>dev->height)return; + uint32_t i; + TFT_SetWindow(dev,x,y,width,height); + for (i = 0; i < height; ++i) { + TFT_DrawHLineColor(dev,x,y+i,width,color); + color+=width; + } +// dev->sendData(color->u8, size*2); +} + +void TFT_DrawHLine(TFT_T *dev, uint16_t x, uint16_t y, uint16_t len,TFT_Color_t color){ + uint16_t i; + uint8_t pdata[dev->width*2]; + if(x+len>dev->width)return; + TFT_SetCur(dev,x,y); + for(i = 0; i < len; i++) + { + /* Exchange LSB and MSB to fit LCD specification */ + pdata[2U*i] = color.u8[0]; + pdata[(2U*i) + 1U] = color.u8[1]; +// pdata[(2U*i) + 1U] = (uint8_t)(Color >> 8); +// pdata[2U*i] = (uint8_t)(Color); + } + dev->sendData(pdata,len*2); +} + +void TFT_Fill(TFT_T *dev, uint16_t x, uint16_t y, uint16_t width, uint16_t height,TFT_Color_t color){ + if(x+width>dev->width||y+height>dev->height)return; + uint32_t i; + TFT_SetWindow(dev,x,y,width,height); + for (i=0;idata(color.u8, 2); +void TFT_FillColor(TFT_T *dev,TFT_Color_t color){ + dev->sendData(color.u8, 2); } + + void TFT_DrawLine(TFT_T *dev, uint16_t x1, uint16_t y1, uint16_t x2, uint16_t y2) { uint16_t i, k, k1, k2; if ((x1 < 0) || (x2 > dev->width) || (y1 < 0) || (y2 > dev->height) || (x1 > x2) || (y1 > y2))return; if (x1 == x2) //画竖线 { for (i = 0; i < (y2 - y1); i++) { - TFT_SetPixel(dev, x1, y1 + i, POINT_COLOR); + TFT_SetPixel(dev, x1, y1 + i,POINT_COLOR); } } else if (y1 == y2) //画横线 { for (i = 0; i < (x2 - x1); i++) { - TFT_SetPixel(dev, x1 + i, y1, POINT_COLOR); + TFT_SetPixel(dev, x1 + i, y1,POINT_COLOR); } } else //画斜线 { @@ -170,7 +221,7 @@ void TFT_DrawLine(TFT_T *dev, uint16_t x1, uint16_t y1, uint16_t x2, uint16_t y2 k2 = x2 - x1; k = k1 * 10 / k2; for (i = 0; i < (x2 - x1); i++) { - TFT_SetPixel(dev, x1 + i, y1 + i * k / 10, POINT_COLOR); + TFT_SetPixel(dev, x1 + i, y1 + i * k / 10,POINT_COLOR); } } } @@ -187,14 +238,14 @@ void TFT_DrawCircle(TFT_T *dev, uint16_t x, uint16_t y, uint16_t r) { a = 0; b = r; while (2 * b * b >= r * r) { - TFT_SetPixel(dev, x + a, y - b, POINT_COLOR); - TFT_SetPixel(dev, x - a, y - b, POINT_COLOR); - TFT_SetPixel(dev, x - a, y + b, POINT_COLOR); - TFT_SetPixel(dev, x + a, y + b, POINT_COLOR); - TFT_SetPixel(dev, x + b, y + a, POINT_COLOR); - TFT_SetPixel(dev, x + b, y - a, POINT_COLOR); - TFT_SetPixel(dev, x - b, y - a, POINT_COLOR); - TFT_SetPixel(dev, x - b, y + a, POINT_COLOR); + TFT_SetPixel(dev, x + a, y - b,POINT_COLOR); + TFT_SetPixel(dev, x - a, y - b,POINT_COLOR); + TFT_SetPixel(dev, x - a, y + b,POINT_COLOR); + TFT_SetPixel(dev, x + a, y + b,POINT_COLOR); + TFT_SetPixel(dev, x + b, y + a,POINT_COLOR); + TFT_SetPixel(dev, x + b, y - a,POINT_COLOR); + TFT_SetPixel(dev, x - b, y - a,POINT_COLOR); + TFT_SetPixel(dev, x - b, y + a,POINT_COLOR); a++; num = (a * a + b * b) - r * r;//计算画的点离圆心的距离 @@ -205,23 +256,23 @@ void TFT_DrawCircle(TFT_T *dev, uint16_t x, uint16_t y, uint16_t r) { } } -void TFT_ShowChar(TFT_T *dev, uint16_t x, uint16_t y, uint16_t chr, uint16_t size1) { +void TFT_ShowChar(TFT_T *dev, uint16_t x, uint16_t y, uint8_t chr, uint16_t size,bool mode) { uint16_t i, m, temp, size2, chr1; uint16_t ys = y; - size2 = (size1 / 8 + ((size1 % 8) ? 1 : 0)) * (size1 / 2); //得到字体一个字符对应点阵集所占的字节数 + size2 = (size / 8 + ((size % 8) ? 1 : 0)) * (size / 2); //得到字体一个字符对应点阵集所占的字节数 chr1 = chr - ' '; //计算偏移后的值 for (i = 0; i < size2; i++) { - if (size1 == 12) { temp = asc2_1206[chr1][i]; } //调用1206字体 - else if (size1 == 16) { temp = asc2_1608[chr1][i]; } //调用1608字体 - else if (size1 == 24) { temp = asc2_2412[chr1][i]; } //调用2412字体 + if (size == 12) { temp = asc2_1206[chr1][i]; } //调用1206字体 + else if (size == 16) { temp = asc2_1608[chr1][i]; } //调用1608字体 + else if (size == 24) { temp = asc2_2412[chr1][i]; } //调用2412字体 else return; for (m = 0; m < 8; m++) //写入数据 { - if (temp & 0x80)TFT_SetPixel(dev, x, ys, POINT_COLOR); - else TFT_SetPixel(dev, x, ys, BACK_COLOR); + if (temp & 0x80)TFT_SetPixel(dev, x, ys,POINT_COLOR); + else if(!mode) TFT_SetPixel(dev, x, ys,BACK_COLOR); temp <<= 1; ys++; - if ((ys - y) == size1) { + if ((ys - y) == size) { ys = y; x++; break; @@ -230,46 +281,50 @@ void TFT_ShowChar(TFT_T *dev, uint16_t x, uint16_t y, uint16_t chr, uint16_t siz } } -void TFT_ShowString(TFT_T *dev, uint16_t x, uint16_t y, uint16_t *str, uint16_t size1) { +void TFT_ShowString(TFT_T *dev, uint16_t x, uint16_t y, uint8_t *str, uint16_t size,bool mode) { while ((*str >= ' ') && (*str <= '~'))//判断是不是非法字符! { - TFT_ShowChar(dev, x, y, *str, size1); - x += size1 / 2; - if (x > dev->width - size1) //换行 + TFT_ShowChar(dev, x, y, *str, size,mode); + x += size / 2; + if (x > dev->width - size) //换行 { x = 0; - y += 2; + y += size; } str++; } } +#define GET_BIT(x, bit) ((x & (1 << bit)) >> bit) +void TFT_HBSet(TFT_T *dev, uint8_t x, uint8_t y, uint8_t data, bool mode) { + for (uint8_t i = 0; i < 8; i++) { + if(GET_BIT(data, i)){ + TFT_SetPixel(dev, x + 7 - i, y, POINT_COLOR); + } else if(!mode){ + TFT_SetPixel(dev, x + 7 - i, y, BACK_COLOR); + } + } +} #ifdef HZK_FONT -void TFT_ShowCHChr(TFT_T *dev, uint16_t x, uint16_t y, Chinese_t *hzk) { - uint16_t i, size2 = Hzk_size * ((Hzk_size + 7) / 8 * 8) / 8; - uint16_t ziku_byte_n, ziku_bytes = ((Hzk_size + 7) / 8 * 8) / 8; - ziku_byte_n = 0; - TFT_Color_t temp; - for (i = 0; i < size2; i++) { - temp = hzk->data[i] ? POINT_COLOR : BACK_COLOR; - TFT_SetPixel(dev, x + ziku_byte_n * 8, y, temp); - ziku_byte_n++; - if (ziku_byte_n >= ziku_bytes) { +void TFT_ShowCHChr(TFT_T *dev, uint8_t x, uint8_t y, Chinese_t *hzk, bool mode) { + uint8_t ziku_bytes = ((Hzk_size + 7) / 8 * 8) / 8; + for (uint8_t i = 0, ziku_byte_n = 0, size2 = Hzk_size * ziku_bytes; i < size2; i++) { + TFT_HBSet(dev, x + ziku_byte_n * 8, y, hzk->data[i], mode); + if (++ziku_byte_n >= ziku_bytes) { ziku_byte_n = 0; y++; } } } - #ifdef UTF8_TO_UNICODE -#include "font.h" +#include "font_t.h" #define GET_LOW_BYTE0(x) ((x >> 0) & 0x000000ff) /* 获取第0个字节 */ #define GET_LOW_BYTE1(x) ((x >> 8) & 0x000000ff) /* 获取第1个字节 */ -void TFT_ShowCHString(TFT_T *dev, uint16_t x, uint16_t y, uint8_t *str) { +void TFT_ShowCHString(TFT_T *dev, uint16_t x, uint16_t y, uint8_t *str,bool mode) { uint32_t unicode_letter; uint16_t step; while (*str != '\0') { @@ -277,15 +332,15 @@ void TFT_ShowCHString(TFT_T *dev, uint16_t x, uint16_t y, uint8_t *str) { step = Font_utf8_to_unicode(str, &unicode_letter); if (step != 0) { Chinese_t *hzk = find_chinese_data(GET_LOW_BYTE1(unicode_letter), GET_LOW_BYTE0(unicode_letter)); - if (hzk != NULL) { - TFT_ShowCHChr(dev, x, y, hzk); + if(hzk!=NULL){ + TFT_ShowCHChr(dev, x, y, hzk, mode); x += Hzk_size; str += step; found = true; } } if (!found) { - TFT_ShowChar(dev, x, y, *str, Hzk_size); + TFT_ShowChar(dev, x, y, *str, Hzk_size,1); x += Hzk_size / 2; str++; } @@ -297,14 +352,14 @@ void TFT_ShowCHString(TFT_T *dev, uint16_t x, uint16_t y, uint8_t *str) { } #else -void TFT_ShowCHString(TFT_T *dev, uint16_t x, uint16_t y, uint8_t *str) { +void TFT_ShowCHString(TFT_T *dev, uint16_t x, uint16_t y, uint8_t *str,bool mode) { uint16_t index; while (*str != '\0') { bool found = false; for (index = 0; index < sizeof(Hzk) / sizeof(Chinese_t); index++) { if (Hzk[index].unicode[0] == str[0] && Hzk[index].unicode[1] == str[1]) // 对比汉字区码位码 { - TFT_ShowCHChr(dev, x, y, &Hzk[index]); + TFT_ShowCHChr(dev, x, y, &Hzk[index],mode); x += Hzk_size; str++; str++; @@ -313,7 +368,7 @@ void TFT_ShowCHString(TFT_T *dev, uint16_t x, uint16_t y, uint8_t *str) { } } if (!found) { - TFT_ShowChar(dev, x, y, *str, Hzk_size); + TFT_ShowChar(dev, x, y, *str, Hzk_size,mode); x += Hzk_size / 2; str++; } @@ -338,7 +393,7 @@ void draw_rect(Font_f_t *fd, uint16_t *data, size_t len) { } } -void TFT_DisplayString(TFT_T *dev, const lv_font_t *font, uint8_t *s, uint16_t x, uint16_t y) { +void TFT_DisplayString(TFT_T *dev, const lv_font_t *font, uint8_t *s, uint16_t x, uint16_t y,bool mode) { uint32_t unicode_letter; Font_f_t fd = {.dev=dev, .dev_w=dev->width, .show=draw_rect}; while (*s) { @@ -347,7 +402,7 @@ void TFT_DisplayString(TFT_T *dev, const lv_font_t *font, uint8_t *s, uint16_t x x += Font_draw_letter(font, &fd, unicode_letter, x, y); x += 0; //字间距 } else { - TFT_ShowChar(dev, x, y, *s, 12); + TFT_ShowChar(dev, x, y, *s, 12,mode); x += 12; s++; } @@ -355,7 +410,7 @@ void TFT_DisplayString(TFT_T *dev, const lv_font_t *font, uint8_t *s, uint16_t x } #endif -uint32_t TFT_Pow(uint8_t m, uint8_t n) { +uint32_t TFT_Pow(uint16_t m, uint16_t n) { uint32_t result = 1; while (n--) { result *= m; @@ -363,27 +418,24 @@ uint32_t TFT_Pow(uint8_t m, uint8_t n) { return result; } -void TFT_ShowNum(TFT_T *dev, uint8_t x, uint8_t y, uint32_t num, uint8_t len, uint8_t size1) { - uint8_t t, temp; +void TFT_ShowNum(TFT_T *dev, uint16_t x, uint16_t y, uint32_t num, uint16_t len, uint8_t size1) { + uint16_t t, temp; for (t = 0; t < len; t++) { temp = (num / TFT_Pow(10, len - t - 1)) % 10; if (temp == 0) { - TFT_ShowChar(dev, x + (size1 / 2) * t, y, '0', size1); + TFT_ShowChar(dev, x + (size1 / 2) * t, y, '0', size1,1); } else { - TFT_ShowChar(dev, x + (size1 / 2) * t, y, temp + '0', size1); + TFT_ShowChar(dev, x + (size1 / 2) * t, y, temp + '0', size1,1); } } } -void TFT_ShowPic(TFT_T *dev, uint8_t x0, uint8_t y0, uint8_t w, uint8_t h, TFT_Color_t *bmp) { - size_t index; - uint16_t x = x0, y = y0; - for (index = 0; index < (w * h) / 8; index++) { - TFT_SetPixel(dev, x, y, bmp[index]); - x++; - if ((x - x0) == w) { - y += 8; - x = x0; - } +void TFT_ShowPic(TFT_T *dev, uint16_t x, uint16_t y, uint16_t width, uint16_t height, TFT_Color_t *bmp) { + if(x+width>dev->width||y+height>dev->height)return; + uint32_t j; + for(j = 0; j < height; j++) + { + TFT_DrawHLineColor(dev,x,y+j,width, bmp); + bmp+=width; } }