LCD—STM32液晶显示(4.液晶控制代码讲解)

这篇具有很好参考价值的文章主要介绍了LCD—STM32液晶显示(4.液晶控制代码讲解)。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

目录

STM32液晶控制代码讲解

液晶接口封装介绍

使用LCD的配置步骤

内存操作要使用volatile进行修饰

图形绘制实现

绘制矩形

重点补充


STM32液晶控制代码讲解

液晶接口封装介绍

指南者液晶接口原理图

LCD—STM32液晶显示(4.液晶控制代码讲解),STM32_LCD原理及应用,stm32,单片机,嵌入式硬件,LCD

左边DB00—DB15表示液晶屏的数据线引脚,分别对应STM32的FSMC外设的FSMC_D0—D15及对应的GPIO

LCD—STM32液晶显示(4.液晶控制代码讲解),STM32_LCD原理及应用,stm32,单片机,嵌入式硬件,LCD

霸道原理图如下

LCD—STM32液晶显示(4.液晶控制代码讲解),STM32_LCD原理及应用,stm32,单片机,嵌入式硬件,LCD

可以发现左边得到数据线都是一样的,右边的LCD_RST不同,我们GPIO只需要设置为普通的推挽输出即可。两个板子通过对比之后就可以连接,自己设计板子的时候,哪些引脚是固定不可改变的,哪些引脚是可以自己随便选择的(其中所有具有FSMC外设复用功能的GPIO都是固定的,不能改变)。

然后看右半边的控制引脚:

LCD_BL是背光引脚,在丝印里面表示是BK,该引脚也可以任意选择,设置为普通的推挽输出就可以了。

LCD_CS为片选引脚,对应着指南者的NE1、霸道的NE4,因此要注意霸道和指南者访问液晶屏的地址不同。

RD引脚和WE引脚分别为读使能和写使能

RS引脚对应着LCD的D/CX控制线,用于控制写入的是数据还是命令,根据之前的“使用FSMC模拟8080时序”章节的讲解,D/CX是需要连接到FSMC的地址线的,通过一根地址线来控制,对于指南者是连接到了A16

下面的5根LCD_TP引脚是用于触摸屏的,它们是直接连接到xpt2046(触摸控制芯片),暂时不涉及到,之后再讲解。

使用时,我们先配置好相应的结构体和GPIO输出方式,然后就可以直接使用指针进行读写操作,对应的通讯引脚会自动产生读写时序。

通过输入0Ch命令,来判断FSMC与LCD是否正常通信,正常通信会返回两个参数,第一个为无效参数,第二个参数为LCD的像素格式(16bit或18bit)

LCD—STM32液晶显示(4.液晶控制代码讲解),STM32_LCD原理及应用,stm32,单片机,嵌入式硬件,LCD

使用LCD的配置步骤

  • 初始化ILI9341的IO引脚
  • LCD FSMC 模式配置,初始化两个结构体
  • 点亮LCD背光灯
  • 复位ILI9341
  • 初始化ILI9341寄存器
  • 设置默认扫描方向

内存操作要使用volatile进行修饰

使用指针从内存中读取数据时,内存地址必须加__IO(在STM32中为volatile)修饰,防止编译器进行变量优化。

比如我们进行写入命令的操作(FSMC_Addr_ILI9341_CMD 为宏)

*( __IO uint16_t * ) ( FSMC_Addr_ILI9341_CMD ) = 0x0C;

如果不加__IO,由于进行读取内存操作的时候,CPU的编译器会将数据从内存(RAM)中先读取到寄存器中,再传给变量,进行重复读取的时候,编译器认为数据没有发生变化,没必要从内存中重新读取,会直接使用寄存器中缓存的值赋值给变量。

而对于写入操作,如果不加__IO,编译器第一次调用会向内存中存入数据0x0C,存入数据成功后,同时LCD会产生相应的写入命令时序;而编译器第二次调用写入命令操作,会认为内存地址FSMC_Addr_ILI9341_CMD中的数据根本没有改变(因为上一次已经写入了0x0C),所以编译器会进行优化,认为没必要再次进行赋值操作,也就不再向内存地址中存入数据0x0C,因此LCD也就不会产生相应的写入命令时序。因此也就会导致LCD写入命令无效。同样读取数据和写入数据的操作同样要加__IO。

注:为了严谨起见,所有的内存操作都应该加上volatile。

LCD—STM32液晶显示(4.液晶控制代码讲解),STM32_LCD原理及应用,stm32,单片机,嵌入式硬件,LCD

图形绘制实现

两种方法:

方法一:首先要再显示器上开辟一个窗口,然后调用填充像素命令(0x2C),接着向窗口中写入像素值,从而实现图形的绘制。

 开辟窗口函数

 

/**
 * @brief  在ILI9341显示器上开辟一个窗口
 * @param  usX :在特定扫描方向下窗口的起点X坐标
 * @param  usY :在特定扫描方向下窗口的起点Y坐标
 * @param  usWidth :窗口的宽度
 * @param  usHeight :窗口的高度
 * @retval 无
 */
void ILI9341_OpenWindow ( uint16_t usX, uint16_t usY, uint16_t usWidth, uint16_t usHeight )
{    
    ILI9341_Write_Cmd ( CMD_SetCoordinateX );                  /* 设置X坐标 */
    ILI9341_Write_Data ( usX >> 8  );     /* 先高8位,然后低8位 */
    ILI9341_Write_Data ( usX & 0xff  );     /* 设置起始点和结束点*/
    ILI9341_Write_Data ( ( usX + usWidth - 1 ) >> 8  );
    ILI9341_Write_Data ( ( usX + usWidth - 1 ) & 0xff  );

    ILI9341_Write_Cmd ( CMD_SetCoordinateY );                  /* 设置Y坐标*/
    ILI9341_Write_Data ( usY >> 8  );
    ILI9341_Write_Data ( usY & 0xff  );
    ILI9341_Write_Data ( ( usY + usHeight - 1 ) >> 8 );
    ILI9341_Write_Data ( ( usY + usHeight - 1) & 0xff );
    
}

方法二:使用填充单个像素点的操作,对相应位置进行像素填充,从而实现图形绘制

/**
 * @brief  对ILI9341显示器的某一点以某种颜色进行填充
 * @param  usX :在特定扫描方向下该点的X坐标
 * @param  usY :在特定扫描方向下该点的Y坐标
 * @note 可使用LCD_SetBackColor、LCD_SetTextColor、LCD_SetColors函数设置颜色
 * @retval 无
 */
void ILI9341_SetPointPixel ( uint16_t usX, uint16_t usY )    
{    
    if ( ( usX < LCD_X_LENGTH ) && ( usY < LCD_Y_LENGTH ) )
  {
        ILI9341_SetCursor ( usX, usY );
        
        ILI9341_FillColor ( 1, CurrentTextColor );
    }
    
}

绘制矩形

方法一绘制实心矩形:

LCD—STM32液晶显示(4.液晶控制代码讲解),STM32_LCD原理及应用,stm32,单片机,嵌入式硬件,LCD

其中RGB888_2_RGB565(R,G,B) 函数可以显示自定义彩色

#define RGB888_2_RGB565(R,G,B) (uint16_t)(((R&1F)

方法二绘制空心矩形:

/**
 * @brief  在 ILI9341 显示器上画一个矩形
 * @param  usX_Start :在特定扫描方向下矩形的起始点X坐标
 * @param  usY_Start :在特定扫描方向下矩形的起始点Y坐标
 * @param  usWidth:矩形的宽度(单位:像素)
 * @param  usHeight:矩形的高度(单位:像素)
 * @param  ucFilled :选择是否填充该矩形
  *   该参数为以下值之一:
  *     @arg 0 :空心矩形
  *     @arg 1 :实心矩形 
 * @note 可使用LCD_SetBackColor、LCD_SetTextColor、LCD_SetColors函数设置颜色
 * @retval 无
 */
void ILI9341_DrawRectangle ( uint16_t usX_Start, uint16_t usY_Start, uint16_t usWidth, uint16_t usHeight, uint8_t ucFilled )
{
    if ( ucFilled )
    {
        ILI9341_OpenWindow ( usX_Start, usY_Start, usWidth, usHeight );
        ILI9341_FillColor ( usWidth * usHeight ,CurrentTextColor);    
    }
    else
    {
        ILI9341_DrawLine ( usX_Start, usY_Start, usX_Start + usWidth - 1, usY_Start );
        ILI9341_DrawLine ( usX_Start, usY_Start + usHeight - 1, usX_Start + usWidth - 1, usY_Start + usHeight - 1 );
        ILI9341_DrawLine ( usX_Start, usY_Start, usX_Start, usY_Start + usHeight - 1 );
        ILI9341_DrawLine ( usX_Start + usWidth - 1, usY_Start, usX_Start + usWidth - 1, usY_Start + usHeight - 1 );        
    }

}

绘制直线

方法一:

LCD—STM32液晶显示(4.液晶控制代码讲解),STM32_LCD原理及应用,stm32,单片机,嵌入式硬件,LCD

方法二:

/**
 * @brief  在 ILI9341 显示器上使用 Bresenham 算法画线段 
 * @param  usX1 :在特定扫描方向下线段的一个端点X坐标
 * @param  usY1 :在特定扫描方向下线段的一个端点Y坐标
 * @param  usX2 :在特定扫描方向下线段的另一个端点X坐标
 * @param  usY2 :在特定扫描方向下线段的另一个端点Y坐标
 * @note 可使用LCD_SetBackColor、LCD_SetTextColor、LCD_SetColors函数设置颜色
 * @retval 无
 */
void ILI9341_DrawLine ( uint16_t usX1, uint16_t usY1, uint16_t usX2, uint16_t usY2 )
{
    uint16_t us; 
    uint16_t usX_Current, usY_Current;
    
    int32_t lError_X = 0, lError_Y = 0, lDelta_X, lDelta_Y, lDistance; 
    int32_t lIncrease_X, lIncrease_Y;     
    
    
    lDelta_X = usX2 - usX1; //计算坐标增量 
    lDelta_Y = usY2 - usY1; 
    
    usX_Current = usX1; 
    usY_Current = usY1; 
    
    
    if ( lDelta_X > 0 ) 
        lIncrease_X = 1; //设置单步方向 
    
    else if ( lDelta_X == 0 ) 
        lIncrease_X = 0;//垂直线 
    
    else 
  { 
    lIncrease_X = -1;
    lDelta_X = - lDelta_X;
  } 

    
    if ( lDelta_Y > 0 )
        lIncrease_Y = 1; 
    
    else if ( lDelta_Y == 0 )
        lIncrease_Y = 0;//水平线 
    
    else 
  {
    lIncrease_Y = -1;
    lDelta_Y = - lDelta_Y;
  } 

    
    if (  lDelta_X > lDelta_Y )
        lDistance = lDelta_X; //选取基本增量坐标轴 
    
    else 
        lDistance = lDelta_Y; 

    
    for ( us = 0; us <= lDistance + 1; us ++ )//画线输出 
    {  
        ILI9341_SetPointPixel ( usX_Current, usY_Current );//画点 
        
        lError_X += lDelta_X ; 
        lError_Y += lDelta_Y ; 
        
        if ( lError_X > lDistance ) 
        { 
            lError_X -= lDistance; 
            usX_Current += lIncrease_X; 
        }  
        
        if ( lError_Y > lDistance ) 
        { 
            lError_Y -= lDistance; 
            usY_Current += lIncrease_Y; 
        } 
        
    }  
    
    
}   

设置显示方向

LCD—STM32液晶显示(4.液晶控制代码讲解),STM32_LCD原理及应用,stm32,单片机,嵌入式硬件,LCD

LCD—STM32液晶显示(4.液晶控制代码讲解),STM32_LCD原理及应用,stm32,单片机,嵌入式硬件,LCD

/**
 * @brief  设置ILI9341的GRAM的扫描方向 
 * @param  ucOption :选择GRAM的扫描方向 
 *     @arg 0-7 :参数可选值为0-7这八个方向
 *
 *    !!!其中0、3、5、6 模式适合从左至右显示文字,
 *                不推荐使用其它模式显示文字    其它模式显示文字会有镜像效果            
 *        
 *    其中0、2、4、6 模式的X方向像素为240,Y方向像素为320
 *    其中1、3、5、7 模式下X方向像素为320,Y方向像素为240
 *
 *    其中 6 模式为大部分液晶例程的默认显示方向
 *    其中 3 模式为摄像头例程使用的方向
 *    其中 0 模式为BMP图片显示例程使用的方向
 *
 * @retval 无
 * @note  坐标图例:A表示向上,V表示向下,<表示向左,>表示向右
                    X表示X轴,Y表示Y轴
*/
void ILI9341_GramScan ( uint8_t ucOption )
{    
    //参数检查,只可输入0-7
    if(ucOption >7 )
        return;
    
    //根据模式更新LCD_SCAN_MODE的值,主要用于触摸屏选择计算参数
    LCD_SCAN_MODE = ucOption;
    
    //根据模式更新XY方向的像素宽度
    if(ucOption%2 == 0)    
    {
        //0 2 4 6模式下X方向像素宽度为240,Y方向为320
        LCD_X_LENGTH = ILI9341_LESS_PIXEL;
        LCD_Y_LENGTH =    ILI9341_MORE_PIXEL;
    }
    else                
    {
        //1 3 5 7模式下X方向像素宽度为320,Y方向为240
        LCD_X_LENGTH = ILI9341_MORE_PIXEL;
        LCD_Y_LENGTH =    ILI9341_LESS_PIXEL; 
    }

    //0x36命令参数的高3位可用于设置GRAM扫描方向    
    ILI9341_Write_Cmd ( 0x36 );
  if(lcdid == LCDID_ILI9341)
  {
    ILI9341_Write_Data ( 0x08 |(ucOption<<5));//根据ucOption的值设置LCD参数,共0-7种模式
  }
  else if(lcdid == LCDID_ST7789V)
  {
    ILI9341_Write_Data ( 0x00 |(ucOption<<5));//根据ucOption的值设置LCD参数,共0-7种模式
  }
    ILI9341_Write_Cmd ( CMD_SetCoordinateX ); 
    ILI9341_Write_Data ( 0x00 );        /* x 起始坐标高8位 */
    ILI9341_Write_Data ( 0x00 );        /* x 起始坐标低8位 */
    ILI9341_Write_Data ( ((LCD_X_LENGTH-1)>>8)&0xFF ); /* x 结束坐标高8位 */    
    ILI9341_Write_Data ( (LCD_X_LENGTH-1)&0xFF );                /* x 结束坐标低8位 */

    ILI9341_Write_Cmd ( CMD_SetCoordinateY ); 
    ILI9341_Write_Data ( 0x00 );        /* y 起始坐标高8位 */
    ILI9341_Write_Data ( 0x00 );        /* y 起始坐标低8位 */
    ILI9341_Write_Data ( ((LCD_Y_LENGTH-1)>>8)&0xFF );    /* y 结束坐标高8位 */     
    ILI9341_Write_Data ( (LCD_Y_LENGTH-1)&0xFF );                /* y 结束坐标低8位 */

    /* write gram start */
    ILI9341_Write_Cmd ( CMD_SetPixel );    
}

重点补充

工程中使用0x6D00 0000地址向液晶屏发送数据,使用0x6C00 0000地址向液晶屏发送命令,但实际上使得地址线FSMC_A23输出高低电平的并不是只有这两个地址,因为只是用到了对应那个地址位的0,1与其他位无关,所以只要是那个bank的地址都可以。因此可以随便改变其它位的地址,只要这个不影响这个位和在地址范围内就行文章来源地址https://www.toymoban.com/news/detail-586392.html

到了这里,关于LCD—STM32液晶显示(4.液晶控制代码讲解)的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • LCD—STM32液晶显示(1.显示器简介及LCD显示原理)(6000字详细介绍)

    目录 显示器简介 液晶显示器 液晶 像素 液晶屏缺点 LED显示器 OLED显示器 显示器的基本参数 STM32板载液晶控制原理(不带微控制器) 液晶控制原理 控制信号线(不带液晶控制器) 液晶数据传输时序 显存 总结 3.2寸液晶屏介绍(搭载液晶控制器) 3.2寸电阻触摸屏实物 ILI9341液晶

    2024年02月17日
    浏览(32)
  • LCD-STM32液晶显示中英文-(7.字模及显示原理)

    目录 字模介绍 什么是字模 字模的构成 字模显示原理 字模制作 如何制作字模 字模寻址公式 存储字模文件         有了编码,我们就能在计算机中处理、存储字符了,但是如果计算机处理完字符后直接以编码的形式输出,人类将难以识别。因此计算机与人交互时,一般会

    2024年02月17日
    浏览(45)
  • LCD—STM32液晶显示(2.使用FSMC模拟8080时序)

    目录 使用STM32的FSMC模拟8080接口时序 FSMC简介 FSMC NOR/PSRAM中的模式B时序图 用FSMC模拟8080时序 重点:HADDR内部地址与FSMC地址信号线的转换(实现地址对齐)         ILI9341的8080通讯接口时序可以由STM32使用普通I/O接口进行模拟,但这样效率太低,STM32提供了一种特别的控制方

    2024年02月17日
    浏览(28)
  • STM32之LCD液晶屏(ILI9341)显示图片

    本文章基于STM32F103VET6,参考野火的驱动程序,用LCD液晶屏显示静态图像。 有纰漏请指出,转载请说明。 学习交流请发邮件 1280253714@qq.com 显示一个像素点 将rgb888图片转为rgb555 输出rgb555的C语言数组 数组的每一个元素对应一个像素点的rgb三个通道的数据,用stm32的FSMC模拟8080时

    2024年02月09日
    浏览(28)
  • LCD—STM32液晶显示(3.NOR FLASH时序结构体)

    目录 LCD结构体配置  NOR FLASH时序结构体 FSMC的NOR FLASH初始化结构体         与控制SRAM时一样,控制FSMC使用NOR FLASH存储器时主要是配置时序寄存器以及控制寄存器,利用ST标准库的时序结构体以及初始化结构体可以很方便地写入参数。 FSMC_AddressSetupTime 本成员设置地址建立

    2024年02月17日
    浏览(34)
  • LCD-STM32液晶显示中英文-(5.字符编码)

    目录 字符编码 字符编码说明参考网站 字符编码 ASCII编码 ASCII编码介绍 ASCII编码表 中文编码 1. GB2312标准 区位码  2. GBK编码 3. GB18030 各个标准的对比说明 4. Big5编码 字符编码及转换测试:导航菜单 - 千千秀字 Unicode官网:Index。 使用举例: keil5设置编码如下:         由于

    2024年02月17日
    浏览(35)
  • LCD-STM32液晶显示中英文-(6.unicode字符集)

    目录 Unicode字符集和编码 UTF-32 UTF-16 UTF-8(重点:必须掌握) BOM ANSI         由于各个国家或地区都根据使用自己的文字系统制定标准,同一个编码在不同的标准里表示不一样的字符,各个标准互不兼容,而又没有一个标准能够囊括所有的字符,即无法用一个标准表达所有

    2024年02月16日
    浏览(28)
  • 一文读懂使用STM32驱动 LCD1602 液晶显示屏(基于Mbed Studio平台)

    LCD (Liquid Crystal Display) 液晶显示屏是一种广泛使用的一种字符型液晶显示模块。其中型号1602表示每行显示16个字符、一共2行。LCD1602相比于OLED最大的好处就是不用使用SPI或I2C等任何通信协议,而是由mbed直接将命令传给LCD从而实现控制。 LCD1602主要参数如下: 显示字符:16×2个

    2024年02月05日
    浏览(29)
  • 字符型液晶显示器LCD 1602的显示控制(Keil+Proteus)

    趁机把LCD 1602的实验完成了,那个电路图有几个地方没弄懂,但是去掉也没有报错,就没管了。 LCD1602_百度百科 (baidu.com) https://baike.baidu.com/item/LCD1602/6014393?fr=ge_ala LCD1602液晶显示屏通过电压来改变填充在两块平行板之间的液晶材料内部分子的排列状况,以达到遮光和透光的目

    2024年02月06日
    浏览(37)
  • LCD—液晶显示

    本节主要介绍以下内容 显示器简介 液晶控制原理 秉火 3.2 寸液晶屏简介 使用 FSMC 模拟 8080 时序 NOR FLASH 时序结构体 FSMC 初始化结构体   显示器属于计算机的 I/O 设备,即输入输出设备。它是一种将特定电子信息输出到屏幕上再反射到人眼的显示工具。常见的有 CRT 显示器、液

    2024年02月02日
    浏览(30)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包