Author Archives: lyping

教你如何快速驱动LCD屏

前言
       LCD屏的驱动对于新手来说,这是一个很大的拦路虎。学完基础外设后,在这里就不知道怎么下手了。一个完整的LCD驱动包含的内容是非常多的,最基础的描点,画线,显示字符,后面还有一些UI。在这里,尽量以浅显的方式驱动LCD,一步一步带大家熟悉掌握LCD屏幕的驱动。

       首先,我们先了解一下LCD(Liquid Crystal Display),即液晶显示器,主要由玻璃基板、背光、驱动IC组成,具体如下图。

       全彩LCD,是一种全彩显示屏,一个像素点可以是RGB565或者RGB888格式(R红色、G绿色、B蓝色就是常说的三基色),可以显示各种颜色。
       至于LCD的显示原理,我们这里就不说了,大家可以通过以下网址进行查看:https://zhuanlan.zhihu.com/p/133306648
       通过上图可以清楚看到,单片机要实现LCD的显示,主要是与驱动IC进行通信。想要进行通信,必须得知道是什么接口,这时候得看LCD模块给你引出什么接口,这是裸屏已经决定了。LCD接口可以大致分为三种:MCU接口、RGB接口与MIPI接口,具体区别如下:

       不同接口的屏幕支持的分辨率都不一样。我们这里主要讲解的是MCU屏—正点原子2.8寸LCD屏,该屏自带SRAM,驱动简单,大部分单片机都能驱动。其实还有一类是SPI接口的支持更小分辨率的屏幕。
       为什么说裸屏已经决定了屏幕的接口,我们以正点原子的2.8寸屏为例,该屏的驱动IC是ILI9341,是支持多种通信接口:MCU接口(8/9/16/18位)、3/4线SPI接口、RGB接口(6/16/18位)。

ILI9341芯片框架图

       通过手册查阅,可以发现IM[3:0]引脚可以选择接口,这就需要结合2.8寸LCD屏原理图进行查看了。

       通过上图,我们就很清楚看到,我们的LCD屏幕是支持使用8位或者16位MCU接口的,不过默认的是16位。所以说,我们的2.8寸LCD屏使用的是16位MCU接口。使用16位MCU接口的显示速度比8位的要快一倍。到这里,我们对于LCD的用什么接口已经很清楚了。

       简单来说,LCD屏(MCU接口)驱动的核心:驱动LCD驱动芯片。
       这里我们就需要一些基本的LCD驱动知识:
       ① 8080时序,LCD驱动芯片一般使用8080时序控制,实现数据写入/读取。
       ② 初始化序列(数组),屏厂提供,用于初始化特定屏幕,不同屏幕厂家不完全相同!
       ③ 画点函数、读点函数(非必须),基于这两个函数可以实现各种绘图功能!
把上面的梳理一下,就是LCD驱动的一般过程了。

        只要我们把每一步都了解清楚,就相当于掌握了LCD屏幕的驱动了。

一.掌握8080时序

        8080时序,称为并口总线时序,常用于MCU屏驱动IC的访问,由Inter提出,也叫英特尔总线。
        接下来,我们来看看LCD 8080时序信号的说明,具体如下表:

      简单来说,这里就是我们用来驱动LCD屏幕用到的引脚。在了解引脚的功能后,就可以通过查看手册的时序图,写出读写函数了。
      8080写时序

       首先拉低CS线选中器件,然后根据写入的内容是数据(RS=1)还是命令(RS=1)进行拉低或拉高RS线,在WR的上升沿,把内容写入LCD驱动IC中,  最后拉高CS线释放片选,而RD是读信号保持高电平即可。

      8080读时序

       首先拉低CS线选中器件,然后根据操作的内容是数据(RS=1)还是命令(RS=1)进行拉低或拉高RS线,在RD的上升沿,把内容读取到MCU,最后拉高CS线释放片选,而WR是写信号保持高电平即可。

       从这里可以知道,我们8080时序操作可分为写数据、写命令、读数据、读命令(没用到)四种。基于写数据,写命令就可以完成初始化LCD操作,也就是发送初始化序列。

二.掌握芯片的必用指令

       LCD驱动芯片用于控制LCD的各种显示功能和效果,整体功能比较复杂,不过我们想要实现基本使用只需要6条指令即可。

       通常我们想验证一下我们的读写函数是否正确,看看能否读取到器件的ID。

       发送完0xD3指令后,后面跟了4个参数,最后2个参数才是有用的,读出的是0x93和0x41,刚好是我们控制器ILI9341数字部分。这里特别注意:不同芯片读取ID的指令是不一样的,不要张冠李戴。
       指令0x36是存储访问控制指令,控制ILI9341存储器的读写方向。简单来说,就是在连续写GRAM的时候,可以控制GRAM指针的增长方向,从而控制显示方式(读GRAM也是一样)。

       发送完0x36指令后,紧跟一个参数,参数里的MX/MY/MV共同控制GRAM的扫描方向以及BGR控制RGB/BGR顺序。默认LCD扫描方向为从左到右,从上到下。

      当我们设置好LCD扫描方向后,显示内容时就有很大灵活性,只需要设置一次坐标,然后不停往LCD填充颜色数据即可,大大提高了显示速度。
      设置坐标的指令分为X轴和Y轴,官方一点就是设置列地址指令和设置页地址设置指令。首先来看,0x2A即列地址设置指令。

       0x2A指令带有4个参数,这里就是2个坐标值SC和EC,也就是列地址的起始值和结束值。其实在设置x坐标时,我们可以只带2个参数即设置SC即可,因为EC没有变化时,我们只设置一次即可,从而提高了速度,不用每次都多发两次数据。
       0x2B指令的用法跟0x2A很类似。

       0x2B指令也是带有4个参数,这里就是2个坐标值SP和EP,也就是页地址的起始值和结束值。其实在设置y坐标时,我们可以只带2个参数即设置SP即可,因为EP没有变化时,我们只设置一次即可,从而提高了速度,不用每次都多发两次数据。
       0x2C指令是写GRAM指令,在发送该指令之后,便可以往LCD的GRAM里面写入颜色数据,并且该指令支持连续写即地址自增。

       当发送0x2C指令之后,数据线变为16位,可以开始写入GRAM数据,即把一个个像素点的颜色值写入。在默认扫描方向(从左到右,从上到下),设置好起始坐标后(0x2A设置SC,0x2B设置SP),每写入一个颜色值,GRAM地址将会自动自增1(SC++),如果碰到EC,则回到SC,同时SP++,一直到坐标(EC,EP)结束,期间不需要再次设置坐标,大大提高了写入速度。
       当我们只需要实现画点操作时,以上指令学习已经够了,不过在GUI使用的时候,还是会经常用到读点,也就是0x2E指令。
       0x2E指令是读GRAM指令,在发送该指令之后,便可以读取GRAM的数据。

       当ILI9341收到0x2E指令后,第一次输出的是dummy数据,也就是无效数据,从第二次开始,读取的才是有效的GRAM数据(需要通过0x2A和0x2B设置位置),输出规律如上图:R1G1àB1R2àG2B2àR3G3…。如果我们只需要读取一个点的颜色值,只需要接收到参数3即可;连续读取的话,就按上述规律去接收即可。

       在这里,我们已经算是把需要了解的各部分都了解到了。接下来,我们就要把这一块一块零散的知识串一起,也就是我们的LCD最基本驱动步骤。
       1、确定IO连接关系(通过LCD模块原理图,开发板液晶接口原理图查看)
       2、初始化IO口(初始化连接LCD的各个IO口)
       3、编写8080接口函数(写数据、写命令、读数据)
       4、编写LCD初始化函数(完成初始化序列配置,设置扫描方向,设置EP/EC,点亮背光)
       5、编写LCD画点函数(实现LCD任意位置画点)

       后面就是对源码的讲解了,而这一部分我想让大家静下心来,看着附件工程进行理解,这样子对知识的理解才更加透彻。后面也跟大家分享如何使用FSMC模拟8080时序驱动LCD屏幕。

正版WIN10激活方法

1、下载微软官方工具制作U盘启动(制作时选择把操作系统一起下载到U盘中)
https://go.microsoft.com/fwlink/?LinkId=691209

2、通过U盘启动,安装系统的步骤就不介绍了
注意:系统安装完,启动时,弹出输入密钥界面,选择“我没有密钥”即可

3、系统启动后,管理员运行CMD,依次输入以下三个指令即可激活
slmgr /ipk W269N-WFGWX-YVC9B-4J6C9-T83GX
slmgr /skms kms.03k.org
slmgr /ato

亲测好用

ODOO域名访问配置

 proxy_read_timeout 720s;
 proxy_connect_timeout 720s;
 proxy_send_timeout 720s;

 # Add Headers for odoo proxy mode
 proxy_set_header X-Forwarded-Host $host;
 proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
 proxy_set_header X-Forwarded-Proto $scheme;
 proxy_set_header X-Real-IP $remote_addr;
 
 location / {
      proxy_pass http://127.0.0.1:8069;
      proxy_set_header X-Real-Ip $remote_addr;
      proxy_set_header X-Forwarded-For $remote_addr;
  }
     location ~* / {
       proxy_cache_valid 200 90m;
       proxy_buffering    on;
       expires 864000;
       proxy_pass http://127.0.0.1:8069;
  }

  # gzip
  gzip_types text/css text/less text/plain text/xml application/xml application/json application/javascript;
  gzip on;

电路中的大力士 剖析自举电路原理

自举电路也叫升压电路,利用自举升压二极管,自举升压电容等电子元件,使电容放电电压和电源电压叠加,从而使电压升高.有的电路升高的电压能达到数倍电源电压。

升压电路原理

举个简单的例子:有一个12V的电路,电路中有一个场效应管需要15V的驱动电压,这个电压怎么弄出来?就是用自举。通常用一个电容和一个二极管,电容存储电压,二极管防止电流倒灌,频率较高的时候,自举电路的电压就是电路输入的电压加上电容上的电压,起到升压的作用。

升压电路只是在实践中定的名称,在理论上没有这个概念。升压电路主要是在甲乙类单电源互补对称电路中使用较为普遍。甲乙类单电源互补对称电路在理论上可以使输出电压Vo达到Vcc的一半,但在实际的测试中,输出电压远达不到Vcc的一半。其中重要的原因就需要一个高于Vcc的电压。所以采用升压电路来升压。

开关直流升压电路(即所谓的boost或者step-up电路)原理

the boost converter,或者叫step-up converter,是一种开关直流升压电路,它可以是输出电压比输入电压高。基本电路图见图1.



假定那个开关(三极管或者mos管)已经断开了很长时间,所有的元件都处于理想状态,电容电压等于输入电压。下面要分充电和放电两个部分来说明这个电路。

充电过程

在充电过程中,开关闭合(三极管导通),等效电路如图二,开关(三极管)处用导线代替。这时,输入电压流过电感。二极管防止电容对地放电。由于输入是直流电,所以电感上的电流以一定的比率线性增加,这个比率跟电感大小有关。随着电感电流增加,电感里储存了一些能量。



放电过程

如图,这是当开关断开(三极管截止)时的等效电路。当开关断开(三极管截止)时,由于电感的电流 保持特性,流经电感的电流不会马上变为0,而是缓慢的由充电完毕时的值变为0。而原来的电路已断开,于是电感只能通过新电路放电,即电感开始给电容充电, 电容两端电压升高,此时电压已经高于输入电压了。升压完毕。



说起来升压过程就是一个电感的能量传递过程。充电时,电感吸收能量,放电时电感放出能量。如果电容量足够大,那么在输出端就可以在放电过程中保持一个持续的电流。如果这个通断的过程不断重复,就可以在电容两端得到高于输入电压的电压。



常用升压电路

P 沟道高端栅极驱动器

直接式驱动器:适用于最大输入电压小于器件的栅- 源极击穿电压。

开放式收集器:方法简单,但是不适用于直接驱动高速电路中的MOSFET。

电平转换驱动器:适用于高速应用,能够与常见PWM 控制器无缝式工作。

N 沟道高端栅极驱动器

直接式驱动器:MOSFET最简单的高端应用,由PWM 控制器或以地为基准的驱动器直接驱动,但它必须满足下面两个条件:

1、VCC
2、Vdc

浮动电源栅极驱动器:独立电源的成本影响是很显著的。光耦合器相对昂贵,而且带宽有限,对噪声敏感。

变压器耦合式驱动器:在不确定的周期内充分控制栅极,但在某种程度上,限制了开关性能。但是,这是可以改善的,只是电路更复杂了。

电荷泵驱动器:对于开关应用,导通时间往往很长。由于电压倍增电路的效率低,可能需要更多低电压级泵。

自举式驱动器:简单,廉价,也有局限;例如,占空比和导通时间都受到刷新自举电容的限制。