打印
[G32A]

【G32A1465测评】驱动TFT-LCD屏

[复制链接]
109|1
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
本帖最后由 yinwuqing110 于 2025-1-5 20:10 编辑

一、引言
前段时间在某电子商城上购得一块1.77寸RGB屏,显示驱动芯片是ST7735S,这款显示器驱动芯片比较流行,是由矽创电子股份有限公司生产,非常适合小尺寸屏的集成设计,流行的驱动接口有IIC与SPI两种,笔者这款是采用SPI驱动接口,坛友有采用SPI硬件+DMA方式驱动该类似的TFT屏,本期咱采用GPIO模拟SPI方式来驱动,这种方式移植起来比较方便,不受硬件IO口的局限制。
ST7735S.zip (3.01 MB)
二、引脚关系图

使用开发板上的IO口与TFT-LCD屏的管脚对应关系

三、实物连接


四、部分驱动代码
lcd_init.h
#ifndef __LCD_INIT_H
#define __LCD_INIT_H

#include "lcd.h"
#include "g32a1xxx_pins.h"

#define USE_HORIZONTAL 1  //设置横屏或者竖屏显示 0或1为竖屏 2或3为横屏

#if USE_HORIZONTAL==0||USE_HORIZONTAL==1
#define LCD_W 128
#define LCD_H 160
#else
#define LCD_W 160
#define LCD_H 128
#endif

#define BOARD_LCD_MOSI_GPIO                                        GPIOD
#define BOARD_LCD_PORT_MOSI_BASE                                 PMD
#define BOARD_LCD_GPIO_MOSI_PIN                                    (5U)

#define BOARD_LCD_SCLK_GPIO                                        GPIOD
#define BOARD_LCD_PORT_SCLK_BASE                                 PMD
#define BOARD_LCD_GPIO_SCLK_PIN                                    (1U)

#define BOARD_LCD_CS_GPIO                                          GPIOD
#define BOARD_LCD_PORT_CS_BASE                                   PMD
#define BOARD_LCD_GPIO_CS_PIN                                      (2U)

#define BOARD_LCD_DC_GPIO                                         GPIOD
#define BOARD_LCD_PORT_DC_BASE                                  PMD
#define BOARD_LCD_GPIO_DC_PIN                                     (3U)

#define BOARD_LCD_RES_GPIO                                       GPIOD
#define BOARD_LCD_PORT_RES_BASE                                PMD
#define BOARD_LCD_GPIO_RES_PIN                                   (8U)

#define BOARD_LCD_BLK_GPIO                                       GPIOD
#define BOARD_LCD_PORT_BLK_BASE                                PMD
#define BOARD_LCD_GPIO_BLK_PIN                                   (9U)

//-----------------LCD端口定义----------------

#define LCD_SCLK_Clr() PINS_WritePin(BOARD_LCD_SCLK_GPIO,BOARD_LCD_GPIO_SCLK_PIN,0)//SCL SCLK
#define LCD_SCLK_Set() PINS_WritePin(BOARD_LCD_SCLK_GPIO,BOARD_LCD_GPIO_SCLK_PIN,1)

#define LCD_CS_Clr()   PINS_WritePin(BOARD_LCD_CS_GPIO,BOARD_LCD_GPIO_CS_PIN,0)//CS
#define LCD_CS_Set()   PINS_WritePin(BOARD_LCD_CS_GPIO,BOARD_LCD_GPIO_CS_PIN,1)

#define LCD_MOSI_Clr() PINS_WritePin(BOARD_LCD_MOSI_GPIO,BOARD_LCD_GPIO_MOSI_PIN,0)//SDA MOSI
#define LCD_MOSI_Set() PINS_WritePin(BOARD_LCD_MOSI_GPIO,BOARD_LCD_GPIO_MOSI_PIN,1)

#define LCD_DC_Clr()   PINS_WritePin(BOARD_LCD_DC_GPIO,BOARD_LCD_GPIO_DC_PIN,0)//DC
#define LCD_DC_Set()   PINS_WritePin(BOARD_LCD_DC_GPIO,BOARD_LCD_GPIO_DC_PIN,1)

#define LCD_RES_Clr()  PINS_WritePin(BOARD_LCD_RES_GPIO,BOARD_LCD_GPIO_RES_PIN,0)//RES
#define LCD_RES_Set()  PINS_WritePin(BOARD_LCD_RES_GPIO,BOARD_LCD_GPIO_RES_PIN,1)

#define LCD_BLK_Clr()  PINS_WritePin(BOARD_LCD_BLK_GPIO,BOARD_LCD_GPIO_BLK_PIN,0)//BLK
#define LCD_BLK_Set()  PINS_WritePin(BOARD_LCD_BLK_GPIO,BOARD_LCD_GPIO_BLK_PIN,1)

void LCD_GPIO_Init(void);//初始化GPIO
void LCD_Writ_Bus(uint8_t dat);//模拟SPI时序
void LCD_WR_DATA8(uint8_t dat);//写入一个字节
void LCD_WR_DATA(uint16_t dat);//写入两个字节
void LCD_WR_REG(uint8_t dat);//写入一个指令
void LCD_Address_Set(uint16_t x1,uint16_t y1,uint16_t x2,uint16_t y2);//设置坐标函数
void LCD_Init(void);//LCD初始化
#endif
lcd_init.c
#include "lcd_init.h"
#include "board.h"
#include "g32a1xxx_clock.h"
#include "osif.h"

/******************************************************************************
      函数说明:LCD串行数据写入函数
      入口数据:dat  要写入的串行数据
      返回值:  无
******************************************************************************/
void LCD_Writ_Bus(u8 dat)
{        
        u8 i;
        LCD_CS_Clr();
        for(i=0;i<8;i++)
        {                          
                LCD_SCLK_Clr();
                if(dat&0x80)
                {
                   LCD_MOSI_Set();
                }
                else
                {
                   LCD_MOSI_Clr();
                }
                LCD_SCLK_Set();
                dat<<=1;
        }        
  LCD_CS_Set();        
}

/******************************************************************************
      函数说明:LCD写入数据
      入口数据:dat 写入的数据
      返回值:  无
******************************************************************************/
void LCD_WR_DATA8(u8 dat)
{
        LCD_Writ_Bus(dat);
}

/******************************************************************************
      函数说明:LCD写入数据
      入口数据:dat 写入的数据
      返回值:  无
******************************************************************************/
void LCD_WR_DATA(u16 dat)
{
        LCD_Writ_Bus(dat>>8);
        LCD_Writ_Bus(dat);
}

/******************************************************************************
      函数说明:LCD写入命令
      入口数据:dat 写入的命令
      返回值:  无
******************************************************************************/
void LCD_WR_REG(u8 dat)
{
        LCD_DC_Clr();//写命令
        LCD_Writ_Bus(dat);
        LCD_DC_Set();//写数据
}

/******************************************************************************
      函数说明:设置起始和结束地址
      入口数据:x1,x2 设置列的起始和结束地址
                y1,y2 设置行的起始和结束地址
      返回值:  无
******************************************************************************/
void LCD_Address_Set(u16 x1,u16 y1,u16 x2,u16 y2)
{
        if(USE_HORIZONTAL==0)
        {
                LCD_WR_REG(0x2a);//列地址设置
                LCD_WR_DATA(x1+2);
                LCD_WR_DATA(x2+2);
                LCD_WR_REG(0x2b);//行地址设置
                LCD_WR_DATA(y1+1);
                LCD_WR_DATA(y2+1);
                LCD_WR_REG(0x2c);//储存器写
        }
        else if(USE_HORIZONTAL==1)
        {
                LCD_WR_REG(0x2a);//列地址设置
                LCD_WR_DATA(x1+2);
                LCD_WR_DATA(x2+2);
                LCD_WR_REG(0x2b);//行地址设置
                LCD_WR_DATA(y1+1);
                LCD_WR_DATA(y2+1);
                LCD_WR_REG(0x2c);//储存器写
        }
        else if(USE_HORIZONTAL==2)
        {
                LCD_WR_REG(0x2a);//列地址设置
                LCD_WR_DATA(x1+1);
                LCD_WR_DATA(x2+1);
                LCD_WR_REG(0x2b);//行地址设置
                LCD_WR_DATA(y1+2);
                LCD_WR_DATA(y2+2);
                LCD_WR_REG(0x2c);//储存器写
        }
        else
        {
                LCD_WR_REG(0x2a);//列地址设置
                LCD_WR_DATA(x1+1);
                LCD_WR_DATA(x2+1);
                LCD_WR_REG(0x2b);//行地址设置
                LCD_WR_DATA(y1+2);
                LCD_WR_DATA(y2+2);
                LCD_WR_REG(0x2c);//储存器写
        }
}

void LCD_Init(void)
{
        /* Enable Clock to Port D */
        CLOCK_SYS_ConfigModuleClock(PMD_CLK, NULL);
        PINS_SetMuxModeSel(BOARD_LCD_PORT_MOSI_BASE, BOARD_LCD_GPIO_MOSI_PIN, PM_MUX_AS_GPIO);
        PINS_SetMuxModeSel(BOARD_LCD_PORT_SCLK_BASE, BOARD_LCD_GPIO_SCLK_PIN, PM_MUX_AS_GPIO);
        PINS_SetMuxModeSel(BOARD_LCD_PORT_CS_BASE, BOARD_LCD_GPIO_CS_PIN, PM_MUX_AS_GPIO);
        PINS_SetMuxModeSel(BOARD_LCD_PORT_DC_BASE, BOARD_LCD_GPIO_DC_PIN, PM_MUX_AS_GPIO);
        PINS_SetMuxModeSel(BOARD_LCD_PORT_RES_BASE, BOARD_LCD_GPIO_RES_PIN, PM_MUX_AS_GPIO);
        PINS_SetMuxModeSel(BOARD_LCD_PORT_BLK_BASE, BOARD_LCD_GPIO_BLK_PIN, PM_MUX_AS_GPIO);
        PINS_SetPinIntSel(BOARD_LCD_PORT_MOSI_BASE, BOARD_LCD_GPIO_MOSI_PIN, PM_DMA_INT_DISABLED);
        PINS_SetPinIntSel(BOARD_LCD_PORT_SCLK_BASE, BOARD_LCD_GPIO_SCLK_PIN, PM_DMA_INT_DISABLED);
        PINS_SetPinIntSel(BOARD_LCD_PORT_CS_BASE,  BOARD_LCD_GPIO_CS_PIN, PM_DMA_INT_DISABLED);
        PINS_SetPinIntSel(BOARD_LCD_PORT_DC_BASE,  BOARD_LCD_GPIO_DC_PIN, PM_DMA_INT_DISABLED);
        PINS_SetPinIntSel(BOARD_LCD_PORT_RES_BASE, BOARD_LCD_GPIO_RES_PIN, PM_DMA_INT_DISABLED);
        PINS_SetPinIntSel(BOARD_LCD_PORT_BLK_BASE, BOARD_LCD_GPIO_BLK_PIN, PM_DMA_INT_DISABLED);
        
        PINS_SetPins(BOARD_LCD_MOSI_GPIO, 1U << BOARD_LCD_GPIO_MOSI_PIN);
        PINS_SetPins(BOARD_LCD_SCLK_GPIO, 1U << BOARD_LCD_GPIO_SCLK_PIN);
        PINS_SetPins(BOARD_LCD_CS_GPIO, 1U << BOARD_LCD_GPIO_CS_PIN);
        PINS_SetPins(BOARD_LCD_DC_GPIO, 1U << BOARD_LCD_GPIO_DC_PIN);
        PINS_SetPins(BOARD_LCD_RES_GPIO, 1U << BOARD_LCD_GPIO_RES_PIN);
        PINS_SetPins(BOARD_LCD_BLK_GPIO, 1U << BOARD_LCD_GPIO_BLK_PIN);

        PINS_SetPinDir(BOARD_LCD_MOSI_GPIO, BOARD_LCD_GPIO_MOSI_PIN, 1U);
        PINS_SetPinDir(BOARD_LCD_SCLK_GPIO, BOARD_LCD_GPIO_SCLK_PIN, 1U);
        PINS_SetPinDir(BOARD_LCD_CS_GPIO, BOARD_LCD_GPIO_CS_PIN, 1U);
        PINS_SetPinDir(BOARD_LCD_DC_GPIO, BOARD_LCD_GPIO_DC_PIN, 1U);
        PINS_SetPinDir(BOARD_LCD_RES_GPIO, BOARD_LCD_GPIO_RES_PIN, 1U);
        PINS_SetPinDir(BOARD_LCD_BLK_GPIO, BOARD_LCD_GPIO_BLK_PIN, 1U);
        
        LCD_RES_Clr();//复位
        OSIF_TimeDelay(10);
        LCD_RES_Set();
        OSIF_TimeDelay(10);
        LCD_BLK_Set();//打开背光
        OSIF_TimeDelay(120);
        LCD_WR_REG(0x11); //Sleep out
        OSIF_TimeDelay(120);

        LCD_WR_REG(0xB1);
        LCD_WR_DATA8(0x05);
        LCD_WR_DATA8(0x3C);
        LCD_WR_DATA8(0x3C);
        LCD_WR_REG(0xB2);
        LCD_WR_DATA8(0x05);
        LCD_WR_DATA8(0x3C);
        LCD_WR_DATA8(0x3C);
        LCD_WR_REG(0xB3);
        LCD_WR_DATA8(0x05);
        LCD_WR_DATA8(0x3C);
        LCD_WR_DATA8(0x3C);
        LCD_WR_DATA8(0x05);
        LCD_WR_DATA8(0x3C);
        LCD_WR_DATA8(0x3C);
        LCD_WR_REG(0xB4);
        LCD_WR_DATA8(0x03);
        LCD_WR_REG(0xC0);
        LCD_WR_DATA8(0x28);
        LCD_WR_DATA8(0x08);
        LCD_WR_DATA8(0x04);
        LCD_WR_REG(0xC1);
        LCD_WR_DATA8(0XC0);
        LCD_WR_REG(0xC2);
        LCD_WR_DATA8(0x0D);
        LCD_WR_DATA8(0x00);
        LCD_WR_REG(0xC3);
        LCD_WR_DATA8(0x8D);
        LCD_WR_DATA8(0x2A);
        LCD_WR_REG(0xC4);
        LCD_WR_DATA8(0x8D);
        LCD_WR_DATA8(0xEE);
        LCD_WR_REG(0xC5);  
        LCD_WR_DATA8(0x1A);
        LCD_WR_REG(0x36); //MX, MY, RGB mode
        if(USE_HORIZONTAL==0)LCD_WR_DATA8(0x00);
        else if(USE_HORIZONTAL==1)LCD_WR_DATA8(0xC0);
        else if(USE_HORIZONTAL==2)LCD_WR_DATA8(0x70);
        else LCD_WR_DATA8(0xA0);
        LCD_WR_REG(0xE0);
        LCD_WR_DATA8(0x04);
        LCD_WR_DATA8(0x22);
        LCD_WR_DATA8(0x07);
        LCD_WR_DATA8(0x0A);
        LCD_WR_DATA8(0x2E);
        LCD_WR_DATA8(0x30);
        LCD_WR_DATA8(0x25);
        LCD_WR_DATA8(0x2A);
        LCD_WR_DATA8(0x28);
        LCD_WR_DATA8(0x26);
        LCD_WR_DATA8(0x2E);
        LCD_WR_DATA8(0x3A);
        LCD_WR_DATA8(0x00);
        LCD_WR_DATA8(0x01);
        LCD_WR_DATA8(0x03);
        LCD_WR_DATA8(0x13);
        LCD_WR_REG(0xE1);
        LCD_WR_DATA8(0x04);
        LCD_WR_DATA8(0x16);
        LCD_WR_DATA8(0x06);
        LCD_WR_DATA8(0x0D);
        LCD_WR_DATA8(0x2D);
        LCD_WR_DATA8(0x26);
        LCD_WR_DATA8(0x23);
        LCD_WR_DATA8(0x27);
        LCD_WR_DATA8(0x27);
        LCD_WR_DATA8(0x25);
        LCD_WR_DATA8(0x2D);
        LCD_WR_DATA8(0x3B);
        LCD_WR_DATA8(0x00);
        LCD_WR_DATA8(0x01);
        LCD_WR_DATA8(0x04);
        LCD_WR_DATA8(0x13);
        LCD_WR_REG(0x3A); //65k mode
        LCD_WR_DATA8(0x05);
        LCD_WR_REG(0x29); //Display on
}
main.c
#include "user_config.h"
#include "g32a1xxx_pins.h"
#include "board.h"
#include <stdio.h>
#include "osif.h"
#include "lcd.h"
#include "lcd_init.h"
#include "pic.h"

typedef struct
{
        unsigned char Index[2];
        unsigned char Msk[32];
}typFNT_GB16;

extern const typFNT_GB16 tfont16[];

#define LED_GPIO            GPIOD
#define BLUE_LED_PIN        (0U)
#define RED_LED_PIN         (15U)
#define GREEN_LED_PIN       (16U)

#define WHITE_LED_PIN       (~0x00018001)

/*!
* [url=home.php?mod=space&uid=247401]@brief[/url]   Pins module initialization LED light
*/
void PINS_Led_Init()
{
    /* Enable Clock to Port D */
    CLOCK_SYS_ConfigModuleClock(PMD_CLK, NULL);
    /* Set pin mode */
    PINS_SetMuxModeSel(LED_RED_PORT_BASE, LED_RED_PIN, PM_MUX_AS_GPIO);
    PINS_SetMuxModeSel(LED_GREEN_PORT_BASE, LED_GREEN_PIN, PM_MUX_AS_GPIO);
    PINS_SetMuxModeSel(LED_BLUE_PORT_BASE, LED_BLUE_PIN, PM_MUX_AS_GPIO);
    /* Set pin interrupt */
    PINS_SetPinIntSel(LED_RED_PORT_BASE, LED_RED_PIN, PM_DMA_INT_DISABLED);
    PINS_SetPinIntSel(LED_GREEN_PORT_BASE, LED_GREEN_PIN, PM_DMA_INT_DISABLED);
    PINS_SetPinIntSel(LED_BLUE_PORT_BASE, LED_BLUE_PIN, PM_DMA_INT_DISABLED);
    /* GPIO Initialization */
    PINS_SetPins(LED_RED_GPIO_BASE, 1U << LED_RED_PIN);
    PINS_SetPins(LED_GREEN_GPIO_BASE, 1U << LED_GREEN_PIN);
    PINS_SetPins(LED_BLUE_GPIO_BASE, 1U << LED_BLUE_PIN);
    /* Set pin as output */
    PINS_SetPinDir(LED_RED_GPIO_BASE, LED_RED_PIN, 1U);
    PINS_SetPinDir(LED_GREEN_GPIO_BASE, LED_GREEN_PIN, 1U);
    PINS_SetPinDir(LED_BLUE_GPIO_BASE, LED_BLUE_PIN, 1U);
}

void Display_title(void)
{
        LCD_Fill(0,0,LCD_W,LCD_H,LIGHTBLUE);
        LCD_ShowIntNum(8,10,2025,4,BLUE,GREEN,16);
        LCD_ShowChinese(40,10,&tfont16[0],BLUE,GREEN,16,0);
        LCD_ShowChinese(56,10,&tfont16[1],BLUE,GREEN,16,0);
        LCD_ShowChinese(72,10,&tfont16[2],BLUE,GREEN,16,0);
        LCD_ShowChinese(88,10,&tfont16[3],BLUE,GREEN,16,0);
        LCD_ShowChinese(104,10,&tfont16[4],BLUE,GREEN,16,0);
        LCD_ShowChinese(8,30,&tfont16[5],BLUE,GREEN,16,0);
        LCD_ShowChinese(24,30,&tfont16[6],BLUE,GREEN,16,0);
        LCD_ShowChinese(40,30,&tfont16[7],BLUE,GREEN,16,0);
        LCD_ShowChinese(56,30,&tfont16[8],BLUE,GREEN,16,0);
        LCD_ShowString(72,30,"A1465",RED,GREEN,16,0);
        LCD_ShowChinese(8,50,&tfont16[9],BLUE,GREEN,16,0);
        LCD_ShowChinese(24,50,&tfont16[10],BLUE,GREEN,16,0);
        LCD_ShowChinese(40,50,&tfont16[11],BLUE,GREEN,16,0);
        LCD_ShowChinese(56,50,&tfont16[12],BLUE,GREEN,16,0);
        LCD_ShowChinese(72,50,&tfont16[13],BLUE,GREEN,16,0);
        LCD_ShowChinese(88,50,&tfont16[14],BLUE,GREEN,16,0);
        LCD_ShowChinese(104,50,&tfont16[15],BLUE,GREEN,16,0);
        LCD_ShowString(43,140,"2025-01-05",BLUE,GREEN,16,0);
        OSIF_TimeDelay(500);
}

/*!
* [url=home.php?mod=space&uid=247401]@brief[/url]   Main function
*/
int main(void)
{
    /* Initialize clock */
    CLOCK_SYS_Init(&g_clockConfig);
    /* led init */
    PINS_Led_Init();
    /* uart init */
    COM_Init();
    /* Initialize LCD */
    LCD_Init();
    OSIF_TimeDelay(200U);
    LCD_Fill(0,0,LCD_W,LCD_H,YELLOW);
    OSIF_TimeDelay(200);
    LCD_Fill(0,0,LCD_W,LCD_H,WHITE);
    PINS_WritePins(LED_GPIO,WHITE_LED_PIN);
    while (1)
    {
                                PINS_ClrPins(LED_RED_GPIO_BASE, 1U << LED_RED_PIN);
                                PINS_SetPins(LED_GREEN_GPIO_BASE, 1U << LED_GREEN_PIN);
                                PINS_SetPins(LED_BLUE_GPIO_BASE, 1U << LED_BLUE_PIN);
                                OSIF_TimeDelay(200);
                                PINS_SetPins(LED_RED_GPIO_BASE, 1U << LED_RED_PIN);
                                PINS_ClrPins(LED_GREEN_GPIO_BASE, 1U << LED_GREEN_PIN);
                                PINS_SetPins(LED_BLUE_GPIO_BASE, 1U << LED_BLUE_PIN);
                                OSIF_TimeDelay(200);
                                PINS_SetPins(LED_RED_GPIO_BASE, 1U << LED_RED_PIN);
                                PINS_SetPins(LED_GREEN_GPIO_BASE, 1U << LED_GREEN_PIN);
                                PINS_ClrPins(LED_BLUE_GPIO_BASE, 1U << LED_BLUE_PIN);
                                OSIF_TimeDelay(200);
                                PINS_SetPins(LED_RED_GPIO_BASE, 1U << LED_RED_PIN);
                                PINS_SetPins(LED_GREEN_GPIO_BASE, 1U << LED_GREEN_PIN);
                                PINS_SetPins(LED_BLUE_GPIO_BASE, 1U << LED_BLUE_PIN);
                                LCD_ShowPicture(0,0,128,160,gImage_1);
                                OSIF_TimeDelay(800);
                                Display_title();
    }
}
五、画图效果
画图采用“Img2Lcd”工具,轻松实现由图片转C代码的处理,至于中文字符的生成,可借助“PCtoLCD2002”工具,如见以下附件,具体使用方法这里不再赘述。
Image2Lcd 2.9.zip (506.51 KB)
PCtoLCD2002.zip (886.17 KB)
使用工具导入图片后设置如下,导出则是C数组,直接调用则行。

屏上画出来的效果如下:

驱动程序点屏效果展现如下:
点屏.zip (1.16 MB)

使用特权

评论回复
沙发
这个极小海的玩偶好可爱

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

101

主题

1030

帖子

7

粉丝