【嵌入式】MCU(HC32F460)+SPI接口LCD液晶屏ILI9341 移植emWin记录1----点亮LCD屏

目录

一 SPI屏的接线

二 SPI屏驱动初始化

三 SPI屏点亮

四 附录


一 SPI屏的接线

        SPI屏的特点在于接线简单,只需要四根SPI线以及几个GPIO口即可驱动工作,但是由于非并口的,所以当像素比比较大的时候,刷新速度可能会受到考验。我这边使用的是一块320*240的串口屏,屏幕驱动为ILI9341,控制芯片选用的是华大的HC32F460,主频为168Mhz,因为主频比较高,同时对屏幕刷新显示要求不大,所以考虑基于此进行开发。

        首先根据显示屏的接线图进行接线:

        其中,真正需要关注的是SPI的四线(SDA即MOSI、SDO即MISO、SCL即SCK、CS片选),GPIO三根线RST复位线、D/C区别输出的是指令还是数据以及LEDA(BL)背光线。

         接线示意图如下:

二 SPI屏驱动初始化

        接线完成之后,就需要在程序中对这几个接口进行初始化。

        【1】首先选定几个管脚,做一些定义:

/* SPI_SCK Port/Pin definition */
#define SPI1_SCK_PORT                    (PortA)
#define SPI1_SCK_PIN                     (Pin06)
#define SPI1_SCK_FUNC                    (Func_Spi1_Sck)/* SPI_NSS Port/Pin definition */
#define SPI1_NSS_PORT                    (PortB)
#define SPI1_NSS_PIN                     (Pin01)
#define SPI1_NSS_HIGH()                  (PORT_SetBits(SPI1_NSS_PORT, SPI1_NSS_PIN))
#define SPI1_NSS_LOW()                   (PORT_ResetBits(SPI1_NSS_PORT, SPI1_NSS_PIN))/* SPI_MOSI Port/Pin definition */
#define SPI1_MOSI_PORT                   (PortA)
#define SPI1_MOSI_PIN                    (Pin07)
#define SPI1_MOSI_FUNC                   (Func_Spi1_Mosi)/* SPI_MISO Port/Pin definition */
#define SPI1_MISO_PORT                   (PortB)
#define SPI1_MISO_PIN                    (Pin00)
#define SPI1_MISO_FUNC                   (Func_Spi1_Miso)/* SPI unit and clock definition */
#define SPI1_UNIT                        (M4_SPI1)
#define SPI1_UNIT_CLOCK                  (PWC_FCG1_PERIPH_SPI1)//RES引脚
#define LCD_RES_PORT                    (PortE)
#define LCD_RES_PIN                     (Pin11)
#define LCD_RES_HIGH()                  (PORT_SetBits(LCD_RES_PORT, LCD_RES_PIN))
#define LCD_RES_LOW()                   (PORT_ResetBits(LCD_RES_PORT, LCD_RES_PIN))
//DC引脚
#define LCD_DC_PORT                     (PortE)
#define LCD_DC_PIN                      (Pin12)
#define LCD_DC_HIGH()                   (PORT_SetBits(LCD_DC_PORT, LCD_DC_PIN))
#define LCD_DC_LOW()                    (PORT_ResetBits(LCD_DC_PORT, LCD_DC_PIN))
//BLK引脚
#define LCD_BL_PORT                     (PortE)
#define LCD_BL_PIN                      (Pin13)
#define LCD_BL_HIGH()                   (PORT_SetBits(LCD_BL_PORT, LCD_BL_PIN))
#define LCD_BL_LOW()                    (PORT_ResetBits(LCD_BL_PORT, LCD_BL_PIN))

        【2】其次是GPIO口初始化(这边将SPI的CS脚当作GPIO进行初始化):

/**************************************************************************
* 函数名称: LCD_InitGPIO
* 功能描述: LCD初始化GPIO引脚
* 输入参数: 
* 输出参数: 
* 返 回 值: 
* 其它说明: 初始化LCD用到的GPIO口,包括RES、DC、BL以及SPI的NSS引脚
**************************************************************************/
void LCD_InitGPIO(void)
{stc_port_init_t stcPortInit;/* configure structure initialization */MEM_ZERO_STRUCT(stcPortInit);stcPortInit.enPinMode = Pin_Mode_Out;/* RES & DC & BL */PORT_Init(LCD_RES_PORT, LCD_RES_PIN, &stcPortInit);PORT_Init(LCD_DC_PORT,  LCD_DC_PIN, &stcPortInit);PORT_Init(LCD_BL_PORT,  LCD_BL_PIN, &stcPortInit);LCD_BL_HIGH();   /* 打开背光 *//* SPI NSS */PORT_Init(SPI1_NSS_PORT, SPI1_NSS_PIN, &stcPortInit);SPI1_NSS_HIGH();
}

        【3】SPI初始化:

/**************************************************************************
* 函数名称: LCD_InitSPI1
* 功能描述: LCD初始化SPI
* 输入参数: 
* 输出参数: 
* 返 回 值: 
* 其它说明: 初始化SPI用到的口,包括MOSI、MISO、SCK
**************************************************************************/
void LCD_InitSPI1(void)
{stc_spi_init_t stcSpiInit;/* configuration structure initialization */MEM_ZERO_STRUCT(stcSpiInit);/* Configuration peripheral clock */PWC_Fcg1PeriphClockCmd(SPI1_UNIT_CLOCK, Enable);/* Configuration SPI pin */PORT_SetFunc(SPI1_SCK_PORT, SPI1_SCK_PIN, SPI1_SCK_FUNC,  Disable);PORT_SetFunc(SPI1_MOSI_PORT, SPI1_MOSI_PIN, SPI1_MOSI_FUNC, Disable);PORT_SetFunc(SPI1_MISO_PORT, SPI1_MISO_PIN, SPI1_MISO_FUNC, 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(SPI1_UNIT, &stcSpiInit);SPI_Cmd(SPI1_UNIT, Enable);
}

        【4】结合SPI的读写功能,封装接口供LCD进行写命令(LCD_WriteCMD)和写数据(LCD_WriteDAT):

/**************************************************************************
* 函数名称: SPI_RW
* 功能描述: SPI读写功能
* 输入参数:
* 输出参数:
* 返 回 值:
* 其它说明:
**************************************************************************/
uint8_t SPI_RW(M4_SPI_TypeDef *SPIx, uint8_t data)
{while (Reset == SPI_GetFlag(SPIx, SpiFlagSendBufferEmpty)){}SPI_SendData8(SPIx, data);while (Reset == SPI_GetFlag(SPIx, SpiFlagReceiveBufferFull)){}return SPI_ReceiveData8(SPIx);
}/**************************************************************************
* 函数名称: LCD_WriteCMD
* 功能描述: LCD写命令
* 输入参数: 
* 输出参数: 
* 返 回 值: 
* 其它说明: 
**************************************************************************/
void LCD_WriteCMD(U8 Command)
{SPI1_NSS_LOW();LCD_DC_LOW();SPI_RW(SPI1_UNIT, Command);SPI1_NSS_HIGH();
}/**************************************************************************
* 函数名称: LCD_WriteDAT
* 功能描述: LCD写数据
* 输入参数: 
* 输出参数: 
* 返 回 值: 
* 其它说明: 
**************************************************************************/
void LCD_WriteDAT(U8 Data)
{SPI1_NSS_LOW();LCD_DC_HIGH();SPI_RW(SPI1_UNIT, Data);SPI1_NSS_HIGH();
}

        【5】封装LCD的一些基本的接口,比如复位接口以及寄存器配置接口(其中寄存器的相关配置可以参考附录中提供的ILI9431数据手册):

/**************************************************************************
* 函数名称: LCD_HardwareReset
* 功能描述: LCD复位
* 输入参数: 
* 输出参数: 
* 返 回 值: 
* 其它说明: 
**************************************************************************/
void LCD_HardwareReset(void)
{LCD_RES_HIGH();  Ddl_Delay1ms(1);LCD_RES_LOW();   Ddl_Delay1ms(80);LCD_RES_HIGH();  Ddl_Delay1ms(10);
}/**************************************************************************
* 函数名称: LCD_ConfigureREG
* 功能描述: LCD寄存器配置
* 输入参数: 
* 输出参数: 
* 返 回 值: 
* 其它说明: 
**************************************************************************/
void LCD_ConfigureREG(void)
{//功耗控制BLCD_WriteCMD(0xCF);LCD_WriteDAT(0x00);LCD_WriteDAT(0xC1);LCD_WriteDAT(0X30);//电源时序控制LCD_WriteCMD(0xED);LCD_WriteDAT(0x64);LCD_WriteDAT(0x03);LCD_WriteDAT(0X12);LCD_WriteDAT(0X81);//驱动时序控制ALCD_WriteCMD(0xE8); LCD_WriteDAT(0x85);LCD_WriteDAT(0x10);LCD_WriteDAT(0x7A);//功耗控制ALCD_WriteCMD(0xCB);LCD_WriteDAT(0x39);LCD_WriteDAT(0x2C);LCD_WriteDAT(0x00);LCD_WriteDAT(0x34);LCD_WriteDAT(0x02);//泵比控制LCD_WriteCMD(0xF7);LCD_WriteDAT(0x20);//驱动时序控制BLCD_WriteCMD(0xEA);LCD_WriteDAT(0x00);LCD_WriteDAT(0x00);//功耗控制1LCD_WriteCMD(0xC0);  //Power control LCD_WriteDAT(0x1B);  //VRH[5:0]//功耗控制2LCD_WriteCMD(0xC1);  //Power control LCD_WriteDAT(0x01);  //SAP[2:0];BT[3:0]//VCOM控制1LCD_WriteCMD(0xC5);LCD_WriteDAT(0x30);LCD_WriteDAT(0x30);//VCOM控制2LCD_WriteCMD(0xC7);LCD_WriteDAT(0XB7);//存储器访问控制LCD_WriteCMD(0x36);LCD_WriteDAT(0x48);//像素格式设置LCD_WriteCMD(0x3A);LCD_WriteDAT(0x55);//帧速率控制(正常模式/全色模式)LCD_WriteCMD(0xB1);LCD_WriteDAT(0x00);LCD_WriteDAT(0x1A);//显示功能设置控制LCD_WriteCMD(0xB6);LCD_WriteDAT(0x0A);LCD_WriteDAT(0xA2);//使能3GLCD_WriteCMD(0xF2);  LCD_WriteDAT(0x00);  //3Gamma Function Disable //伽马设置LCD_WriteCMD(0x26);  LCD_WriteDAT(0x01);  //Gamma curve selected //正极伽马校正LCD_WriteCMD(0xE0);LCD_WriteDAT(0x0F);LCD_WriteDAT(0x2A);LCD_WriteDAT(0x28);LCD_WriteDAT(0x08);LCD_WriteDAT(0x0E);LCD_WriteDAT(0x08);LCD_WriteDAT(0x54);LCD_WriteDAT(0XA9);LCD_WriteDAT(0x43);LCD_WriteDAT(0x0A);LCD_WriteDAT(0x0F);LCD_WriteDAT(0x00);LCD_WriteDAT(0x00);LCD_WriteDAT(0x00);LCD_WriteDAT(0x00);//负极伽马校正LCD_WriteCMD(0XE1);LCD_WriteDAT(0x00);LCD_WriteDAT(0x15);LCD_WriteDAT(0x17);LCD_WriteDAT(0x07);LCD_WriteDAT(0x11);LCD_WriteDAT(0x06);LCD_WriteDAT(0x2B);LCD_WriteDAT(0x56);LCD_WriteDAT(0x3C);LCD_WriteDAT(0x05);LCD_WriteDAT(0x10);LCD_WriteDAT(0x0F);LCD_WriteDAT(0x3F);LCD_WriteDAT(0x3F);LCD_WriteDAT(0x0F);//行地址设置LCD_WriteCMD(0x2B);LCD_WriteDAT(0x00);LCD_WriteDAT(0x00);LCD_WriteDAT(0x01);LCD_WriteDAT(0x3f);//列地址设置LCD_WriteCMD(0x2A);LCD_WriteDAT(0x00);LCD_WriteDAT(0x00);LCD_WriteDAT(0x00);LCD_WriteDAT(0xef);//退出睡眠模式LCD_WriteCMD(0x11);Ddl_Delay1ms(120);//开显示(0x28为关显示)LCD_WriteCMD(0x29);
}

        【6】添加清屏接口LCD_Clear,支持以某种颜色刷屏:

/**************************************************************************
* 函数名称: LCD_SetCursor
* 功能描述: 设置光标位置
* 输入参数: Xpos为横坐标,Ypos为纵坐标
* 输出参数: 
* 返 回 值: 
* 其它说明: 
**************************************************************************/
void LCD_SetCursor(uint16_t Xpos, uint16_t Ypos)
{	 LCD_WriteCMD(lcddev.setxcmd);  //0x2A列地址设置命令LCD_WriteDAT(Xpos>>8); LCD_WriteDAT(Xpos&0xFF);	LCD_WriteCMD(lcddev.setycmd);  //0x2B行地址设置命令LCD_WriteDAT(Ypos>>8); LCD_WriteDAT(Ypos&0xFF);
}/**************************************************************************
* 函数名称: LCD_WriteRAM_Prepare
* 功能描述: 开始写GRAM
* 输入参数: 
* 输出参数: 
* 返 回 值: 
* 其它说明: 
**************************************************************************/
void LCD_WriteRAM_Prepare(void)
{LCD_WriteCMD(lcddev.wramcmd);  //0x2C存储器写命令
}/**************************************************************************
* 函数名称: LCD_WriteRAM
* 功能描述: LCD写GRAM,写颜色值
* 输入参数: 
* 输出参数: 
* 返 回 值: 
* 其它说明: 
**************************************************************************/
void LCD_WriteRAM(uint16_t Data)
{SPI1_NSS_LOW();LCD_DC_HIGH();SPI_RW(SPI1_UNIT, Data);SPI_RW(SPI1_UNIT, Data >> 8);SPI1_NSS_HIGH();
}/**************************************************************************
* 函数名称: LCD_Clear
* 功能描述: 清屏函数
* 输入参数: color:要清屏的填充色
* 输出参数: 
* 返 回 值: 
* 其它说明: 
**************************************************************************/
void LCD_Clear(uint16_t color)
{uint32_t index = 0;      uint32_t totalpoint = lcddev.width;  //屏幕横向总像素值totalpoint *= lcddev.height; //横向总像素*纵向总像素=得到总像素值LCD_SetCursor(0x00,0x0000);  //设置光标位置LCD_WriteRAM_Prepare();      //开始写入GRAM	 	  for(index = 0;index < totalpoint;index ++){LCD_WriteRAM(color);	   }
}

        【7】画点函数LCD_DrawPoint:

/**************************************************************************
* 函数名称: LCD_DrawPoint
* 功能描述: 画点
* 输入参数: x,y为坐标,POINT_COLOR为此点的颜色
* 输出参数: 
* 返 回 值: 
* 其它说明: 
**************************************************************************/
void LCD_DrawPoint(U16 x,U16 y)
{LCD_SetCursor(x, y);         //设置光标位置 LCD_WriteRAM_Prepare();	     //开始写入GRAMLCD_WriteRAM(POINT_COLOR);   //画笔颜色
}

三 SPI屏点亮

        有了上面的接口作为准备,就可以驱动SPI串口屏显示一些简单的界面了:

/**************************************************************************
* 函数名称: LCD_AllInit
* 功能描述: LCD初始化
* 输入参数: 
* 输出参数: 
* 返 回 值: 
* 其它说明: 
**************************************************************************/
void LCD_AllInit(void)
{LCD_InitGPIO();  //初始化几个GPIO口,包括BL、DC、RES以及SPI的CSLCD_InitSPI1();  //初始化SPI的几个口,包括SCK、MOSI以及MISOLCD_HardwareReset();  //LCD复位LCD_ConfigureREG();   //RGB配置初始化LCD_DisplayDir(1);  //默认为横屏LCD_Clear(WHITE);  //清屏白色
}/**************************************************************************
* 函数名称: GUI_Task
* 功能描述: GUI子任务
* 输入参数: 
* 输出参数: 
* 返 回 值: 
* 其它说明: 
**************************************************************************/
void GUI_Task(void)
{
//直接使用SPI的驱动来绘图uint8_t i = 0;LCD_AllInit();while(1){switch(i){case 1: LCD_Clear(WHITE); break;case 2: LCD_Clear(BLACK); break;case 3: LCD_Clear(RED); break;case 4: LCD_Clear(GREEN); break;case 5: LCD_Clear(BLUE); break;default: break;}i ++;if(i == 6) i=0;os_dly_wait(1000);  //RTX操作系统延时}

                  

        至此,关于SPI的一些基本移植已经完成,后续需要增加更多丰富的界面元素,考虑移植emWin来设计GUI界面。(后续的移植操作参考SPI屏+emWin移植)

四 附录

【1】ILI9341资料汇总:

https://download.csdn.net/download/sinat_33408502/21516340

【2】HC32F460资料汇总:

https://download.csdn.net/download/sinat_33408502/21516444

【3】《【嵌入式】MCU(HC32F460)+SPI接口LCD液晶屏ILI9341 移植emWin记录2----移植emWin》:

https://blog.csdn.net/sinat_33408502/article/details/119915261


本文来自互联网用户投稿,文章观点仅代表作者本人,不代表本站立场,不承担相关法律责任。如若转载,请注明出处。 如若内容造成侵权/违法违规/事实不符,请点击【内容举报】进行投诉反馈!

相关文章

立即
投稿

微信公众账号

微信扫一扫加关注

返回
顶部