【HC32F460开发板测评】08.硬件SPI接口驱动TFT液晶屏
<p>HC32F460开发板上扩展了1组硬件SPI接口J18,以排针的形式方便与外部硬件进行功能扩展。本实验主要是通过硬件SPI接口,来驱动一块SPI接口的TFT液晶显示屏,进行刷屏动作;</p><p> </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) << 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***/
</code></pre>
<p> </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 & 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 =
{
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);
}
}
/******************* (C) COPYRIGHT 2021 *************************END OF FILE***/
</code></pre>
<p> </p>
<p>运行效果图:</p>
<p></p>
<p>运行视频:</p>
<p><iframe allowfullscreen="true" frameborder="0" height="510" src="https://training.eeworld.com.cn/shareOpenCourseAPI?isauto=true&lessonid=29973" style="background:#eee;margin-bottom:10px;" width="750"></iframe><br />
</p>
<p> </p>
<p>工程源码:</p>
<p></p>
<p> </p>
<p>当前使用的SPI查询的方式进行读写数据的,可以从视频出看出,整个屏幕的刷新过程有些缓慢;后续可以通过DMA方式来实现刷屏动作,这样会大大加快屏幕的刷新率。</p>
<p> </p>
<p>SPI查询的方式是慢些,,</p>
<p>不影响效果,有的场合不需要快速刷屏</p>
<p>加油,介绍的很详细!</p>
<p>这是一个128*128的屏幕吗?spi速率达到极速的话,显示效果应该会好很多!</p>
<p>我用了,只是用模拟IO的SPI才能成功.</p>
<p>自带的SPI,相位不对.SDA和CLK</p>
yxl-scpz 发表于 2021-6-26 10:57
我用了,只是用模拟IO的SPI才能成功.
自带的SPI,相位不对.SDA和CLK
<p>模拟怎么配置端口的速度</p>
<p> </p>
<p> </p>
楼主有试过用硬件IIC来实现吗? emmnn 发表于 2022-1-10 18:33
楼主有试过用硬件IIC来实现吗?
<p>额……这个是SPI接口的屏哈……</p>
<p>手上的开发板是V1.2版本的,需要使用SPI验证外部6轴传感器,找到V1.4的原理图(与V1.2差异不大),参考下SPI引脚连接与配置。</p>
页:
[1]