xld0932 发表于 2021-5-7 21:12

【HC32F460开发板测评】08.硬件SPI接口驱动TFT液晶屏

<p>HC32F460开发板上扩展了1组硬件SPI接口J18,以排针的形式方便与外部硬件进行功能扩展。本实验主要是通过硬件SPI接口,来驱动一块SPI接口的TFT液晶显示屏,进行刷屏动作;</p>

<p>&nbsp;</p>

<p>J18 SPI接口原理示意图:</p>

<p></p>

<p>SPI接口管脚与MCU引脚的连接如下图所示:</p>

<p></p>

<p>我们使用的是一块SPI接口的1.44寸TFT液晶显示屏,屏幕分辨率为128*128,操作接口定义如下图所示:</p>

<p></p>

<p>我们看到除了电源和SPI接口之外,还需要3个控制引脚来操作这个TFT液晶显示屏,我们借助MOTOR接口中20脚、19脚、18脚(PC0~PC2)这3个引脚分别来控制BL、D/C和RES,如下图所示:</p>

<p></p>

<p>液晶显示屏实物图如下所示:</p>

<p>程序源码头文件:</p>

<pre>
<code class="language-cpp">/*******************************************************************************
* @file    MD144.h
* @authorxld0932
* @version V1.00
* @date 31-Mar-2021
* @brief ......
*******************************************************************************/


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


#ifdef __cplusplus
extern "C" {
#endif


#undefEXTERN


#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) &lt;&lt; 10) &amp; 0xF800) |\
                        (((uint16_t)(g) &lt;&lt;5) &amp; 0x07E0) |\
                        (((uint16_t)(b) &lt;&lt;0) &amp; 0x001F)


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


#ifdef __cplusplus
}
#endif


#endif


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

</code></pre>

<p>&nbsp;</p>

<p>程序源码源程序:</p>

<pre>
<code>/*******************************************************************************
* @file    MD144.c
* @authorxld0932
* @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      
* @attention *******************************************************************************/
void MD144_InitGPIO(void)
{
    stc_port_init_t stcPortInit;

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

    stcPortInit.enPinMode = Pin_Mode_Out;

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

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

    /* SPI NSS */
    PORT_Init(PortE, Pin01, &amp;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, &amp;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 &lt; 128; i++)
    {
      for(uint16_t j = 0; j &lt; 128; j++)
      {
            MD144_SPI_ReadWrite(Color &gt;&gt; 8);
            MD144_SPI_ReadWrite(Color &gt;&gt; 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 =
    {
      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 &lt; 100; i++)
    {
      MD144_ClearScreen(ColorTable);
    }
}


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

</code></pre>

<p>&nbsp;</p>

<p>运行效果图:</p>

<p></p>

<p>运行视频:</p>

<p><iframe allowfullscreen="true" frameborder="0" height="510" src="https://training.eeworld.com.cn/shareOpenCourseAPI?isauto=true&amp;lessonid=29973" style="background:#eee;margin-bottom:10px;" width="750"></iframe><br />
&nbsp;</p>

<p>&nbsp;</p>

<p>工程源码:</p>

<p></p>

<p>&nbsp;</p>

<p>当前使用的SPI查询的方式进行读写数据的,可以从视频出看出,整个屏幕的刷新过程有些缓慢;后续可以通过DMA方式来实现刷屏动作,这样会大大加快屏幕的刷新率。</p>

<p>&nbsp;</p>

火辣西米秀 发表于 2021-5-7 21:39

<p>SPI查询的方式是慢些,,</p>

<p>不影响效果,有的场合不需要快速刷屏</p>

freebsder 发表于 2021-5-8 09:34

<p>加油,介绍的很详细!</p>

w494143467 发表于 2021-5-9 15:46

<p>这是一个128*128的屏幕吗?spi速率达到极速的话,显示效果应该会好很多!</p>

yxl-scpz 发表于 2021-6-26 10:57

<p>我用了,只是用模拟IO的SPI才能成功.</p>

<p>自带的SPI,相位不对.SDA和CLK</p>

fjj838142260 发表于 2021-7-5 11:28

yxl-scpz 发表于 2021-6-26 10:57
我用了,只是用模拟IO的SPI才能成功.

自带的SPI,相位不对.SDA和CLK

<p>模拟怎么配置端口的速度</p>

<p>&nbsp;</p>

<p>&nbsp;</p>

emmnn 发表于 2022-1-10 18:33

楼主有试过用硬件IIC来实现吗?

xld0932 发表于 2022-1-11 14:04

emmnn 发表于 2022-1-10 18:33
楼主有试过用硬件IIC来实现吗?

<p>额&hellip;&hellip;这个是SPI接口的屏哈&hellip;&hellip;</p>

32446975 发表于 2024-11-29 16:15

<p>手上的开发板是V1.2版本的,需要使用SPI验证外部6轴传感器,找到V1.4的原理图(与V1.2差异不大),参考下SPI引脚连接与配置。</p>
页: [1]
查看完整版本: 【HC32F460开发板测评】08.硬件SPI接口驱动TFT液晶屏