yinwuqing 发表于 2024-12-4 00:02:53

【Avnet | NXP FRDM-MCXN947试用活动】驱动TFT彩屏

本帖最后由 yinwuqing 于 2024-12-4 00:22 编辑

一、简介
本次采用SPI方式驱动ST7735S TFT-LCD屏。ST7735S是用于262K彩色图形型TFT-LCD的单芯片控制器/驱动器。由396条组成源极线和162个栅极线驱动电路。该芯片能够直接连接到外部微处理器,并接受串行外围接口(SPI)、8位/9位/16位/18位并行接口。显示数据可以存储在132 x 162 x 18位的片上显示数据RAM中。它可以执行显示数据RAM读/写操作,无需外部操作时钟,可最大限度地降低功耗。此外,由于驱动液晶所需的集成电源电路具有较少组件的显示系统。


二、硬件连线
   该屏为1.8寸,宽高:128 x 160,本人采用的是基于硬禾学堂提供的外设底板,该部分电路原理图如下:

由上电路原理图可知,该外设底板集成的LCD屏是具备触摸功能的,此次就单单显示部分功能进行驱动。
   再来看FRDM-MCXN947开发板的原理图部分,两者信号脚确认好后,才能使用杜邦线进行正确连接。

两块板子信号脚的连接布设如下:

ST7735STFT-LCD屏 FRDM-MCXN947开发板
VCCP3V3
GND GND
SCLK P4_1(SCL)
MOSIP4_0(SDA)
DC(Data/Command)P0_7
CS(Chip Select) P0_12
BLK(Backlight) P4_5
RES P4_7
硬件连接图:


三、代码实现
    本次工程还是在上期点灯例程上进行完善吧,首先在pin_mux.c文件中加入io的初始化代码。
void BOARD_InitPins(void)
{
/* Enables the clock for PORT0 controller: Enables clock */
CLOCK_EnableClock(kCLOCK_Port0);
/* Enables the clock for PORT1 controller: Enables clock */
CLOCK_EnableClock(kCLOCK_Port1);
CLOCK_EnableClock(kCLOCK_Port4);

gpio_pin_config_t LCD_GPIO_config0 = {
      .pinDirection = kGPIO_DigitalOutput,
      .outputLogic = 0U,
};
gpio_pin_config_t LCD_GPIO_config1 = {
      .pinDirection = kGPIO_DigitalOutput,
      .outputLogic = 1U,
};
      
GPIO_PinInit(GPIO0, 7U, &LCD_GPIO_config0);
GPIO_PinInit(GPIO0, 12U, &LCD_GPIO_config0);
GPIO_PinInit(GPIO4, 0U, &LCD_GPIO_config0);
GPIO_PinInit(GPIO4, 1U, &LCD_GPIO_config0);
GPIO_PinInit(GPIO4, 5U, &LCD_GPIO_config0);
GPIO_PinInit(GPIO4, 7U, &LCD_GPIO_config0);
      
PORT_SetPinMux(PORT0, 7U, kPORT_MuxAlt0);
PORT_SetPinMux(PORT0, 12U,kPORT_MuxAlt0);
PORT_SetPinMux(PORT4, 0U, kPORT_MuxAlt0);
PORT_SetPinMux(PORT4, 1U, kPORT_MuxAlt0);
PORT_SetPinMux(PORT4, 5U, kPORT_MuxAlt0);
PORT_SetPinMux(PORT4, 7U, kPORT_MuxAlt0);

const port_pin_config_t port0_7_config= {/* Internal pull-up/down resistor is disabled */
                                                      kPORT_PullDisable,
                                                      /* Low internal pull resistor value is selected. */
                                                      kPORT_LowPullResistor,
                                                      /* Fast slew rate is configured */
                                                      kPORT_FastSlewRate,
                                                      /* Passive input filter is disabled */
                                                      kPORT_PassiveFilterDisable,
                                                      /* Open drain output is disabled */
                                                      kPORT_OpenDrainDisable,
                                                      /* Low drive strength is configured */
                                                      kPORT_LowDriveStrength,
                                                      /* Pin is configured as PIO0_10 */
                                                      kPORT_MuxAlt0,
                                                      /* Digital input enabled */
                                                      kPORT_InputBufferEnable,
                                                      /* Digital input is not inverted */
                                                      kPORT_InputNormal,
                                                      /* Pin Control Register fields are not locked */
                                                      kPORT_UnlockRegister};

const port_pin_config_t port0_10_pinB12_config = {/* Internal pull-up/down resistor is disabled */
                                                      kPORT_PullDisable,
                                                      /* Low internal pull resistor value is selected. */
                                                      kPORT_LowPullResistor,
                                                      /* Fast slew rate is configured */
                                                      kPORT_FastSlewRate,
                                                      /* Passive input filter is disabled */
                                                      kPORT_PassiveFilterDisable,
                                                      /* Open drain output is disabled */
                                                      kPORT_OpenDrainDisable,
                                                      /* Low drive strength is configured */
                                                      kPORT_LowDriveStrength,
                                                      /* Pin is configured as PIO0_10 */
                                                      kPORT_MuxAlt0,
                                                      /* Digital input enabled */
                                                      kPORT_InputBufferEnable,
                                                      /* Digital input is not inverted */
                                                      kPORT_InputNormal,
                                                      /* Pin Control Register fields are not locked */
                                                      kPORT_UnlockRegister};
    /* PORT0_10 (pin B12) is configured as PIO0_10 */
    PORT_SetPinConfig(PORT0, 10U, &port0_10_pinB12_config);
                                                                                                                                                                                                                        
   const port_pin_config_t port0_27_pinE10_config = {/* Internal pull-up/down resistor is disabled */
                                                      kPORT_PullDisable,
                                                      /* Low internal pull resistor value is selected. */
                                                      kPORT_LowPullResistor,
                                                      /* Fast slew rate is configured */
                                                      kPORT_FastSlewRate,
                                                      /* Passive input filter is disabled */
                                                      kPORT_PassiveFilterDisable,
                                                      /* Open drain output is disabled */
                                                      kPORT_OpenDrainDisable,
                                                      /* Low drive strength is configured */
                                                      kPORT_LowDriveStrength,
                                                      /* Pin is configured as PIO0_27 */
                                                      kPORT_MuxAlt0,
                                                      /* Digital input enabled */
                                                      kPORT_InputBufferEnable,
                                                      /* Digital input is not inverted */
                                                      kPORT_InputNormal,
                                                      /* Pin Control Register fields are not locked */
                                                      kPORT_UnlockRegister};
    /* PORT0_27 (pin E10) is configured as PIO0_27 */
    PORT_SetPinConfig(PORT0, 27U, &port0_27_pinE10_config);

const port_pin_config_t port1_2_pinC04_config = {/* Internal pull-up/down resistor is disabled */
                                                      kPORT_PullDisable,
                                                      /* Low internal pull resistor value is selected. */
                                                      kPORT_LowPullResistor,
                                                      /* Fast slew rate is configured */
                                                      kPORT_FastSlewRate,
                                                      /* Passive input filter is disabled */
                                                      kPORT_PassiveFilterDisable,
                                                      /* Open drain output is disabled */
                                                      kPORT_OpenDrainDisable,
                                                      /* Low drive strength is configured */
                                                      kPORT_LowDriveStrength,
                                                      /* Pin is configured as PIO1_2 */
                                                      kPORT_MuxAlt0,
                                                      /* Digital input enabled */
                                                      kPORT_InputBufferEnable,
                                                      /* Digital input is not inverted */
                                                      kPORT_InputNormal,
                                                      /* Pin Control Register fields are not locked */
                                                      kPORT_UnlockRegister};
    /* PORT1_2 (pin C04) is configured as PIO1_2 */
    PORT_SetPinConfig(PORT1, 2U, &port1_2_pinC04_config);                                                                                                                                                                                                                        

const port_pin_config_t port0_2_pinB16_config = {/* Internal pull-up/down resistor is disabled */
                                                   kPORT_PullDisable,
                                                   /* Low internal pull resistor value is selected. */
                                                   kPORT_LowPullResistor,
                                                   /* Fast slew rate is configured */
                                                   kPORT_FastSlewRate,
                                                   /* Passive input filter is disabled */
                                                   kPORT_PassiveFilterDisable,
                                                   /* Open drain output is disabled */
                                                   kPORT_OpenDrainDisable,
                                                   /* High drive strength is configured */
                                                   kPORT_HighDriveStrength,
                                                   /* Pin is configured as SWO */
                                                   kPORT_MuxAlt1,
                                                   /* Digital input enabled */
                                                   kPORT_InputBufferEnable,
                                                   /* Digital input is not inverted */
                                                   kPORT_InputNormal,
                                                   /* Pin Control Register fields are not locked */
                                                   kPORT_UnlockRegister};
    /* PORT0_2 (pin B16) is configured as SWO */
    PORT_SetPinConfig(PORT0, 2U, &port0_2_pinB16_config);                                                                     
    PORT_SetPinConfig(PORT0, 7U, &port0_7_config);
    PORT_SetPinConfig(PORT0, 12U,&port0_7_config);
    PORT_SetPinConfig(PORT4, 0U, &port0_7_config);
    PORT_SetPinConfig(PORT4, 1U, &port0_7_config);
    PORT_SetPinConfig(PORT4, 5U, &port0_7_config);
    PORT_SetPinConfig(PORT4, 7U, &port0_7_config);
}lcd_init.c
#include "lcd_init.h"
#include "board.h"
#include "peripherals.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)
{
      
      LCD_RES_Clr();//复位
      SysTick_DelayTicks(1000);
      LCD_RES_Set();
      SysTick_DelayTicks(1000);
      
      LCD_BLK_Set();//打开背光
      SysTick_DelayTicks(120000);
      
      //************* Start Initial Sequence **********//
      LCD_WR_REG(0x11); //Sleep out
      SysTick_DelayTicks(120000);            //Delay 120ms
      //------------------------------------ST7735S Frame Rate-----------------------------------------//
      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);
      //------------------------------------End ST7735S Frame Rate---------------------------------//
      LCD_WR_REG(0xB4); //Dot inversion
      LCD_WR_DATA8(0x03);
      //------------------------------------ST7735S Power Sequence---------------------------------//
      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);
      //---------------------------------End ST7735S Power Sequence-------------------------------------//
      LCD_WR_REG(0xC5); //VCOM
      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);
      //------------------------------------ST7735S Gamma Sequence---------------------------------//
      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);
      //------------------------------------End ST7735S Gamma Sequence-----------------------------//
      LCD_WR_REG(0x3A); //65k mode
      LCD_WR_DATA8(0x05);
      LCD_WR_REG(0x29); //Display on
}
lcd_init.h
#ifndef __LCD_INIT_H
#define __LCD_INIT_H

#include "board.h"
#include "pin_mux.h"
#include "lcd.h"

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

typedef uint32_t u32;
typedef uint16_t u16;
typedef uint8_t u8;

#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_SCLK_GPIO GPIO4
#define BOARD_LCD_GPIO_SCLK_PIN (1U)

#define BOARD_LCD_CS_GPIO GPIO0
#define BOARD_LCD_GPIO_CS_PIN   (12U)

#define BOARD_LCD_MOSI_GPIO GPIO4
#define BOARD_LCD_GPIO_MOSI_PIN (0U)

#define BOARD_LCD_DC_GPIO GPIO0
#define BOARD_LCD_GPIO_DC_PIN   (7U)

#define BOARD_LCD_RES_GPIO GPIO4
#define BOARD_LCD_GPIO_RES_PIN(7U)

#define BOARD_LCD_BLK_GPIO GPIO4
#define BOARD_LCD_GPIO_BLK_PIN(5U)

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

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

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

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

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

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

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


void LCD_GPIO_Init(void);//初始化GPIO
void LCD_Writ_Bus(u8 dat);//模拟SPI时序
void LCD_WR_DATA8(u8 dat);//写入一个字节
void LCD_WR_DATA(u16 dat);//写入两个字节
void LCD_WR_REG(u8 dat);//写入一个指令
void LCD_Address_Set(u16 x1,u16 y1,u16 x2,u16 y2);//设置坐标函数
void LCD_Init(void);//LCD初始化
#endif
其它显示字符的接口函数如下:
/******************************************************************************
      函数说明:显示汉字串
      入口数据:x,y显示坐标
                *s 要显示的汉字串
                fc 字的颜色
                bc 字的背景色
                sizey 字号 可选 16 24 32
                mode:0非叠加模式1叠加模式
      返回值:无
******************************************************************************/
void LCD_ShowChinese(u16 x,u16 y,u8 *s,u16 fc,u16 bc,u8 sizey,u8 mode)
{
      while(*s!=0)
      {
                if(sizey==12) LCD_ShowChinese12x12(x,y,s,fc,bc,sizey,mode);
                else if(sizey==16) LCD_ShowChinese16x16(x,y,s,fc,bc,sizey,mode);
                else if(sizey==24) LCD_ShowChinese24x24(x,y,s,fc,bc,sizey,mode);
                else if(sizey==32) LCD_ShowChinese32x32(x,y,s,fc,bc,sizey,mode);
                else return;
                s+=1;
                x+=((128/sizey)+(128%sizey));
      }
}

/******************************************************************************
      函数说明:显示单个12x12汉字
      入口数据:x,y显示坐标
                *s 要显示的汉字
                fc 字的颜色
                bc 字的背景色
                sizey 字号
                mode:0非叠加模式1叠加模式
      返回值:无
******************************************************************************/
void LCD_ShowChinese12x12(u16 x,u16 y,u8 *s,u16 fc,u16 bc,u8 sizey,u8 mode)
{
      u8 i,j,m=0;
      u16 k;
      u16 HZnum;//汉字数目
      u16 TypefaceNum;//一个字符所占字节大小
      u16 x0=x;
      TypefaceNum=(sizey/8+((sizey%8)?1:0))*sizey;
                                 
      HZnum=sizeof(tfont12)/sizeof(typFNT_GB12);      //统计汉字数目
      for(k=0;k<HZnum;k++)
      {
                if((tfont12.Index==*(s))&&(tfont12.Index==*(s+1)))
                {         
                        LCD_Address_Set(x,y,x+sizey-1,y+sizey-1);
                        for(i=0;i<TypefaceNum;i++)
                        {
                              for(j=0;j<8;j++)
                              {      
                                        if(!mode)//非叠加方式
                                        {
                                                if(tfont12.Msk&(0x01<<j))LCD_WR_DATA(fc);
                                                else LCD_WR_DATA(bc);
                                                m++;
                                                if(m%sizey==0)
                                                {
                                                      m=0;
                                                      break;
                                                }
                                        }
                                        else//叠加方式
                                        {
                                                if(tfont12.Msk&(0x01<<j))      LCD_DrawPoint(x,y,fc);//画一个点
                                                x++;
                                                if((x-x0)==sizey)
                                                {
                                                      x=x0;
                                                      y++;
                                                      break;
                                                }
                                        }
                              }
                        }
                }                                          
                continue;//查找到对应点阵字库立即退出,防止多个汉字重复取模带来影响
      }
}

/******************************************************************************
      函数说明:显示单个16x16汉字
      入口数据:x,y显示坐标
                *s 要显示的汉字
                fc 字的颜色
                bc 字的背景色
                sizey 字号
                mode:0非叠加模式1叠加模式
      返回值:无
******************************************************************************/
void LCD_ShowChinese16x16(u16 x,u16 y,u8 *s,u16 fc,u16 bc,u8 sizey,u8 mode)
{
      u8 i,j,m=0;
      u16 k;
      u16 HZnum;//汉字数目
      u16 TypefaceNum;//一个字符所占字节大小
      u16 x0=x;
TypefaceNum=(sizey/8+((sizey%8)?1:0))*sizey;
      HZnum=sizeof(tfont16)/sizeof(typFNT_GB16);      //统计汉字数目
      for(k=0;k<HZnum;k++)
      {
                if ((tfont16.Index==*(s))&&(tfont16.Index==*(s+1)))
                {         
                        LCD_Address_Set(x,y,x+sizey-1,y+sizey-1);
                        for(i=0;i<TypefaceNum;i++)
                        {
                              for(j=0;j<8;j++)
                              {      
                                        if(!mode)//非叠加方式
                                        {
                                                if(tfont16.Msk&(0x01<<j))LCD_WR_DATA(fc);
                                                else LCD_WR_DATA(bc);
                                                m++;
                                                if(m%sizey==0)
                                                {
                                                      m=0;
                                                      break;
                                                }
                                        }
                                        else//叠加方式
                                        {
                                                if(tfont16.Msk&(0x01<<j))      LCD_DrawPoint(x,y,fc);//画一个点
                                                x++;
                                                if((x-x0)==sizey)
                                                {
                                                      x=x0;
                                                      y++;
                                                      break;
                                                }
                                        }
                              }
                        }
                }                                          
                continue;//查找到对应点阵字库立即退出,防止多个汉字重复取模带来影响
      }
}

/******************************************************************************
      函数说明:显示单个24x24汉字
      入口数据:x,y显示坐标
                *s 要显示的汉字
                fc 字的颜色
                bc 字的背景色
                sizey 字号
                mode:0非叠加模式1叠加模式
      返回值:无
******************************************************************************/
void LCD_ShowChinese24x24(u16 x,u16 y,u8 *s,u16 fc,u16 bc,u8 sizey,u8 mode)
{
      u8 i,j,m=0;
      u16 k;
      u16 HZnum;//汉字数目
      u16 TypefaceNum;//一个字符所占字节大小
      u16 x0=x;
      TypefaceNum=(sizey/8+((sizey%8)?1:0))*sizey;
      HZnum=sizeof(tfont24)/sizeof(typFNT_GB24);      //统计汉字数目
      for(k=0;k<HZnum;k++)
      {
                if ((tfont24.Index==*(s))&&(tfont24.Index==*(s+1)))
                {         
                        LCD_Address_Set(x,y,x+sizey-1,y+sizey-1);
                        for(i=0;i<TypefaceNum;i++)
                        {
                              for(j=0;j<8;j++)
                              {      
                                        if(!mode)//非叠加方式
                                        {
                                                if(tfont24.Msk&(0x01<<j))LCD_WR_DATA(fc);
                                                else LCD_WR_DATA(bc);
                                                m++;
                                                if(m%sizey==0)
                                                {
                                                      m=0;
                                                      break;
                                                }
                                        }
                                        else//叠加方式
                                        {
                                                if(tfont24.Msk&(0x01<<j))      LCD_DrawPoint(x,y,fc);//画一个点
                                                x++;
                                                if((x-x0)==sizey)
                                                {
                                                      x=x0;
                                                      y++;
                                                      break;
                                                }
                                        }
                              }
                        }
                }                                          
                continue;//查找到对应点阵字库立即退出,防止多个汉字重复取模带来影响
      }
}

/******************************************************************************
      函数说明:显示单个32x32汉字
      入口数据:x,y显示坐标
                *s 要显示的汉字
                fc 字的颜色
                bc 字的背景色
                sizey 字号
                mode:0非叠加模式1叠加模式
      返回值:无
******************************************************************************/
void LCD_ShowChinese32x32(u16 x,u16 y,u8 *s,u16 fc,u16 bc,u8 sizey,u8 mode)
{
      u8 i,j,m=0;
      u16 k;
      u16 HZnum;//汉字数目
      u16 TypefaceNum;//一个字符所占字节大小
      u16 x0=x;
      TypefaceNum=(sizey/8+((sizey%8)?1:0))*sizey;
      HZnum=sizeof(tfont32)/sizeof(typFNT_GB32);      //统计汉字数目
      for(k=0;k<HZnum;k++)
      {
                if ((tfont32.Index==*(s))&&(tfont32.Index==*(s+1)))
                {         
                        LCD_Address_Set(x,y,x+sizey-1,y+sizey-1);
                        for(i=0;i<TypefaceNum;i++)
                        {
                              for(j=0;j<8;j++)
                              {      
                                        if(!mode)//非叠加方式
                                        {
                                                if(tfont32.Msk&(0x01<<j))LCD_WR_DATA(fc);
                                                else LCD_WR_DATA(bc);
                                                m++;
                                                if(m%sizey==0)
                                                {
                                                      m=0;
                                                      break;
                                                }
                                        }
                                        else//叠加方式
                                        {
                                                if(tfont32.Msk&(0x01<<j))      LCD_DrawPoint(x,y,fc);//画一个点
                                                x++;
                                                if((x-x0)==sizey)
                                                {
                                                      x=x0;
                                                      y++;
                                                      break;
                                                }
                                        }
                              }
                        }
                }                                          
                continue;//查找到对应点阵字库立即退出,防止多个汉字重复取模带来影响
      }
}

/******************************************************************************
      函数说明:显示单个字符
      入口数据:x,y显示坐标
                num 要显示的字符
                fc 字的颜色
                bc 字的背景色
                sizey 字号
                mode:0非叠加模式1叠加模式
      返回值:无
******************************************************************************/
void LCD_ShowChar(u16 x,u16 y,u8 num,u16 fc,u16 bc,u8 sizey,u8 mode)
{
      u8 temp,sizex,t,m=0;
      u16 i,TypefaceNum;//一个字符所占字节大小
      u16 x0=x;
      sizex=sizey/2;
      TypefaceNum=(sizex/8+((sizex%8)?1:0))*sizey;
      num=num-' ';    //得到偏移后的值
      LCD_Address_Set(x,y,x+sizex-1,y+sizey-1);//设置光标位置
      for(i=0;i<TypefaceNum;i++)
      {
                if(sizey==12)temp=ascii_1206;                     //调用6x12字体
                else if(sizey==16)temp=ascii_1608;               //调用8x16字体
                else if(sizey==24)temp=ascii_2412;               //调用12x24字体
                else if(sizey==32)temp=ascii_3216;               //调用16x32字体
                else return;
                for(t=0;t<8;t++)
                {
                        if(!mode)//非叠加模式
                        {
                              if(temp&(0x01<<t))LCD_WR_DATA(fc);
                              else LCD_WR_DATA(bc);
                              m++;
                              if(m%sizex==0)
                              {
                                        m=0;
                                        break;
                              }
                        }
                        else//叠加模式
                        {
                              if(temp&(0x01<<t))LCD_DrawPoint(x,y,fc);//画一个点
                              x++;
                              if((x-x0)==sizex)
                              {
                                        x=x0;
                                        y++;
                                        break;
                              }
                        }
                }
      }                     
}

/******************************************************************************
      函数说明:显示字符串
      入口数据:x,y显示坐标
                *p 要显示的字符串
                fc 字的颜色
                bc 字的背景色
                sizey 字号
                mode:0非叠加模式1叠加模式
      返回值:无
******************************************************************************/
void LCD_ShowString(u16 x,u16 y,const u8 *p,u16 fc,u16 bc,u8 sizey,u8 mode)
{         
      while(*p!='\0')
      {      
                LCD_ShowChar(x,y,*p,fc,bc,sizey,mode);
                x+=sizey/2;
                p++;
      }
}main.c
#include "pin_mux.h"
#include "peripherals.h"
#include "board.h"
#include "pic.h"
#include "lcd_init.h"
/*******************************************************************************
* Definitions
******************************************************************************/

typedef struct
{
      unsigned char Index;
      unsigned char Msk;
}typFNT_GB16;
/*******************************************************************************
* Prototypes
******************************************************************************/
extern const typFNT_GB16 tfont16[];
/*******************************************************************************
* Variables
******************************************************************************/
volatile uint32_t g_systickCounter;
/*******************************************************************************
* Code
******************************************************************************/

void SysTick_Handler(void)
{
    if (g_systickCounter != 0U)
    {
      g_systickCounter--;
    }
}

void SysTick_DelayTicks(uint32_t n)
{
    g_systickCounter = n;
    while (g_systickCounter != 0U)
    {
    }
}

void Display_title(void)
{
      LCD_Fill(0,0,LCD_W,LCD_H,WHITE);
      LCD_ShowIntNum(8,10,2024,4,RED,BLACK,16);
      LCD_ShowChinese(40,10,&tfont16,RED,BLACK,16,0);
      LCD_ShowChinese(56,10,&tfont16,RED,BLACK,16,0);
      LCD_ShowChinese(72,10,&tfont16,RED,BLACK,16,0);
      LCD_ShowChinese(88,10,&tfont16,RED,BLACK,16,0);
      LCD_ShowChinese(104,10,&tfont16,RED,BLACK,16,0);
      LCD_ShowChinese(8,30,&tfont16,RED,BLACK,16,0);
      LCD_ShowChinese(24,30,&tfont16,RED,BLACK,16,0);
      LCD_ShowString(40,30,"MCX",RED,BLACK,16,0);
      LCD_ShowString(64,30," ",BLACK,BLACK,16,0);
      LCD_ShowString(72,30,"N",RED,BLACK,16,0);
      LCD_ShowString(80,30," ",BLACK,BLACK,16,0);
      LCD_ShowChinese(88,30,&tfont16,RED,BLACK,16,0);
      LCD_ShowChinese(104,30,&tfont16,RED,BLACK,16,0);
      
      LCD_ShowChinese(8,50,&tfont16,RED,BLACK,16,0);
      LCD_ShowChinese(24,50,&tfont16,RED,BLACK,16,0);
      LCD_ShowChinese(40,50,&tfont16,RED,BLACK,16,0);
      LCD_ShowChinese(56,50,&tfont16,RED,BLACK,16,0);
      LCD_ShowChinese(72,50,&tfont16,RED,BLACK,16,0);
      LCD_ShowChinese(88,50,&tfont16,RED,BLACK,16,0);
      LCD_ShowChinese(104,50,&tfont16,RED,BLACK,16,0);
      LCD_ShowChinese(8,70,&tfont16,RED,BLACK,16,0);
      LCD_ShowChinese(24,70,&tfont16,RED,BLACK,16,0);
      LCD_ShowString(56,70,"2024-12-02",BLUE,BROWN,12,0);
       for(uint8_t num=0; num<3; num++)
      {
                LCD_ShowPicture(0,87,128,160,gImage_21);
                LCD_ShowPicture(0,87,128,160,gImage_22);
                LCD_ShowPicture(0,87,128,160,gImage_23);
                LCD_ShowPicture(0,87,128,160,gImage_24);
                LCD_ShowPicture(0,87,128,160,gImage_25);
      }
}

int main(void)
{
    /* Board pin init */
    CLOCK_EnableClock(kCLOCK_Gpio0);
    CLOCK_EnableClock(kCLOCK_Gpio1);
    CLOCK_EnableClock(kCLOCK_Gpio4);
    BOARD_InitPins();
    LED_RED_INIT(LOGIC_LED_OFF);
    LED_BLUE_INIT(LOGIC_LED_OFF);
    LED_GREEN_INIT(LOGIC_LED_OFF);
      
    /* Set systick reload value to generate 1us interrupt */
    if (SysTick_Config(SystemCoreClock / 1000000U))
    {
      while (1)
      {
      }
    }
               
      LCD_Init();
      SysTick_DelayTicks(200U);
      LCD_Fill(0,0,LCD_W,LCD_H,YELLOW);
      SysTick_DelayTicks(200);
      LCD_Fill(0,0,LCD_W,LCD_H,WHITE);
      while (1)
      {
            LCD_ShowPicture(4,0,128,160,gImage_1);
            Display_title();
      }
}
四、下载运行
      编译通过后,将程序下载到FRDM-MCXN947开发板中,显示效果如下:



NXP FRDM-MCXN947驱动TFT-LCD屏
https://www.bilibili.com/video/BV1bTzSYfEyh/

【NXP FRDM-MCXN947驱动TFT-LCD屏】 https://www.bilibili.com/video/BV1bTzSYfEyh/?share_source=copy_web&vd_source=e6778606bed9c8e5e7d4db72f6889b7f

页: [1]
查看完整版本: 【Avnet | NXP FRDM-MCXN947试用活动】驱动TFT彩屏