906|0

107

帖子

1

TA的资源

一粒金砂(高级)

楼主
 

【兆易GD32H759I-EVAL】TLI与LCD显示实现(2) [复制链接]

  本帖最后由 尹小舟 于 2024-6-23 20:02 编辑

本实验移植正点原子LCD驱动

 

画点函数


void lcd_point_set(uint16_t xpos, uint16_t ypos, uint16_t color)
{
    *(__IO uint16_t*)(current_framebuffer + 2*((LCD_PIXEL_WIDTH*ypos) + xpos)) = color;
}

 

  1. 函数定义:

    • 函数名:lcd_point_set
    • 参数:
      • xpos:一个无符号16位整数,表示点的x坐标。
      • ypos:一个无符号16位整数,表示点的y坐标。
      • color:一个无符号16位整数,表示要设置的颜色。
    • 返回值:无(void)
  2. 函数功能:

    • 根据给定的xpos和ypos,在LCD的当前帧缓冲区(current_framebuffer)中设置指定颜色的点。
  3. 参数详解:

    • \param[in] xpos, ypos, color:这些是函数的输入参数,用于传递x位置、y位置和颜色值给函数。
    • 该函数没有返回值(retval)。
  4. 函数体:

    • *(__IO uint16_t*)(current_framebuffer + 2*((LCD_PIXEL_WIDTH*ypos) + xpos)) = color;
      • 这行代码执行了实际的点设置操作。
      • __IO 是一个修饰符,通常用于指示编译器这个变量是“输入/输出”的
      • current_framebuffer 是一个指向帧缓冲区的指针(这个指针可能在其他地方定义)。帧缓冲区通常用于存储要在LCD上显示的像素数据。
      • LCD_PIXEL_WIDTH 是一个常量,表示LCD的像素宽度。
      • 通过计算 (LCD_PIXEL_WIDTH*ypos) + xpos,我们可以找到特定点在帧缓冲区中的位置(索引)。但是,因为我们每个像素用2个字节(16位)来表示颜色,所以需要乘以2来获取字节地址。
      • 然后,我们将计算出的地址强制转换为指向uint16_t的指针,并解引用它以写入颜色值。

代码的移植关键是实现LCD的初始化,和实现画点函数

 

	

#ifndef __LCD_H
#define __LCD_H

#include "stdlib.h"
#include "gd32h7xx.h"
#include "./BSP/LCD/tli.h"


/******************************************************************************************/

//设置RGB屏方向
//0为竖屏 1为横屏
#define RGB_DIR  1

/* LCD重要参数集 */
typedef struct
{
    uint16_t width;     /* LCD 宽度 */
    uint16_t height;    /* LCD 高度 */
    uint16_t id;        /* LCD ID */
    uint8_t dir;        /* 横屏还是竖屏控制:0,竖屏;1,横屏。 */
    uint16_t wramcmd;   /* 开始写gram指令 */
    uint16_t setxcmd;   /* 设置x坐标指令 */
    uint16_t setycmd;   /* 设置y坐标指令 */
} _lcd_dev;

/* LCD参数 */
extern _lcd_dev lcddev; /* 管理LCD重要参数 */

/* LCD的画笔颜色和背景色 */
extern uint32_t  g_point_color;     /* 默认红色 */
extern uint32_t  g_back_color;      /* 背景颜色,默认为白色 */

/* LCD背光控制 */
#define LCD_BL(x)        do{ x ? \
                             gpio_bit_write(GPIOJ, GPIO_PIN_10, SET) : \
                             gpio_bit_write(GPIOJ, GPIO_PIN_10, RESET); \
                         }while(0)     

/* LCD复位引脚 */
#define LCD_RST(x)       do{ x ? \
                             gpio_bit_write(GPIOJ, GPIO_PIN_11, SET) : \
                             gpio_bit_write(GPIOJ, GPIO_PIN_11, RESET); \
                         }while(0)     
/* LCD地址结构体 */
typedef struct
{
    volatile uint16_t LCD_REG;
    volatile uint16_t LCD_RAM;
} LCD_TypeDef;


/******************************************************************************************/
/* EXMC相关参数 定义 
 * 注意: 我们默认是通过EXMC块0来连接LCD, 块0有4个片选: EXMC_NE0~3
 *
 */
#define LCD_EXMC_NEX         3              /* 使用EXMC_NE3接LCD_CS,取值范围只能是: 0~3 */
#define LCD_EXMC_AX          10             /* 使用EXMC_A10接LCD_RS,取值范围是: 0 ~ 25 */

/* LCD_BASE的详细计算方法:
 * 我们一般使用EXMC的块0(BANK0)来驱动TFTLCD液晶屏(MCU屏), 块0地址范围总大小为256MB,均分成4块:
 * 存储块0(EXMC_NE0)地址范围: 0X6000 0000 ~ 0X63FF FFFF
 * 存储块1(EXMC_NE1)地址范围: 0X6400 0000 ~ 0X67FF FFFF
 * 存储块2(EXMC_NE2)地址范围: 0X6800 0000 ~ 0X6BFF FFFF
 * 存储块3(EXMC_NE3)地址范围: 0X6C00 0000 ~ 0X6FFF FFFF
 *
 * 我们需要根据硬件连接方式选择合适的片选(连接LCD_CS)和地址线(连接LCD_RS)
 * 开发板使用EXMC_NE3连接LCD_CS, EXMC_A10连接LCD_RS ,16位数据线,计算方法如下:
 * 首先EXMC_NE3的基地址为: 0X6C00 0000;     NEx的基址为(x=0/1/2/3): 0X6000 0000 + (0X400 0000 * x)
 * EXMC_A10对应地址值: 2^10 * 2 = 0X800;       EXMC_Ay对应的地址为(y = 0 ~ 25): 2^y * 2
 *
 * LCD->LCD_REG,对应LCD_RS = 0(LCD寄存器); LCD->LCD_RAM,对应LCD_RS = 1(LCD数据)
 * 则 LCD->LCD_RAM的地址为:  0X6C00 0000 + 2^10 * 2 = 0X6C00 0800
 *    LCD->LCD_REG的地址可以为 LCD->LCD_RAM之外的任意地址.
 * 由于我们使用结构体管理LCD_REG 和 LCD_RAM(REG在前,RAM在后,均为16位数据宽度)
 * 因此 结构体的基地址(LCD_BASE) = LCD_RAM - 2 = 0X6C00 0800 -2
 *
 * 更加通用的计算公式为((片选脚EXMC_NEx)x=0/1/2/3, (RS接地址线EXMC_Ay)y=0~25):
 *          LCD_BASE = (0X6000 0000 + (0X400 0000 * x)) | (2^y * 2 -2)
 *          等效于(使用移位操作)
 *          LCD_BASE = (0X6000 0000 + (0X400 0000 * x)) | ((1 << y) * 2 -2)
 */
#define LCD_BASE        (uint32_t)((0X60000000 + (0X4000000 * LCD_EXMC_NEX)) | (((1 << LCD_EXMC_AX) * 2) -2))
#define LCD             ((LCD_TypeDef *) LCD_BASE)

/******************************************************************************************/
/* LCD扫描方向和颜色 定义 */

/* 扫描方向定义 */
#define L2R_U2D         0           /* 从左到右,从上到下 */
#define L2R_D2U         1           /* 从左到右,从下到上 */
#define R2L_U2D         2           /* 从右到左,从上到下 */
#define R2L_D2U         3           /* 从右到左,从下到上 */

#define U2D_L2R         4           /* 从上到下,从左到右 */
#define U2D_R2L         5           /* 从上到下,从右到左 */
#define D2U_L2R         6           /* 从下到上,从左到右 */
#define D2U_R2L         7           /* 从下到上,从右到左 */

#define DFT_SCAN_DIR    L2R_U2D     /* 默认的扫描方向 */

#if TLI_PIXFORMAT == TLI_PIXFORMAT_RGB565

/* 常用画笔颜色 */
#define WHITE           0xFFFF      /* 白色 */
#define BLACK           0x0000      /* 黑色 */
#define RED             0xF800      /* 红色 */
#define GREEN           0x07E0      /* 绿色 */
#define BLUE            0x001F      /* 蓝色 */ 
#define MAGENTA         0XF81F      /* 品红色/紫红色 = BLUE + RED */
#define YELLOW          0XFFE0      /* 黄色 = GREEN + RED */
#define CYAN            0X07FF      /* 青色 = GREEN + BLUE */   

/* 非常用颜色 */
#define BROWN           0XBC40      /* 棕色 */
#define BRRED           0XFC07      /* 棕红色 */
#define GRAY            0X8430      /* 灰色 */ 
#define DARKBLUE        0X01CF      /* 深蓝色 */
#define LIGHTBLUE       0X7D7C      /* 浅蓝色 */ 
#define GRAYBLUE        0X5458      /* 灰蓝色 */ 
#define LIGHTGREEN      0X841F      /* 浅绿色 */  
#define LGRAY           0XC618      /* 浅灰色(PANNEL),窗体背景色 */ 
#define LGRAYBLUE       0XA651      /* 浅灰蓝色(中间层颜色) */ 
#define LBBLUE          0X2B12      /* 浅棕蓝色(选择条目的反色) */ 

#elif TLI_PIXFORMAT == TLI_PIXFORMAT_RGB888

/* 常用画笔颜色 */
#define WHITE           0xFFFFFF      /* 白色 */
#define BLACK           0x000000      /* 黑色 */
#define RED             0xFF0000      /* 红色 */
#define GREEN           0x00FF00      /* 绿色 */
#define BLUE            0x0000FF      /* 蓝色 */ 
#define MAGENTA         0XFF00FF      /* 品红色/紫红色 = BLUE + RED */
#define YELLOW          0XFFFF00      /* 黄色 = GREEN + RED */
#define CYAN            0X00FFFF      /* 青色 = GREEN + BLUE */  

/* 非常用颜色 */
#define BROWN           0xB88800      /* 棕色 */
#define BRRED           0XFA8038       /* 棕红色 */
#define GRAY            0X808080      /* 灰色 */ 
#define DARKBLUE        0X00383C       /* 深蓝色 */
#define LIGHTBLUE       0X3CACE0      /* 浅蓝色 */ 
#define GRAYBLUE        0X5088C0       /* 灰蓝色 */ 
#define LIGHTGREEN      0X8080FA       /* 浅绿色 */  
#define LGRAY           0XC0C0C0      /* 浅灰色(PANNEL),窗体背景色 */ 
#define LGRAYBLUE       0XA0C888       /* 浅灰蓝色(中间层颜色) */ 
#define LBBLUE          0x286090       /* 浅棕蓝色(选择条目的反色) */

//#define BROWN           0xA52A2A      /* 棕色 */
//#define BRRED           0XFA8072       /* 棕红色 */
//#define GRAY            0X808080      /* 灰色 */ 
//#define DARKBLUE        0X003399       /* 深蓝色 */
//#define LIGHTBLUE       0XADD8E6      /* 浅蓝色 */ 
//#define GRAYBLUE        0X7AB8CC       /* 灰蓝色 */ 
//#define LIGHTGREEN      0X90EE90       /* 浅绿色 */  
//#define LGRAY           0XC0C0C0      /* 浅灰色(PANNEL),窗体背景色 */ 
//#define LGRAYBLUE       0X778899       /* 浅灰蓝色(中间层颜色) */ 
//#define LBBLUE          0x004D99       /* 浅棕蓝色(选择条目的反色) */

#else

#define WHITE           0xFFFFFFFF      /* 白色 */
#define BLACK           0xFF000000      /* 黑色 */
#define RED             0xFFFF0000      /* 红色 */
#define GREEN           0xFF00FF00      /* 绿色 */
#define BLUE            0xFF0000FF      /* 蓝色 */ 
#define MAGENTA         0XFFFF00FF      /* 品红色/紫红色 = BLUE + RED */
#define YELLOW          0XFFFFFF00      /* 黄色 = GREEN + RED */
#define CYAN            0XFF00FFFF      /* 青色 = GREEN + BLUE */  

#define BROWN           0xFFB88800      /* 棕色 */
#define BRRED           0XFFFA8038       /* 棕红色 */
#define GRAY            0XFF808080      /* 灰色 */ 
#define DARKBLUE        0XFF00383C       /* 深蓝色 */
#define LIGHTBLUE       0XFF3CACE0      /* 浅蓝色 */ 
#define GRAYBLUE        0XFF5088C0       /* 灰蓝色 */ 
#define LIGHTGREEN      0XFF8080FA       /* 浅绿色 */  
#define LGRAY           0XFFC0C0C0      /* 浅灰色(PANNEL),窗体背景色 */ 
#define LGRAYBLUE       0XFFA0C888       /* 浅灰蓝色(中间层颜色) */ 
#define LBBLUE          0xFF286090       /* 浅棕蓝色(选择条目的反色) */

#define color16M_black    0xFF000000
#define color16M_white    0xFFFFFFFF
#define color16M_red      0x00FF0000
#define color16M_green    0x0000FF00
#define color16M_blue     0x000000FF
#define color16M_blue2    0xFF00BFFF
#define color16M_yellow   color16M_red|color16M_green
#define color16M_cyan     color16M_green|color16M_blue
#define color16M_magenta  color16M_red|color16M_blue

#endif

/******************************************************************************************/
/* 函数声明 */
  


void lcd_init(void);                        /* 初始化LCD */ 
  
void lcd_display_on(void);                  /* 开显示 */ 
void lcd_display_off(void);                 /* 关显示 */
void lcd_display_dir(uint8_t dir);          /* 设置屏幕显示方向 */ 


uint16_t lcd_read_point(uint16_t x, uint16_t y);                /* 读点(32位颜色,兼容TLI) */
void lcd_draw_point(uint16_t x, uint16_t y, uint32_t color);    /* 画点(32位颜色,兼容TLI) */

void lcd_clear(uint16_t color);                                                                 /* LCD清屏 */
void lcd_fill_circle(uint16_t x, uint16_t y, uint16_t r, uint32_t color);                       /* 填充实心圆 */
void lcd_draw_circle(uint16_t x0, uint16_t y0, uint8_t r, uint32_t color);                      /* 画圆 */
void lcd_draw_hline(uint16_t x, uint16_t y, uint16_t len, uint32_t color);                      /* 画水平线 */

void lcd_fill(uint16_t sx, uint16_t sy, uint16_t ex, uint16_t ey, uint32_t color);              /* 纯色填充矩形(32位颜色,兼容TLI) */
void lcd_color_fill(uint16_t sx, uint16_t sy, uint16_t ex, uint16_t ey, uint16_t *color);       /* 彩色填充矩形 */
void lcd_draw_line(uint16_t x1, uint16_t y1, uint16_t x2, uint16_t y2, uint32_t color);         /* 画直线 */
void lcd_draw_rectangle(uint16_t x1, uint16_t y1, uint16_t x2, uint16_t y2, uint32_t color);    /* 画矩形 */

void lcd_show_char(uint16_t x, uint16_t y, char chr, uint8_t size, uint8_t mode, uint32_t color);                       /* 显示一个字符 */
void lcd_show_num(uint16_t x, uint16_t y, uint32_t num, uint8_t len, uint8_t size, uint32_t color);                     /* 显示数字 */
void lcd_show_xnum(uint16_t x, uint16_t y, uint32_t num, uint8_t len, uint8_t size, uint8_t mode, uint32_t color);      /* 扩展显示数字 */
void lcd_show_string(uint16_t x, uint16_t y, uint16_t width, uint16_t height, uint8_t size, char *p, uint32_t color);   /* 显示字符串 */


#endif

 

 


#include "stdlib.h"
#include "./BSP/LCD/lcd.h"
#include "./BSP/LCD/lcdfont.h"



#include "gd32h759i_lcd_eval.h"
#include "gd32h759i_eval_exmc_sdram.h"
/* LCD的画笔颜色和背景色 */
uint32_t g_point_color = RED;    /* 画笔颜色 */
uint32_t g_back_color  = 0XFFFFFFFF;    /* 背景色 */

/* 管理LCD重要参数 */
_lcd_dev lcddev;




#define LCD_FRAME_BUFFER         ((uint32_t)0xC0000000)
#define BUFFER_OFFSET            ((uint32_t)0x7F800)

//static font_struct *current_font;
static uint16_t current_textcolor = 0x0000;
static uint16_t current_backcolor = 0xFFFF;
static uint32_t current_framebuffer = LCD_FRAME_BUFFER;
static uint32_t current_layer = LCD_LAYER_BACKGROUND;

static void lcd_char_draw(uint16_t xpos, uint16_t ypos, const uint16_t *c);
static void lcd_vertical_char_draw(uint16_t xpos, uint16_t ypos, const uint16_t *c);
static void pixel_set(int16_t x, int16_t y);

#define HORIZONTAL_SYNCHRONOUS_PULSE  41
#define HORIZONTAL_BACK_PORCH         2
#define ACTIVE_WIDTH                  480
#define HORIZONTAL_FRONT_PORCH        2

#define VERTICAL_SYNCHRONOUS_PULSE    10
#define VERTICAL_BACK_PORCH           2
#define ACTIVE_HEIGHT                 272
#define VERTICAL_FRONT_PORCH          2
/*!
    \brief    enable the LCD layer0 or layer1
    \param[in]  layer: LCD layer
      \arg        LCD_LAYER_BACKGROUND
      \arg        LCD_LAYER_FOREGROUND
    \param[out] none
    \retval     none
*/
void lcd_layer_enable(uint32_t layer)
{
    if(LCD_LAYER_BACKGROUND == layer){
        tli_layer_enable(LAYER0);
    }else if(LCD_LAYER_FOREGROUND == layer){
        tli_layer_enable(LAYER1);
    }
    tli_enable();
}

/*!
    \brief    set the LCD layer
    \param[in]  layer: LCD layer
      \arg        LCD_LAYER_BACKGROUND
      \arg        LCD_LAYER_FOREGROUND
    \param[out] none
    \retval     none
*/
void lcd_layer_set(uint32_t layer)
{
    if(LCD_LAYER_BACKGROUND == layer){
        current_framebuffer = LCD_FRAME_BUFFER;
        current_layer = LCD_LAYER_BACKGROUND;
    }else{
        current_framebuffer = LCD_FRAME_BUFFER + BUFFER_OFFSET;
        current_layer = LCD_LAYER_FOREGROUND;
    }
}

/*!
    \brief    set the transparency of LCD
    \param[in]  trans: transparency of LCD, from 0 to 255
    \param[out] none
    \retval     none
*/
void lcd_transparency_set(uint8_t trans)
{
    if (LCD_LAYER_BACKGROUND == current_layer){
        TLI_LXSA(LAYER0) &= ~(TLI_LXSA_SA);
        TLI_LXSA(LAYER0) = trans;
    }else{
        TLI_LXSA(LAYER1) &= ~(TLI_LXSA_SA);
        TLI_LXSA(LAYER1) = trans;
    }
    tli_reload_config(TLI_REQUEST_RELOAD_EN);
}




/*!
    \brief    initialize TLI layer0 or layer1
    \param[in]  layer: LCD layer
      \arg        LCD_LAYER_BACKGROUND
      \arg        LCD_LAYER_FOREGROUND
    \param[in]  width: width of the window
    \param[in]  height: height of the window
    \param[out] none
    \retval     none
*/
void lcd_layer_init(uint32_t layer, uint32_t width, uint32_t height)
{
    tli_layer_parameter_struct  tli_layer_init_struct;
    if(LCD_LAYER_BACKGROUND == layer){
        /* TLI layer0 configuration */
        tli_layer_init_struct.layer_window_leftpos = (HORIZONTAL_SYNCHRONOUS_PULSE + HORIZONTAL_BACK_PORCH);
        tli_layer_init_struct.layer_window_rightpos = (width + HORIZONTAL_SYNCHRONOUS_PULSE + HORIZONTAL_BACK_PORCH - 1);
        tli_layer_init_struct.layer_window_toppos = (VERTICAL_SYNCHRONOUS_PULSE + VERTICAL_BACK_PORCH);
        tli_layer_init_struct.layer_window_bottompos = (height + VERTICAL_SYNCHRONOUS_PULSE + VERTICAL_BACK_PORCH - 1);
        tli_layer_init_struct.layer_ppf = LAYER_PPF_RGB565;
        tli_layer_init_struct.layer_sa = 0xFF;
        tli_layer_init_struct.layer_default_blue = 0xFF;
        tli_layer_init_struct.layer_default_green = 0xFF;
        tli_layer_init_struct.layer_default_red = 0xFF;
        tli_layer_init_struct.layer_default_alpha = 0xFF;
        tli_layer_init_struct.layer_acf1 = LAYER_ACF1_PASA;
        tli_layer_init_struct.layer_acf2 = LAYER_ACF2_PASA;
        tli_layer_init_struct.layer_frame_bufaddr = LCD_FRAME_BUFFER;
        tli_layer_init_struct.layer_frame_line_length = ((width * 2) + 3); 
        tli_layer_init_struct.layer_frame_buf_stride_offset = (width * 2);
        tli_layer_init_struct.layer_frame_total_line_number = height; 
        tli_layer_init(LAYER0, &tli_layer_init_struct);
    }else if(LCD_LAYER_FOREGROUND == layer){
        /* TLI layer1 configuration */
        tli_layer_init_struct.layer_window_leftpos = (HORIZONTAL_SYNCHRONOUS_PULSE + HORIZONTAL_BACK_PORCH);
        tli_layer_init_struct.layer_window_rightpos = (width + HORIZONTAL_SYNCHRONOUS_PULSE + HORIZONTAL_BACK_PORCH - 1);
        tli_layer_init_struct.layer_window_toppos = (VERTICAL_SYNCHRONOUS_PULSE + VERTICAL_BACK_PORCH);
        tli_layer_init_struct.layer_window_bottompos = (height + VERTICAL_SYNCHRONOUS_PULSE + VERTICAL_BACK_PORCH - 1);
        tli_layer_init_struct.layer_ppf = LAYER_PPF_RGB565;
        tli_layer_init_struct.layer_sa = 0xFF;
        tli_layer_init_struct.layer_default_blue = 0xFF;
        tli_layer_init_struct.layer_default_green = 0xFF;
        tli_layer_init_struct.layer_default_red = 0xFF;
        tli_layer_init_struct.layer_default_alpha = 0x0;
        tli_layer_init_struct.layer_acf1 = LAYER_ACF1_PASA;
        tli_layer_init_struct.layer_acf2 = LAYER_ACF2_PASA;
        tli_layer_init_struct.layer_frame_bufaddr = LCD_FRAME_BUFFER + BUFFER_OFFSET;
        tli_layer_init_struct.layer_frame_line_length = ((width * 2) + 3); 
        tli_layer_init_struct.layer_frame_buf_stride_offset = (width * 2);
        tli_layer_init_struct.layer_frame_total_line_number = height; 
        tli_layer_init(LAYER1, &tli_layer_init_struct);
    }

    tli_reload_config(TLI_REQUEST_RELOAD_EN);
//    lcd_font_set(&LCD_DEFAULT_FONT);
}


/**
 * @brief   初始化LCD
 *   @note      该初始化函数可以初始化各种型号的LCD(详见本.c文件最前面的描述)
 *
 * @param       无
 * @retval      无
 */
void lcd_init(void)
{
    tli_parameter_struct tli_init_struct;
    lcddev.width  = 480;
	  lcddev.height = 272;
    /* enable GPIO clock */
    rcu_periph_clock_enable(RCU_GPIOA);
    rcu_periph_clock_enable(RCU_GPIOB);
    rcu_periph_clock_enable(RCU_GPIOC);
    rcu_periph_clock_enable(RCU_GPIOD);
    rcu_periph_clock_enable(RCU_GPIOE);
    rcu_periph_clock_enable(RCU_GPIOF);
    rcu_periph_clock_enable(RCU_GPIOH);
    rcu_periph_clock_enable(RCU_GPIOG);

    /* configure HSYNC(PE15), VSYNC(PA7), PCLK(PG7) */
    gpio_af_set(GPIOE, GPIO_AF_14, GPIO_PIN_15);
    gpio_af_set(GPIOA, GPIO_AF_14, GPIO_PIN_7);
    gpio_af_set(GPIOG, GPIO_AF_14, GPIO_PIN_7);
    gpio_mode_set(GPIOE, GPIO_MODE_AF, GPIO_PUPD_NONE, GPIO_PIN_15);
    gpio_output_options_set(GPIOE, GPIO_OTYPE_PP, GPIO_OSPEED_100_220MHZ, GPIO_PIN_15);
    gpio_mode_set(GPIOA, GPIO_MODE_AF, GPIO_PUPD_NONE, GPIO_PIN_7);
    gpio_output_options_set(GPIOA, GPIO_OTYPE_PP, GPIO_OSPEED_100_220MHZ, GPIO_PIN_7);
    gpio_mode_set(GPIOG, GPIO_MODE_AF, GPIO_PUPD_NONE, GPIO_PIN_7);
    gpio_output_options_set(GPIOG, GPIO_OTYPE_PP, GPIO_OSPEED_100_220MHZ, GPIO_PIN_7);

    /* configure LCD_R7(PG6), LCD_R6(PH12), LCD_R5(PH11), LCD_R4(PA5), LCD_R3(PH9),LCD_R2(PH8),
                 LCD_R1(PH3), LCD_R0(PH2) */
    gpio_af_set(GPIOG, GPIO_AF_14, GPIO_PIN_6);
    gpio_af_set(GPIOH, GPIO_AF_14, GPIO_PIN_12);
    gpio_af_set(GPIOH, GPIO_AF_14, GPIO_PIN_11);
    gpio_af_set(GPIOA, GPIO_AF_14, GPIO_PIN_5);
    gpio_af_set(GPIOH, GPIO_AF_14, GPIO_PIN_9);
    gpio_af_set(GPIOH, GPIO_AF_14, GPIO_PIN_8);
    gpio_af_set(GPIOH, GPIO_AF_14, GPIO_PIN_3);
    gpio_af_set(GPIOH, GPIO_AF_14, GPIO_PIN_2);

    gpio_mode_set(GPIOG, GPIO_MODE_AF, GPIO_PUPD_NONE, GPIO_PIN_6);
    gpio_output_options_set(GPIOG, GPIO_OTYPE_PP, GPIO_OSPEED_100_220MHZ, GPIO_PIN_6);
    gpio_mode_set(GPIOH, GPIO_MODE_AF, GPIO_PUPD_NONE, GPIO_PIN_12);
    gpio_output_options_set(GPIOH, GPIO_OTYPE_PP, GPIO_OSPEED_100_220MHZ, GPIO_PIN_12);
    gpio_mode_set(GPIOH, GPIO_MODE_AF, GPIO_PUPD_NONE, GPIO_PIN_11);
    gpio_output_options_set(GPIOH, GPIO_OTYPE_PP, GPIO_OSPEED_100_220MHZ, GPIO_PIN_11);
    gpio_mode_set(GPIOA, GPIO_MODE_AF, GPIO_PUPD_NONE, GPIO_PIN_5);
    gpio_output_options_set(GPIOA, GPIO_OTYPE_PP, GPIO_OSPEED_100_220MHZ, GPIO_PIN_5);
    gpio_mode_set(GPIOH, GPIO_MODE_AF, GPIO_PUPD_NONE, GPIO_PIN_9);
    gpio_output_options_set(GPIOH, GPIO_OTYPE_PP, GPIO_OSPEED_100_220MHZ, GPIO_PIN_9);
    gpio_mode_set(GPIOH, GPIO_MODE_AF, GPIO_PUPD_NONE, GPIO_PIN_8);
    gpio_output_options_set(GPIOH, GPIO_OTYPE_PP, GPIO_OSPEED_100_220MHZ, GPIO_PIN_8);
    gpio_mode_set(GPIOH, GPIO_MODE_AF, GPIO_PUPD_NONE, GPIO_PIN_3);
    gpio_output_options_set(GPIOH, GPIO_OTYPE_PP, GPIO_OSPEED_100_220MHZ, GPIO_PIN_3);
    gpio_mode_set(GPIOH, GPIO_MODE_AF, GPIO_PUPD_NONE, GPIO_PIN_2);
    gpio_output_options_set(GPIOH, GPIO_OTYPE_PP, GPIO_OSPEED_100_220MHZ, GPIO_PIN_2);

    /* configure  LCD_G7(PD3), LCD_G6(PC7), LCD_G5(PC1), LCD_G4(PH15), LCD_G3(PH14), LCD_G2(PH13),LCD_G1(PB0), LCD_G0(PB1) */
    gpio_af_set(GPIOD, GPIO_AF_14, GPIO_PIN_3);
    gpio_af_set(GPIOC, GPIO_AF_14, GPIO_PIN_7);
    gpio_af_set(GPIOC, GPIO_AF_14, GPIO_PIN_1);
    gpio_af_set(GPIOH, GPIO_AF_14, GPIO_PIN_15);
    gpio_af_set(GPIOH, GPIO_AF_14, GPIO_PIN_14);
    gpio_af_set(GPIOH, GPIO_AF_14, GPIO_PIN_13);
    gpio_af_set(GPIOB, GPIO_AF_14, GPIO_PIN_0);
    gpio_af_set(GPIOB, GPIO_AF_14, GPIO_PIN_1);

    gpio_mode_set(GPIOD, GPIO_MODE_AF, GPIO_PUPD_NONE, GPIO_PIN_3);
    gpio_output_options_set(GPIOD, GPIO_OTYPE_PP, GPIO_OSPEED_100_220MHZ, GPIO_PIN_3);
    gpio_mode_set(GPIOC, GPIO_MODE_AF, GPIO_PUPD_NONE, GPIO_PIN_7);
    gpio_output_options_set(GPIOC, GPIO_OTYPE_PP, GPIO_OSPEED_100_220MHZ, GPIO_PIN_7);
    gpio_mode_set(GPIOC, GPIO_MODE_AF, GPIO_PUPD_NONE, GPIO_PIN_1);
    gpio_output_options_set(GPIOC, GPIO_OTYPE_PP, GPIO_OSPEED_100_220MHZ, GPIO_PIN_1);
    gpio_mode_set(GPIOH, GPIO_MODE_AF, GPIO_PUPD_NONE, GPIO_PIN_15);
    gpio_output_options_set(GPIOH, GPIO_OTYPE_PP, GPIO_OSPEED_100_220MHZ, GPIO_PIN_15);
    gpio_mode_set(GPIOH, GPIO_MODE_AF, GPIO_PUPD_NONE, GPIO_PIN_14);
    gpio_output_options_set(GPIOH, GPIO_OTYPE_PP, GPIO_OSPEED_100_220MHZ, GPIO_PIN_14);
    gpio_mode_set(GPIOH, GPIO_MODE_AF, GPIO_PUPD_NONE, GPIO_PIN_13);
    gpio_output_options_set(GPIOH, GPIO_OTYPE_PP, GPIO_OSPEED_100_220MHZ, GPIO_PIN_13);
    gpio_mode_set(GPIOB, GPIO_MODE_AF, GPIO_PUPD_NONE, GPIO_PIN_0);
    gpio_output_options_set(GPIOB, GPIO_OTYPE_PP, GPIO_OSPEED_100_220MHZ, GPIO_PIN_0);
    gpio_mode_set(GPIOB, GPIO_MODE_AF, GPIO_PUPD_NONE, GPIO_PIN_1);
    gpio_output_options_set(GPIOB, GPIO_OTYPE_PP, GPIO_OSPEED_100_220MHZ, GPIO_PIN_1);

    /* configure LCD_B7(PB9), LCD_B6(PB8), LCD_B5(PB5), LCD_B4(PC11), LCD_B3(PG11),LCD_B2(PG10), LCD_B1(PG12), LCD_B0(PG14) */
    gpio_af_set(GPIOB, GPIO_AF_14, GPIO_PIN_9);
    gpio_af_set(GPIOB, GPIO_AF_14, GPIO_PIN_8);
    gpio_af_set(GPIOB, GPIO_AF_3, GPIO_PIN_5);
    gpio_af_set(GPIOC, GPIO_AF_14, GPIO_PIN_11);
    gpio_af_set(GPIOG, GPIO_AF_14, GPIO_PIN_11);
    gpio_af_set(GPIOG, GPIO_AF_14, GPIO_PIN_10);
    gpio_af_set(GPIOG, GPIO_AF_14, GPIO_PIN_12);
    gpio_af_set(GPIOG, GPIO_AF_14, GPIO_PIN_14);

    gpio_mode_set(GPIOB, GPIO_MODE_AF, GPIO_PUPD_NONE, GPIO_PIN_9);
    gpio_output_options_set(GPIOB, GPIO_OTYPE_PP, GPIO_OSPEED_100_220MHZ, GPIO_PIN_9);
    gpio_mode_set(GPIOB, GPIO_MODE_AF, GPIO_PUPD_NONE, GPIO_PIN_8);
    gpio_output_options_set(GPIOB, GPIO_OTYPE_PP, GPIO_OSPEED_100_220MHZ, GPIO_PIN_8);
    gpio_mode_set(GPIOB, GPIO_MODE_AF, GPIO_PUPD_NONE, GPIO_PIN_5);
    gpio_output_options_set(GPIOB, GPIO_OTYPE_PP, GPIO_OSPEED_100_220MHZ, GPIO_PIN_5);
    gpio_mode_set(GPIOC, GPIO_MODE_AF, GPIO_PUPD_NONE, GPIO_PIN_11);
    gpio_output_options_set(GPIOC, GPIO_OTYPE_PP, GPIO_OSPEED_100_220MHZ, GPIO_PIN_11);
    gpio_mode_set(GPIOG, GPIO_MODE_AF, GPIO_PUPD_NONE, GPIO_PIN_11);
    gpio_output_options_set(GPIOG, GPIO_OTYPE_PP, GPIO_OSPEED_100_220MHZ, GPIO_PIN_11);
    gpio_mode_set(GPIOG, GPIO_MODE_AF, GPIO_PUPD_NONE, GPIO_PIN_10);
    gpio_output_options_set(GPIOG, GPIO_OTYPE_PP, GPIO_OSPEED_100_220MHZ, GPIO_PIN_10);
    gpio_mode_set(GPIOG, GPIO_MODE_AF, GPIO_PUPD_NONE, GPIO_PIN_12);
    gpio_output_options_set(GPIOG, GPIO_OTYPE_PP, GPIO_OSPEED_100_220MHZ, GPIO_PIN_12);
    gpio_mode_set(GPIOG, GPIO_MODE_AF, GPIO_PUPD_NONE, GPIO_PIN_14);
    gpio_output_options_set(GPIOG, GPIO_OTYPE_PP, GPIO_OSPEED_100_220MHZ, GPIO_PIN_14);

    /* configure LCD_DE(PF10) */
    gpio_af_set(GPIOF, GPIO_AF_14, GPIO_PIN_10);
    gpio_mode_set(GPIOF, GPIO_MODE_AF, GPIO_PUPD_NONE, GPIO_PIN_10);
    gpio_output_options_set(GPIOF, GPIO_OTYPE_PP, GPIO_OSPEED_100_220MHZ, GPIO_PIN_10);
    /* LCD PWM BackLight(PG13) */
    gpio_mode_set(GPIOG, GPIO_MODE_OUTPUT, GPIO_PUPD_PULLUP, GPIO_PIN_13);
    gpio_output_options_set(GPIOG, GPIO_OTYPE_PP, GPIO_OSPEED_100_220MHZ, GPIO_PIN_13);
    gpio_bit_set(GPIOG, GPIO_PIN_13);

    rcu_periph_clock_enable(RCU_TLI);

    /* configure PLL2 to generate TLI clock 25MHz/25*192/3 = 64MHz*/
    rcu_pll_input_output_clock_range_config(IDX_PLL1,RCU_PLL1RNG_1M_2M,RCU_PLL1VCO_192M_836M);
    if(ERROR == rcu_pll2_config(25,192,3,3,3)){
        while(1){
        }
    }
    rcu_pll_clock_output_enable(RCU_PLL2R);
    rcu_tli_clock_div_config(RCU_PLL2R_DIV8);
    
    rcu_osci_on(RCU_PLL2_CK);
    
    if(ERROR == rcu_osci_stab_wait(RCU_PLL2_CK)){
        while(1){
        }
    }

    /* configure the EXMC access mode */
    exmc_synchronous_dynamic_ram_init(EXMC_SDRAM_DEVICE0);

    /* TLI initialization */
    tli_init_struct.signalpolarity_hs = TLI_HSYN_ACTLIVE_LOW;
    tli_init_struct.signalpolarity_vs = TLI_VSYN_ACTLIVE_LOW;
    tli_init_struct.signalpolarity_de = TLI_DE_ACTLIVE_LOW;
    tli_init_struct.signalpolarity_pixelck = TLI_PIXEL_CLOCK_INVERTEDTLI;

    /* LCD display timing configuration */
    tli_init_struct.synpsz_hpsz = HORIZONTAL_SYNCHRONOUS_PULSE - 1;
    tli_init_struct.synpsz_vpsz = VERTICAL_SYNCHRONOUS_PULSE - 1;
    tli_init_struct.backpsz_hbpsz = HORIZONTAL_SYNCHRONOUS_PULSE + HORIZONTAL_BACK_PORCH - 1;
    tli_init_struct.backpsz_vbpsz = VERTICAL_SYNCHRONOUS_PULSE + VERTICAL_BACK_PORCH - 1;
    tli_init_struct.activesz_hasz = HORIZONTAL_SYNCHRONOUS_PULSE + HORIZONTAL_BACK_PORCH + ACTIVE_WIDTH - 1;
    tli_init_struct.activesz_vasz = VERTICAL_SYNCHRONOUS_PULSE + VERTICAL_BACK_PORCH + ACTIVE_HEIGHT - 1;
    tli_init_struct.totalsz_htsz = HORIZONTAL_SYNCHRONOUS_PULSE + HORIZONTAL_BACK_PORCH + ACTIVE_WIDTH + HORIZONTAL_FRONT_PORCH - 1;
    tli_init_struct.totalsz_vtsz = VERTICAL_SYNCHRONOUS_PULSE + VERTICAL_BACK_PORCH + ACTIVE_HEIGHT + VERTICAL_FRONT_PORCH - 1;

    /* LCD background color configure*/
    tli_init_struct.backcolor_red = 0xFF;
    tli_init_struct.backcolor_green = 0xFF;
    tli_init_struct.backcolor_blue = 0xFF;
    tli_init(&tli_init_struct);
    
		
		lcd_layer_init(LCD_LAYER_BACKGROUND, LCD_PIXEL_WIDTH, LCD_PIXEL_HEIGHT);
    lcd_layer_init(LCD_LAYER_FOREGROUND, LCD_PIXEL_WIDTH, LCD_PIXEL_HEIGHT);
    tli_layer_enable(LAYER0);
    tli_layer_enable(LAYER1);
    tli_enable();
  
    lcd_layer_set(LCD_LAYER_BACKGROUND);
    lcd_transparency_set(255);
    lcd_clear(LCD_COLOR_WHITE);
    
    lcd_layer_set(LCD_LAYER_FOREGROUND);
    lcd_transparency_set(0);
    lcd_clear(LCD_COLOR_WHITE);
    lcd_layer_set(LCD_LAYER_BACKGROUND);
		
    lcd_clear(WHITE);            /* 清屏 */    
}


/*!
    \brief    configure the packeted pixel format
    \param[in]  pixel_format: pixel format
      \arg        LAYER_PPF_ARGB8888
      \arg        LAYER_PPF_RGB888
      \arg        LAYER_PPF_RGB565
      \arg        LAYER_PPF_ARGB1555
      \arg        LAYER_PPF_ARGB4444
      \arg        LAYER_PPF_L8
      \arg        LAYER_PPF_AL44
      \arg        LAYER_PPF_AL88
    \param[out] none
    \retval     none
*/
void lcd_pixel_format_config(uint32_t pixel_format)
{
    if(LCD_LAYER_BACKGROUND == current_layer){
        TLI_LXPPF(LAYER0) &= ~(TLI_LXPPF_PPF);
        TLI_LXPPF(LAYER0) = pixel_format;
    }else{
        TLI_LXPPF(LAYER1) &= ~(TLI_LXPPF_PPF);
        TLI_LXPPF(LAYER1) = pixel_format;
    }
}

/*!
    \brief    configure the frame buffer base address
    \param[in]  address: frame buffer base address
    \param[out] none
    \retval     none
*/
void lcd_address_config(uint32_t address)
{
    if (LCD_LAYER_BACKGROUND == current_layer){
        TLI_LXFBADDR(LAYER0) &= ~(TLI_LXFBADDR_FBADD);
        TLI_LXFBADDR(LAYER0) = address;
    }else{
        TLI_LXFBADDR(LAYER1) &= ~(TLI_LXFBADDR_FBADD);
        TLI_LXFBADDR(LAYER1) = address;
    }

    tli_reload_config(TLI_REQUEST_RELOAD_EN);
}



/**
 * @brief       读取某个点的颜色值
 * @param       x,y:坐标
 * @retval      此点的颜色(32位颜色,方便兼容TLI)
 */
uint16_t lcd_read_point(uint16_t x, uint16_t y)
{
  return *(__IO uint16_t*)(current_framebuffer + 2*((LCD_PIXEL_WIDTH*y) + x));
}

/**
 * @brief       LCD开启显示
 * @param       无
 * @retval      无
 */
void lcd_display_on(void)
{
   
        tli_enable();                /* 使能TLI */
    
}

/**
 * @brief       LCD关闭显示
 * @param       无
 * @retval      无
 */
void lcd_display_off(void)
{
    
        tli_disable();               /* 禁能TLI */
 
}


/**
 * @brief       画点
 * @param       x,y: 坐标
 * @param       color: 点的颜色(32位颜色,方便兼容TLI)
 * @retval      无
 */
void lcd_draw_point(uint16_t x, uint16_t y, uint32_t color)
{
	*(__IO uint16_t*)(current_framebuffer + 2*((LCD_PIXEL_WIDTH*y) + x)) = color;
}

/**
 * @brief       设置LCD显示方向
 * @param       dir:0,竖屏; 1,横屏
 * @retval      无
 */
void lcd_display_dir(uint8_t dir)
{
   
}





/*!
    \brief    clear the LCD with specified color
    \param[in]  color: LCD color
      \arg        LCD_COLOR_WHITE
      \arg        LCD_COLOR_BLACK
      \arg        LCD_COLOR_GREY
      \arg        LCD_COLOR_BLUE
      \arg        LCD_COLOR_BLUE2
      \arg        LCD_COLOR_RED
      \arg        LCD_COLOR_MAGENTA
      \arg        LCD_COLOR_GREEN
      \arg        LCD_COLOR_CYAN
      \arg        LCD_COLOR_YELLOW
    \param[out] none
    \retval     none
*/
void lcd_clear(uint16_t color)
{
    uint32_t index = 0;
    for (index = 0x00; index < BUFFER_OFFSET; index++){
        *(__IO uint16_t*)(current_framebuffer + (2*index)) = color;
    }
}

/**
 * @brief       在指定区域内填充单个颜色
 * @param       (sx,sy),(ex,ey):填充矩形对角坐标,区域大小为:(ex - sx + 1) * (ey - sy + 1)
 * @param       color: 要填充的颜色(32位颜色,方便兼容TLI)
 * @retval      无
 */
void lcd_fill(uint16_t sx, uint16_t sy, uint16_t ex, uint16_t ey, uint32_t color)
{
    uint16_t i, j;
    uint16_t xlen = 0;
  
    
      
        for (i = sy; i <= ey; i++)
        {
            for (j = sx; j < ex; j++)
            {
                lcd_draw_point(j, i, color);
            }
        }
   
  
}

/**
 * @brief       在指定区域内填充指定颜色块
 * @param       (sx,sy),(ex,ey):填充矩形对角坐标,区域大小为:(ex - sx + 1) * (ey - sy + 1)
 * @param       color: 要填充的颜色数组首地址
 * @retval      无
 */
void lcd_color_fill(uint16_t sx, uint16_t sy, uint16_t ex, uint16_t ey, uint16_t *color)
{
    uint16_t height, width;
    uint16_t i, j;
  
    
		width = ex - sx + 1;            /* 得到填充的宽度 */
		height = ey - sy + 1;           /* 高度 */

		for (i = 0; i < height; i++)
		{
				for (j = 0; j < width; j++)
				{
						lcd_draw_point(sx+j, sy+i, color[i * width + j]);
				}
		}
    
}

/**
 * @brief       画线
 * @param       x1,y1: 起点坐标
 * @param       x2,y2: 终点坐标
 * @param       color: 线的颜色
 * @retval      无
 */
void lcd_draw_line(uint16_t x1, uint16_t y1, uint16_t x2, uint16_t y2, uint32_t color)
{
    uint16_t t;
    int xerr = 0, yerr = 0, delta_x, delta_y, distance;
    int incx, incy, row, col;
    delta_x = x2 - x1;          /* 计算坐标增量 */
    delta_y = y2 - y1;
    row = x1;
    col = y1;

    if (delta_x > 0) incx = 1;          /* 设置单步方向 */
    else if (delta_x == 0) incx = 0;    /* 垂直线 */
    else
    {
        incx = -1;
        delta_x = -delta_x;
    }

    if (delta_y > 0) incy = 1;
    else if (delta_y == 0) incy = 0;    /* 水平线 */
    else
    {
        incy = -1;
        delta_y = -delta_y;
    }

    if ( delta_x > delta_y) distance = delta_x; /* 选取基本增量坐标轴 */
    else distance = delta_y;

    for (t = 0; t <= distance + 1; t++ )    /* 画线输出 */
    {
        lcd_draw_point(row, col, color);    /* 画点 */
        xerr += delta_x ;
        yerr += delta_y ;

        if (xerr > distance)
        {
            xerr -= distance;
            row += incx;
        }

        if (yerr > distance)
        {
            yerr -= distance;
            col += incy;
        }
    }
}

/**
 * @brief       画水平线
 * @param       x,y  : 起点坐标
 * @param       len  : 线长度
 * @param       color: 矩形的颜色
 * @retval      无
 */
void lcd_draw_hline(uint16_t x, uint16_t y, uint16_t len, uint32_t color)
{
    if ((len == 0) || (x > lcddev.width) || (y > lcddev.height)) return;

    lcd_fill(x, y, x + len - 1, y, color);
}

/**
 * @brief       画矩形
 * @param       x1,y1: 起点坐标
 * @param       x2,y2: 终点坐标
 * @param       color: 矩形的颜色
 * @retval      无
 */
void lcd_draw_rectangle(uint16_t x1, uint16_t y1, uint16_t x2, uint16_t y2, uint32_t color)
{
    lcd_draw_line(x1, y1, x2, y1, color);
    lcd_draw_line(x1, y1, x1, y2, color);
    lcd_draw_line(x1, y2, x2, y2, color);
    lcd_draw_line(x2, y1, x2, y2, color);
}

/**
 * @brief       画圆
 * @param       x0,y0: 圆中心坐标
 * @param       r    : 半径
 * @param       color: 圆的颜色
 * @retval      无
 */
void lcd_draw_circle(uint16_t x0, uint16_t y0, uint8_t r, uint32_t color)
{
    int a, b;
    int di;
    a = 0;
    b = r;
    di = 3 - (r << 1);       /* 判断下个点位置的标志 */

    while (a <= b)
    {
        lcd_draw_point(x0 + a, y0 - b, color);  /* 5 */
        lcd_draw_point(x0 + b, y0 - a, color);  /* 0 */
        lcd_draw_point(x0 + b, y0 + a, color);  /* 4 */
        lcd_draw_point(x0 + a, y0 + b, color);  /* 6 */
        lcd_draw_point(x0 - a, y0 + b, color);  /* 1 */
        lcd_draw_point(x0 - b, y0 + a, color);
        lcd_draw_point(x0 - a, y0 - b, color);  /* 2 */
        lcd_draw_point(x0 - b, y0 - a, color);  /* 7 */
        a++;

        /* 使用Bresenham算法画圆 */
        if (di < 0)
        {
            di += 4 * a + 6;
        }
        else
        {
            di += 10 + 4 * (a - b);
            b--;
        }
    }
}

/**
 * @brief       填充实心圆
 * @param       x,y  : 圆中心坐标
 * @param       r    : 半径
 * @param       color: 圆的颜色
 * @retval      无
 */
void lcd_fill_circle(uint16_t x, uint16_t y, uint16_t r, uint32_t color)
{
    uint32_t i;
    uint32_t imax = ((uint32_t)r * 707) / 1000 + 1;
    uint32_t sqmax = (uint32_t)r * (uint32_t)r + (uint32_t)r / 2;
    uint32_t xr = r;

    lcd_draw_hline(x - r, y, 2 * r, color);

    for (i = 1; i <= imax; i++)
    {
        if ((i * i + xr * xr) > sqmax)
        {
            /* draw lines from outside */
            if (xr > imax)
            {
                lcd_draw_hline (x - i + 1, y + xr, 2 * (i - 1), color);
                lcd_draw_hline (x - i + 1, y - xr, 2 * (i - 1), color);
            }

            xr--;
        }

        /* draw lines from inside (center) */
        lcd_draw_hline(x - xr, y + i, 2 * xr, color);
        lcd_draw_hline(x - xr, y - i, 2 * xr, color);
    }
}

/**
 * @brief       在指定位置显示一个字符
 * @param       x,y   : 坐标
 * @param       chr   : 要显示的字符:' '--->'~'
 * @param       size  : 字体大小 12/16/24/32
 * @param       mode  : 叠加方式(1); 非叠加方式(0);
 * @param       color : 字符的颜色;
 * @retval      无
 */
void lcd_show_char(uint16_t x, uint16_t y, char chr, uint8_t size, uint8_t mode, uint32_t color)
{
    uint8_t temp, t1, t;
    uint16_t y0 = y;
    uint8_t csize = 0;
    uint8_t *pfont = 0;

    csize = (size / 8 + ((size % 8) ? 1 : 0)) * (size / 2); /* 得到字体一个字符对应点阵集所占的字节数 */
    chr = chr - ' ';    /* 得到偏移后的值(ASCII字库是从空格开始取模,所以-' '就是对应字符的字库) */

    switch (size)
    {
        case 12:
            pfont = (uint8_t *)asc2_1206[chr];  /* 调用1206字体 */
            break;

        case 16:
            pfont = (uint8_t *)asc2_1608[chr];  /* 调用1608字体 */
            break;

        case 24:
            pfont = (uint8_t *)asc2_2412[chr];  /* 调用2412字体 */
            break;

        case 32:
            pfont = (uint8_t *)asc2_3216[chr];  /* 调用3216字体 */
            break;

        default:
            return ;
    }

    for (t = 0; t < csize; t++)
    {
        temp = pfont[t];    /* 获取字符的点阵数据 */

        for (t1 = 0; t1 < 8; t1++)  /* 一个字节8个点 */
        {
            if (temp & 0x80)        /* 有效点,需要显示 */
            {
                lcd_draw_point(x, y, color);        /* 画点出来,要显示这个点 */
            }
            else if (mode == 0)     /* 无效点并且选择非叠加方式 */
            {
                lcd_draw_point(x, y, g_back_color); /* 画背景色,相当于这个点不显示(注意背景色由全局变量控制) */
            }

            temp <<= 1; /* 移位, 以便获取下一个位的状态 */
            y++;

            if (y >= lcddev.height) return;     /* 超区域了 */

            if ((y - y0) == size)               /* 显示完一列了? */
            {
                y = y0;                         /* y坐标复位 */
                x++;                            /* x坐标递增 */

                if (x >= lcddev.width) return;  /* x坐标超区域了 */

                break;
            }
        }
    }
}

/**
 * @brief       平方函数, m^n
 * @param       m: 底数
 * @param       n: 指数
 * @retval      m的n次方
 */
static uint32_t lcd_pow(uint8_t m, uint8_t n)
{
    uint32_t result = 1;

    while (n--) result *= m;

    return result;
}

/**
 * @brief       显示len个数字(高位为0则不显示)
 * @param       x,y   : 起始坐标
 * @param       num   : 数值(0 ~ 2^32)
 * @param       len   : 显示数字的位数
 * @param       size  : 选择字体 12/16/24/32
 * @param       color : 数字的颜色;
 * @retval      无
 */
void lcd_show_num(uint16_t x, uint16_t y, uint32_t num, uint8_t len, uint8_t size, uint32_t color)
{
    uint8_t t, temp;
    uint8_t enshow = 0;

    for (t = 0; t < len; t++)   /* 按总显示位数循环 */
    {
        temp = (num / lcd_pow(10, len - t - 1)) % 10;   /* 获取对应位的数字 */

        if (enshow == 0 && t < (len - 1))   /* 没有使能显示,且还有位要显示 */
        {
            if (temp == 0)
            {
                lcd_show_char(x + (size / 2) * t, y, ' ', size, 0, color);  /* 显示空格,占位 */
                continue;   /* 继续下个一位 */
            }
            else
            {
                enshow = 1; /* 使能显示 */
            }

        }

        lcd_show_char(x + (size / 2) * t, y, temp + '0', size, 0, color);   /* 显示字符 */
    }
}

/**
 * @brief       扩展显示len个数字(高位是0也显示)
 * @param       x,y   : 起始坐标
 * @param       num   : 数值(0 ~ 2^32)
 * @param       len   : 显示数字的位数
 * @param       size  : 选择字体 12/16/24/32
 * @param       mode  : 显示模式
 *              [7]:0,不填充;1,填充0.
 *              [6:1]:保留
 *              [0]:0,非叠加显示;1,叠加显示.
 * @param       color : 数字的颜色;
 * @retval      无
 */
void lcd_show_xnum(uint16_t x, uint16_t y, uint32_t num, uint8_t len, uint8_t size, uint8_t mode, uint32_t color)
{
    uint8_t t, temp;
    uint8_t enshow = 0;

    for (t = 0; t < len; t++)   /* 按总显示位数循环 */
    {
        temp = (num / lcd_pow(10, len - t - 1)) % 10;    /* 获取对应位的数字 */

        if (enshow == 0 && t < (len - 1))   /* 没有使能显示,且还有位要显示 */
        {
            if (temp == 0)
            {
                if (mode & 0X80)   /* 高位需要填充0 */
                {
                    lcd_show_char(x + (size / 2) * t, y, '0', size, mode & 0X01, color);  /* 用0占位 */
                }
                else
                {
                    lcd_show_char(x + (size / 2) * t, y, ' ', size, mode & 0X01, color);  /* 用空格占位 */
                }

                continue;
            }
            else
            {
                enshow = 1; /* 使能显示 */
            }

        }

        lcd_show_char(x + (size / 2) * t, y, temp + '0', size, mode & 0X01, color);
    }
}

/**
 * @brief       显示字符串
 * @param       x,y         : 起始坐标
 * @param       width,height: 区域大小
 * @param       size        : 选择字体 12/16/24/32
 * @param       p           : 字符串首地址
 * @param       color       : 字符串的颜色;
 * @retval      无
 */
void lcd_show_string(uint16_t x, uint16_t y, uint16_t width, uint16_t height, uint8_t size, char *p, uint32_t color)
{
    uint8_t x0 = x;
    width += x;
    height += y;

    while ((*p <= '~') && (*p >= ' '))   /* 判断是不是非法字符! */
    {
        if (x >= width)
        {
            x = x0;
            y += size;
        }

        if (y >= height) break; /* 退出 */

        lcd_show_char(x, y, *p, size, 0, color);
        x += size / 2;
        p++;
    }
}








 

 

 

 

 

 


#include "gd32h7xx.h"
#include "systick.h"
#include <stdio.h>
#include "gd32h759i_eval.h"
#include "gd32h759i_lcd_eval.h"
#include "./SYSTEM/delay/delay.h"
#include "./BSP/TIMER/timer.h"
#include "./BSP/24CXX/24cxx.h"
#include "./BSP/LCD/lcd.h"

const uint8_t g_text_buf[] = {"gd32 IIC TEST"}; /* 要写入到 24c02 的字符串数组 */
#define TEXT_SIZE sizeof(g_text_buf) /* TEXT 字符串长度 */
/*!
    \brief      toggle the led every 500ms
    \param[in]  none
    \param[out] none
    \retval     none
*/
void led_spark(void)
{
    static __IO uint32_t timingdelaylocal = 0U;

    if(timingdelaylocal) {

        if(timingdelaylocal < 500U) {
            gd_eval_led_on(LED1);
        } else {
            gd_eval_led_off(LED1);
        }

        timingdelaylocal--;
    } else {
        timingdelaylocal = 1000U;
    }
}

/*!
    \brief      enable the CPU cache
    \param[in]  none
    \param[out] none
    \retval     none
*/
void cache_enable(void)
{
    /* enable i-cache */
    SCB_EnableICache();

    /* enable d-cache */
    SCB_EnableDCache();
}

/*!
    \brief      main function
    \param[in]  none
    \param[out] none
    \retval     none
*/

int main(void)
{
	  uint8_t x = 0;
	  uint8_t datatemp[TEXT_SIZE];
    /* enable the CPU cache */
    cache_enable();
    /* configure systick */
    //systick_config();
	  delay_init(600);
    /* initilize the LEDs, USART and key */
    gd_eval_led_init(LED1);
    gd_eval_led_init(LED2);
    gd_eval_com_init(EVAL_COM);
    gd_eval_key_init(KEY_WAKEUP, KEY_MODE_GPIO);
	  gd_eval_key_init(KEY_TAMPER, KEY_MODE_GPIO);
	  at24cxx_init();
	  timerx_int_init(10 - 1, 30000 - 1);     
    printf("\r\nCK_SYS is %d", rcu_clock_freq_get(CK_SYS));
	  lcd_init();
	  while (at24cxx_check()) 
		{
		   gd_eval_led_on(LED1);
		   delay_ms(500);lcd_init();
		   gd_eval_led_off(LED1);
		   delay_ms(500);
		}
		
		
    while(1) {
			
			if(RESET == gd_eval_key_scan(KEY_WAKEUP))
			{
			   printf("\r\nCK_SYS is 1");
				 at24cxx_write(0, (uint8_t *)g_text_buf, TEXT_SIZE);
			}
			
			if(RESET == gd_eval_key_scan(KEY_TAMPER))
			{
			  printf("\r\nCK_SYS is 2");
				at24cxx_read(0, datatemp, TEXT_SIZE);
				printf("The Data Readed Is: %s\r\n",datatemp);
			}
			
			 switch (x)
			 {
				 case 0: lcd_clear(WHITE); break;
				 case 1: lcd_clear(BLACK); break;
				 case 2: lcd_clear(BLUE); break;
				 case 3: lcd_clear(RED); break;
				 case 4: lcd_clear(MAGENTA); break;
				 case 5: lcd_clear(GREEN); break;
				 case 6: lcd_clear(CYAN); break;
				 case 7: lcd_clear(YELLOW); break;
				 case 8: lcd_clear(BRRED); break;
				 case 9: lcd_clear(GRAY); break;
				 case 10: lcd_clear(LGRAY); break;
				 case 11: lcd_clear(BROWN); break;
			 }
			 lcd_show_string(10, 40, 240, 32, 32, "STM32", RED);
			 lcd_show_string(10, 80, 240, 24, 24, "TFTLCD TEST", RED);
			 lcd_show_string(10, 110, 240, 16, 16, "ATOM@ALIENTEK", RED);
			
			 x++;
       if (x == 12)
			 x = 0;
			
			 delay_ms(1000);
    }
}

/* retarget the C library printf function to the USART */
int fputc(int ch, FILE *f)
{
    usart_data_transmit(EVAL_COM, (uint8_t)ch);
    while(RESET == usart_flag_get(EVAL_COM, USART_FLAG_TBE));

    return ch;
}

 

实验现象

 

 

GD32H7_EVAL_ATK_LCD.zip (14.11 MB, 下载次数: 5)

 

GD32H7_EVAL_ATK_LCD.zip

14.11 MB, 下载次数: 3

点赞 关注
 
 

回复
举报
您需要登录后才可以回帖 登录 | 注册

随便看看
查找数据手册?

EEWorld Datasheet 技术支持

相关文章 更多>>
关闭
站长推荐上一条 1/6 下一条

 
EEWorld订阅号

 
EEWorld服务号

 
汽车开发圈

About Us 关于我们 客户服务 联系方式 器件索引 网站地图 最新更新 手机版

站点相关: 国产芯 安防电子 汽车电子 手机便携 工业控制 家用电子 医疗电子 测试测量 网络通信 物联网

北京市海淀区中关村大街18号B座15层1530室 电话:(010)82350740 邮编:100190

电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2025 EEWORLD.com.cn, Inc. All rights reserved
快速回复 返回顶部 返回列表