6147 views|7 replies

205

Posts

0

Resources
The OP
 

[HC32F460 Development Board Review] 08. Hardware SPI interface drives TFT LCD screen [Copy link]

 

The HC32F460 development board has a hardware SPI interface J18, which is convenient for functional expansion with external hardware in the form of a pin header. This experiment mainly uses the hardware SPI interface to drive a TFT LCD screen with an SPI interface to refresh the screen;

J18 SPI interface principle diagram:

The connection between the SPI interface pins and the MCU pins is shown in the following figure:

We use a 1.44-inch TFT LCD display with an SPI interface. The screen resolution is 128*128. The operation interface definition is shown in the figure below:

We can see that in addition to the power supply and SPI interface, three control pins are required to operate this TFT LCD screen. We use the three pins 20, 19, and 18 (PC0~PC2) in the MOTOR interface to control BL, D/C, and RES respectively, as shown in the following figure:

The actual picture of the LCD screen is as follows:

Program source docker file:

/*******************************************************************************
 * @file    MD144.h
 * @author  xld0932
 * [url=home.php?mod=space&uid=252314]@version[/url] V1.00
 * [url=home.php?mod=space&uid=311857]@date[/url] 31-Mar-2021
 * [url=home.php?mod=space&uid=159083]@brief[/url] ......
*******************************************************************************/


/* Define to prevent recursive inclusion -------------------------------------*/
#ifndef __MD144_H__
#define __MD144_H__


#ifdef __cplusplus
extern "C" {
#endif


#undef  EXTERN


#ifdef  __MD144_C__
#define EXTERN
#else
#define EXTERN extern
#endif


/* Includes ------------------------------------------------------------------*/
#include "config.h"


/* Exported constants --------------------------------------------------------*/
/* Exported types ------------------------------------------------------------*/


/* Exported macro ------------------------------------------------------------*/
#define RGB(r, g, b)    (((uint16_t)(r) << 10) & 0xF800) |  \
                        (((uint16_t)(g) <<  5) & 0x07E0) |  \
                        (((uint16_t)(b) <<  0) & 0x001F)


/* Exported functions --------------------------------------------------------*/
EXTERN void MD144_Init(void);
EXTERN void MD144_Demo(void);


#ifdef __cplusplus
}
#endif


#endif


/******************* (C) COPYRIGHT 2021 *************************END OF FILE***/

Program source code Source program:

/*******************************************************************************
 * @file    MD144.c
 * @author  xld0932
 * @version V1.00
 * @date    31-Mar-2021
 * @brief   ......
*******************************************************************************/


/* Define to prevent recursive inclusion -------------------------------------*/
#define __MD144_C__


/* Includes ------------------------------------------------------------------*/
#include "MD144.h"


/* Private typedef -----------------------------------------------------------*/
/* Private define ------------------------------------------------------------*/


/* Private macro -------------------------------------------------------------*/
#define MD144_BL_H()    PORT_SetBits(  PortC, Pin00)
#define MD144_BL_L()    PORT_ResetBits(PortC, Pin00)

#define MD144_CS_H()    PORT_SetBits(  PortE, Pin01)
#define MD144_CS_L()    PORT_ResetBits(PortE, Pin01)

#define MD144_DC_H()    PORT_SetBits(  PortC, Pin01)
#define MD144_DC_L()    PORT_ResetBits(PortC, Pin01)

#define MD144_RES_H()   PORT_SetBits(  PortC, Pin02)
#define MD144_RES_L()   PORT_ResetBits(PortC, Pin02)


/* Private variables ---------------------------------------------------------*/
/* Private function prototypes -----------------------------------------------*/
/* Private functions ---------------------------------------------------------*/


/* Exported variables --------------------------------------------------------*/
/* Exported function prototypes ----------------------------------------------*/



/*******************************************************************************
 * @brief       
 * @param       
 * @retval      
 * [url=home.php?mod=space&uid=1020061]@attention[/url] *******************************************************************************/
void MD144_InitGPIO(void)
{
    stc_port_init_t stcPortInit;

    /* configure structure initialization */
    MEM_ZERO_STRUCT(stcPortInit);

    stcPortInit.enPinMode = Pin_Mode_Out;

    /* BL & DC & RES */
    PORT_Init(PortC, Pin00, &stcPortInit);
    PORT_Init(PortC, Pin01, &stcPortInit);
    PORT_Init(PortC, Pin02, &stcPortInit);

    MD144_BL_H();   /* 打开背光 */

    /* SPI NSS */
    PORT_Init(PortE, Pin01, &stcPortInit);

    MD144_CS_H();
}


/*******************************************************************************
 * @brief       
 * @param       
 * @retval      
 * @attention   
*******************************************************************************/
void MD144_InitSPI3(void)
{
    stc_spi_init_t stcSpiInit;

    /* configuration structure initialization */
    MEM_ZERO_STRUCT(stcSpiInit);

    /* Configuration peripheral clock */
    PWC_Fcg1PeriphClockCmd(PWC_FCG1_PERIPH_SPI3, Enable);

    /* Configuration SPI pin */
    PORT_SetFunc(PortE, Pin00, Func_Spi3_Sck,  Disable);
    PORT_SetFunc(PortE, Pin02, Func_Spi3_Mosi, Disable);
    PORT_SetFunc(PortE, Pin03, Func_Spi3_Miso, Disable);

    /* Configuration SPI structure */
    stcSpiInit.enClkDiv                 = SpiClkDiv2;
    stcSpiInit.enFrameNumber            = SpiFrameNumber1;
    stcSpiInit.enDataLength             = SpiDataLengthBit8;
    stcSpiInit.enFirstBitPosition       = SpiFirstBitPositionMSB;
    stcSpiInit.enSckPolarity            = SpiSckIdleLevelLow;
    stcSpiInit.enSckPhase               = SpiSckOddSampleEvenChange;
    stcSpiInit.enReadBufferObject       = SpiReadReceiverBuffer;
    stcSpiInit.enWorkMode               = SpiWorkMode3Line;
    stcSpiInit.enTransMode              = SpiTransFullDuplex;
    stcSpiInit.enCommAutoSuspendEn      = Disable;
    stcSpiInit.enModeFaultErrorDetectEn = Disable;
    stcSpiInit.enParitySelfDetectEn     = Disable;
    stcSpiInit.enParityEn               = Disable;
    stcSpiInit.enParity                 = SpiParityEven;

    /* SPI master mode */
    stcSpiInit.enMasterSlaveMode                     = SpiModeMaster;
    stcSpiInit.stcDelayConfig.enSsSetupDelayOption   = SpiSsSetupDelayCustomValue;
    stcSpiInit.stcDelayConfig.enSsSetupDelayTime     = SpiSsSetupDelaySck1;
    stcSpiInit.stcDelayConfig.enSsHoldDelayOption    = SpiSsHoldDelayCustomValue;
    stcSpiInit.stcDelayConfig.enSsHoldDelayTime      = SpiSsHoldDelaySck1;
    stcSpiInit.stcDelayConfig.enSsIntervalTimeOption = SpiSsIntervalCustomValue;
    stcSpiInit.stcDelayConfig.enSsIntervalTime       = SpiSsIntervalSck6PlusPck2;
    stcSpiInit.stcSsConfig.enSsValidBit              = SpiSsValidChannel0;
    stcSpiInit.stcSsConfig.enSs0Polarity             = SpiSsLowValid;
    SPI_Init(M4_SPI3, &stcSpiInit);

    SPI_Cmd(M4_SPI3, Enable);
}


/*******************************************************************************
 * @brief       
 * @param       
 * @retval      
 * @attention   
*******************************************************************************/
uint8_t MD144_SPI_ReadWrite(uint8_t Data)
{
    /* Wait tx buffer empty */
    while(Reset == SPI_GetFlag(M4_SPI3, SpiFlagSendBufferEmpty));
    /* Send data */
    SPI_SendData8(M4_SPI3, Data);

    /* Wait rx buffer full */
    while (Reset == SPI_GetFlag(M4_SPI3, SpiFlagReceiveBufferFull));
    /* Receive data */
    return SPI_ReceiveData8(M4_SPI3);
}


/*******************************************************************************
 * @brief       
 * @param       
 * @retval      
 * @attention   
*******************************************************************************/
void MD144_WriteCMD(uint8_t Command)
{
    MD144_CS_L();
    MD144_DC_L();
    MD144_SPI_ReadWrite(Command);
    MD144_CS_H();
}


/*******************************************************************************
 * @brief       
 * @param       
 * @retval      
 * @attention   
*******************************************************************************/
void MD144_WriteDAT(uint8_t Data)
{
    MD144_CS_L();
    MD144_DC_H();
    MD144_SPI_ReadWrite(Data);
    MD144_CS_H();
}


/*******************************************************************************
 * @brief       
 * @param       
 * @retval      
 * @attention   
*******************************************************************************/
void MD144_HardwareReset(void)
{
    MD144_RES_H();  Ddl_Delay1ms(50);
    MD144_RES_L();  Ddl_Delay1ms(100);
    MD144_RES_H();  Ddl_Delay1ms(50);
}


/*******************************************************************************
 * @brief       
 * @param       
 * @retval      
 * @attention   
*******************************************************************************/
void MD144_ConfigureREG(void)
{
    MD144_WriteCMD(0x11);   //---Exit Sleep

    Ddl_Delay1ms(50);

    MD144_WriteCMD(0xB1);
    MD144_WriteDAT(0x02);
    MD144_WriteDAT(0x35);
    MD144_WriteDAT(0x36);

    MD144_WriteCMD(0xB2);
    MD144_WriteDAT(0x02);
    MD144_WriteDAT(0x35);
    MD144_WriteDAT(0x36);

    MD144_WriteCMD(0xB3);
    MD144_WriteDAT(0x02);
    MD144_WriteDAT(0x35);
    MD144_WriteDAT(0x36);
    MD144_WriteDAT(0x02);
    MD144_WriteDAT(0x35);
    MD144_WriteDAT(0x36);

    //------------------------------End ST7735S Frame Rate----------------------

    MD144_WriteCMD(0xB4); //Dot inversion
    MD144_WriteDAT(0x03);

    MD144_WriteCMD(0xC0);
    MD144_WriteDAT(0xA2);
    MD144_WriteDAT(0x02);
    MD144_WriteDAT(0x84);

    MD144_WriteCMD(0xC1);
    MD144_WriteDAT(0XC5);

    MD144_WriteCMD(0xC2);
    MD144_WriteDAT(0x0D);
    MD144_WriteDAT(0x00);

    MD144_WriteCMD(0xC3);
    MD144_WriteDAT(0x8D);
    MD144_WriteDAT(0x2A);

    MD144_WriteCMD(0xC4);
    MD144_WriteDAT(0x8D);
    MD144_WriteDAT(0xEE);

    //------------------------------End ST7735S Power Sequence------------------

    MD144_WriteCMD(0xC5);   //---VCOM
    MD144_WriteDAT(0x03);

    MD144_WriteCMD(0x3A);   //---Set Color Format
    MD144_WriteDAT(0x05);

    MD144_WriteCMD(0x36);   //---Set Scanning Direction
    MD144_WriteDAT(0x08);

    //------------------------------ST7735S Gamma Sequence----------------------

    MD144_WriteCMD(0xE0);
    MD144_WriteDAT(0x12);
    MD144_WriteDAT(0x1C);
    MD144_WriteDAT(0x10);
    MD144_WriteDAT(0x18);
    MD144_WriteDAT(0x33);
    MD144_WriteDAT(0x2C);
    MD144_WriteDAT(0x25);
    MD144_WriteDAT(0x28);
    MD144_WriteDAT(0x28);
    MD144_WriteDAT(0x27);
    MD144_WriteDAT(0x2F);
    MD144_WriteDAT(0x3C);
    MD144_WriteDAT(0x00);
    MD144_WriteDAT(0x03);
    MD144_WriteDAT(0x03);
    MD144_WriteDAT(0x10);

    MD144_WriteCMD(0xE1);
    MD144_WriteDAT(0x12);
    MD144_WriteDAT(0x1C);
    MD144_WriteDAT(0x10);
    MD144_WriteDAT(0x18);
    MD144_WriteDAT(0x2D);
    MD144_WriteDAT(0x28);
    MD144_WriteDAT(0x23);
    MD144_WriteDAT(0x28);
    MD144_WriteDAT(0x28);
    MD144_WriteDAT(0x26);
    MD144_WriteDAT(0x2F);
    MD144_WriteDAT(0x3B);
    MD144_WriteDAT(0x00);
    MD144_WriteDAT(0x03);
    MD144_WriteDAT(0x03);
    MD144_WriteDAT(0x10);

    MD144_WriteCMD(0x30);             
    MD144_WriteDAT(0x00);             
    MD144_WriteDAT(0x00);             
    MD144_WriteDAT(0x00);             
    MD144_WriteDAT(0x80);

    MD144_WriteCMD(0x12);

    MD144_WriteCMD(0x29);   //---Display On
}


/*******************************************************************************
 * @brief       
 * @param       
 * @retval      
 * @attention   
*******************************************************************************/
void MD144_WriteBlock(uint16_t X0, uint16_t Y0, uint16_t X1, uint16_t Y1)
{
    MD144_WriteCMD(0x2A);
    MD144_WriteDAT(0x00);
    MD144_WriteDAT(0x00);
    MD144_WriteDAT(0x00);
    MD144_WriteDAT(0x7F);

    MD144_WriteCMD(0x2B);
    MD144_WriteDAT(0x00);
    MD144_WriteDAT(0x00);
    MD144_WriteDAT(0x00);
    MD144_WriteDAT(0x9F);

    MD144_WriteCMD(0x2C);
}


/*******************************************************************************
 * @brief       
 * @param       
 * @retval      
 * @attention   
*******************************************************************************/
void MD144_ClearScreen(uint16_t Color)
{
    MD144_WriteBlock(0, 0, 127, 127);

    MD144_CS_L();
    MD144_DC_H();

    for(uint16_t i = 0; i < 128; i++)
    {
        for(uint16_t j = 0; j < 128; j++)
        {
            MD144_SPI_ReadWrite(Color >> 8);
            MD144_SPI_ReadWrite(Color >> 0);
        }
    }

    MD144_CS_H();
}


/*******************************************************************************
 * @brief       
 * @param       
 * @retval      
 * @attention   
*******************************************************************************/
void MD144_Init(void)
{
    MD144_InitGPIO();

    MD144_InitSPI3();

    MD144_HardwareReset();

    MD144_ConfigureREG();

    MD144_ClearScreen(RGB(255, 0, 0));
}


/*******************************************************************************
 * @brief       
 * @param       
 * @retval      
 * @attention   
*******************************************************************************/
void MD144_Demo(void)
{
    uint16_t ColorTable[7] =
    {
        RGB(255,   0,   0),
        RGB(  0, 255,   0),
        RGB(  0,   0, 255),
        RGB(255, 255,   0),
        RGB(255,   0, 255),
        RGB(  0, 255, 255),
        RGB(255, 255, 255),
    };

    for(uint8_t i = 0; i < 100; i++)
    {
        MD144_ClearScreen(ColorTable[i%7]);
    }
}


/******************* (C) COPYRIGHT 2021 *************************END OF FILE***/

Running effect diagram:

Run the video:


Project source code:

Project_SPI_TFT.zip (849.72 KB, downloads: 72)

The SPI query method currently used to read and write data can be seen from the video that the refresh process of the entire screen is a bit slow; the screen refresh action can be achieved through DMA in the future, which will greatly speed up the refresh rate of the screen.

This post is from Domestic Chip Exchange

Latest reply

Have you tried to implement it using hardware IIC?  Details Published on 2022-1-10 18:33

赞赏

1

查看全部赞赏

Personal signatureWe are a team and we work as a team !
 
 

1662

Posts

0

Resources
2
 

The SPI query method is slower.

Does not affect the effect, some occasions do not require fast screen refresh

This post is from Domestic Chip Exchange
 
 
 

7422

Posts

2

Resources
3
 

Come on, very detailed introduction!

This post is from Domestic Chip Exchange
Personal signature

默认摸鱼,再摸鱼。2022、9、28

 
 
 

1942

Posts

2

Resources
4
 

Is this a 128*128 screen? If the spi rate reaches the maximum speed, the display effect should be much better!

This post is from Domestic Chip Exchange
 
 
 

1

Posts

0

Resources
5
 

I used it, but it was only successful when using the SPI of the simulated IO.

The built-in SPI has the wrong phase. SDA and CLK

This post is from Domestic Chip Exchange
 
 
 

1

Posts

0

Resources
6
 
yxl-scpz posted on 2021-6-26 10:57 I used it, but it was only successful with the SPI of analog IO. The built-in SPI has the wrong phase. SDA and CLK

How to configure the port speed in simulation

This post is from Domestic Chip Exchange
 
 
 

35

Posts

1

Resources
7
 
Have you tried to implement it using hardware IIC?
This post is from Domestic Chip Exchange

Comments

Um... this is a screen with SPI interface...  Details Published on 2022-1-11 14:04
 
 
 

205

Posts

0

Resources
8
 
emmnn posted on 2022-1-10 18:33 Have you tried to use hardware IIC to implement it?

Um... this is a screen with SPI interface...

This post is from Domestic Chip Exchange
Personal signatureWe are a team and we work as a team !
 
 
 

Guess Your Favourite
Just looking around
Find a datasheet?

EEWorld Datasheet Technical Support

EEWorld
subscription
account

EEWorld
service
account

Automotive
development
circle

Copyright © 2005-2024 EEWORLD.com.cn, Inc. All rights reserved 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号
快速回复 返回顶部 Return list