IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 嵌入式 -> 【嵌入式】MCU(HC32F460)+SPI接口LCD液晶屏ILI9341 移植emWin记录1----点亮LCD屏 -> 正文阅读

[嵌入式]【嵌入式】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)
{
    //功耗控制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

  嵌入式 最新文章
基于高精度单片机开发红外测温仪方案
89C51单片机与DAC0832
基于51单片机宠物自动投料喂食器控制系统仿
《痞子衡嵌入式半月刊》 第 68 期
多思计组实验实验七 简单模型机实验
CSC7720
启明智显分享| ESP32学习笔记参考--PWM(脉冲
STM32初探
STM32 总结
【STM32】CubeMX例程四---定时器中断(附工
上一篇文章      下一篇文章      查看所有文章
加:2021-08-26 12:16:06  更:2021-08-26 12:16:49 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年5日历 -2024/5/21 3:30:11-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码