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

您所在的位置:网站首页 紫金花乳胶漆的价格 【嵌入式】MCU(HC32F460)+SPI接口LCD液晶屏ILI9341 移植emWin记录1

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

#【嵌入式】MCU(HC32F460)+SPI接口LCD液晶屏ILI9341 移植emWin记录1| 来源: 网络整理| 查看: 265

目录

一 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) { //功耗控制B LCD_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); //驱动时序控制A LCD_WriteCMD(0xE8); LCD_WriteDAT(0x85); LCD_WriteDAT(0x10); LCD_WriteDAT(0x7A); //功耗控制A LCD_WriteCMD(0xCB); LCD_WriteDAT(0x39); LCD_WriteDAT(0x2C); LCD_WriteDAT(0x00); LCD_WriteDAT(0x34); LCD_WriteDAT(0x02); //泵比控制 LCD_WriteCMD(0xF7); LCD_WriteDAT(0x20); //驱动时序控制B LCD_WriteCMD(0xEA); LCD_WriteDAT(0x00); LCD_WriteDAT(0x00); //功耗控制1 LCD_WriteCMD(0xC0); //Power control LCD_WriteDAT(0x1B); //VRH[5:0] //功耗控制2 LCD_WriteCMD(0xC1); //Power control LCD_WriteDAT(0x01); //SAP[2:0];BT[3:0] //VCOM控制1 LCD_WriteCMD(0xC5); LCD_WriteDAT(0x30); LCD_WriteDAT(0x30); //VCOM控制2 LCD_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); //使能3G LCD_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(); //开始写入GRAM LCD_WriteRAM(POINT_COLOR); //画笔颜色 } 三 SPI屏点亮

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

/************************************************************************** * 函数名称: LCD_AllInit * 功能描述: LCD初始化 * 输入参数: * 输出参数: * 返 回 值: * 其它说明: **************************************************************************/ void LCD_AllInit(void) { LCD_InitGPIO(); //初始化几个GPIO口,包括BL、DC、RES以及SPI的CS LCD_InitSPI1(); //初始化SPI的几个口,包括SCK、MOSI以及MISO LCD_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



【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3