LCD 调试方法及问题汇总

调试流程

1. 设置 DTS 中的参数 并 配置管脚

仿造平台的其他 lcd-*-mipi.dtsi 编写 lcd-xxx-mipi.dtsi 后 需要在 主 dts 文件中包含这个 dtsi

#include “lcd-xxx-mipi.dtsi“

先看屏的手册

里面的关键信息有 分辨率(540×960) 接口(2条lanes)

 

## MIPI Host配置
disp_mipi_init: mipi_dsi_init{
        compatible = "rockchip,mipi_dsi_init";

        /* 是否要在 dtsi 中初始化 1 0 */
        rockchip,screen_init    = <1>;

        /* 要几条数据 lane ,根据原理图和 mipi 规格书*/
        rockchip,dsi_lane       = <2>;

        /* ddr clk 一条 lane 的传输速率 Mbits/s  */
        /* 100 + H_total×V_total×fps×3(一个rgb为3字节)×8(8bits)/lanes  */
        /* 这里的 total 指的是 sync + front + back + active */
        /* 比如 H_total = Hsync + HFP(hfront-proch)  + HBP(hback-porch) + Hactive  */
        rockchip,dsi_hs_clk     = <1000>;

        /* 单mipi 还是双 mipi*/
        rockchip,mipi_dsi_num   = <1>;
};

看原理图,完成管脚的配置

可以看到,我这里只用到了 LCD_RST,没有用到 LCD_EN (是 VCC_LCD),说明是默认使能的,也没有 LCD_CS
所以进行如下配置

## 屏电源控制配置
disp_mipi_power_ctr: mipi_power_ctr {
        compatible = "rockchip,mipi_power_ctr";
        mipi_lcd_rst:mipi_lcd_rst{
                compatible = "rockchip,lcd_rst";
                rockchip,gpios = <&gpio2 GPIO_B7 GPIO_ACTIVE_LOW>;
                rockchip,delay = <100>;
        };
        /*
        // 配置 lcd_en GPIO 哪一路 ,有可能没有 LCD_EN 那么就是 VCC 常供电
        mipi_lcd_en:mipi_lcd_en {
                compatible = "rockchip,lcd_en";
                rockchip,gpios = <&gpio0 GPIO_C1 GPIO_ACTIVE_HIGH>;
                rockchip,delay = <100>;
        };
        */
        //还可能有片选 cs
};

根据屏的规格书 完成 timings 配置
垂直方向的信息:


重要的参数有 垂直同步信号 VFP VBP VS 对应填充到屏参中的 Vfront-proch Vback-proch Vsync-len
同样
水平方向的信息:

要注意的是, HS HBP HFP 虽然最小值是 5,但是不能设置的这么低
因为后面还有两条要求,HBLK = HS + HBP + HFP >= 24 且 HS + HBP > 19
所以最初设置 HS = HBP = HFP = 10

// lcd-xxx-mipi.dtsi 中的 屏参
disp_timings: display-timings {
        native-mode = <&timing0>;
        compatible = "rockchip,display-timings";
        timing0: timing0 {
            screen-type = <SCREEN_MIPI>;        //单mipi SCREEN_MIPI 双mipi SCREEN_DUAL_MIPI
            lvds-format = <LVDS_8BIT_2>;        //不用配置
            out-face    = <OUT_P888>;       //屏的接线格式 
            //配置颜色,可为OUT_P888(24位)、OUT_P666(18位)或者OUT_P565(16位)
            clock-frequency = <120000000>;      //dclk频率,看规格书,或者 H×V×fps
            hactive = <540>;            //水平有效像素
            vactive = <960>;            //垂直有效像素
            hback-porch = <80>;         //水平同步信号
            hfront-porch = <81>;            //水平同步信号
            vback-porch = <21>;
            vfront-porch = <21>;            
            hsync-len = <10>;           //水平同步信号
            vsync-len = <3>;
            hsync-active = <0>;         //hync 极性控制 置 1 反转极性
            vsync-active = <0>;
            de-active = <0>;            //DEN 极性控制
            pixelclk-active = <0>;          //dclk 极性控制
            swap-rb = <0>;              //设 1 反转颜色
            swap-rg = <0>;
            swap-gb = <0>;

2. 背光部分

在 rk3288-tb_8846.dts 中还需要打开 mipi 相关的通道 并 配置背光相关的信息。
首先根据这颗背光 IC 的 datasheet

我们了解到 EN 拉高时背光使能,拉低时背光禁能; FB 接受反馈信号,动态控制背光亮度

我们知道这颗背光芯片有两种调光方式
一是 EN 输入 PWM 信号进行调光
二是 EN 使能后,通过 FB 获得反馈信号进行调光。
根据我们的原理图


BL_EN 是普通的 GPIO ,LCDC_BL 是支持 PWM 输出的管脚,所以得知我们硬件采用的是第二种调光方式

 

backlight {
        compatible = "pwm-backlight";
        pwms = <&pwm0 0 25000>;     //在这里配置采用的是 pwm0 还是 pwm1
        brightness-levels = <255 254 253 252 251 250 249 248 247 246 245 244 243 242 241 240
             239 238 237 236 235 234 233 232 231 230 229 228 227 226 225 224 223 222 221 220
             219 218 217 216 215 214 213 212 211 210 209 208 207 206 205 204 203 202 201 200
             199 198 197 196 195 194 193 192 191 190 189 188 187 186 185 184 183 182 181 180
             179 178 177 176 175 174 173 172 171 170 169 168 167 166 165 164 163 162 161 160
             159 158 157 156 155 154 153 152 151 150 149 148 147 146 145 144 143 142 141 140
             139 138 137 136 135 134 133 132 131 130 129 128 127 126 125 124 123 122 121 120
             119 118 117 116 115 114 113 112 111 110 109 108 107 106 105 104 103 102 101 100
             99 98 97 96 95 94 93 92 91 90 89 88 87 86 85 84 83 82 81 80 79 78 77 76 75 74 73 72 71 70
             69 68 67 66 65 64 63 62 61 60 59 58 57 56 55 54 53 52 51 50 49 48 47 46 45 44 43 42 41 40
             39 38 37 36 35 34 33 32 31 30 29 28 27 26 25 24 23 22 21 20 19 18 17 16 15 14 13 12 11 10
             9 8 7 6 5 4 3 2 1 0>;
        default-brightness-level = <200>;
        enable-gpios = <&gpio7 GPIO_A2 GPIO_ACTIVE_HIGH>;   //BL_EN 背光使能管脚
    };

3. LCD 初始化序列 CMDS

最后如果有初始化序列的,打开之前的 screen-init = < 1 > ,并且填充初始化序列

## 屏初始化序列
disp_mipi_init_cmds: screen-on-cmds {
        compatible = "rockchip,screen-on-cmds";
        /*rockchip,cmd_debug = <1>;
        rockchip,on-cmds1 { //指的是一条初始化命令
                compatible = "rockchip,on-cmds";
                rockchip,cmd_type = <LPDT>;     //命令是在 low power(LPDT)还是 high speed(HSDT)下发送
                rockchip,dsi_id = <2>;          //选择通过哪个mipi发送 0==》单mipi0  1==》mipi1 2==》双mipi0+1
                rockchip,cmd = <0x05 0x01>;     //初始化命令
                    //第一个字节 DSI 数据类型; 第二个字节为 LCD 的 CMD; 后面为指令内容
                rockchip,cmd_delay = <0>;
        };
        */
};

值得一讲的是 cmd,一般屏厂或者FAE都会给出初始化序列。
比如这里我拿到的是 MTK 平台的 LCD 初始化代码:

data_array[0]=0x00043902;
data_array[1]=0x8983FFB9; 
dsi_set_cmdq(&data_array, 2, 1); 
MDELAY(10);

分析得知
array[0] 中 04 代表要传输的字节数,3902 代表传输的是长包数据
//MTK平台 3900 代表不传值 3905 表示传一个数据 3902 表示传多个数据
array[1] 中的参数全部为传输的参数,而且正确的传参数据为 B9 FF 83 89
所以移植到 RK 平台就是:

rockchip,on-cmds1 {
                            compatible = "rockchip,on-cmds";
                            rockchip,cmd_type = <LPDT>;
                            rockchip,dsi_id = <0>;
                            rockchip,cmd = <0x39 0xB9 0xFF 0x83 0x89>;
                            //0x39 为 DSI 数据类型、  0xB9 为LCD CMD、后面为参数
                            rockchip,cmd_delay = <10>;
}

我们根据 这块 lcd 的 规格书,也能够验证结果初始化命令参数的正确性:

DSI 协议中 ,0x29 和 0x39 区别:在 Mipi 协议中,它俩都表示 长包(Long Packet)数据类型。
但是 Mipi DSI 的 Spec 中写着两者的区别 0x29 属于 Generic long write ,0x39 属于 DCS long write。
DCS 系的读写命令,可带参数,常用于 LCD 初始化参数命令。
Generic 系读写命令,是协议规范外的命令,通常是一些 IC 定制的,只要确保主机和外设同意这些数据格式即可,通常和 DCS 通用。

另外值得一说的是大部分初始化代码的最后一般都是 exit_sleep 和 display_on。

rockchip,on-cmds15 {
                            compatible = "rockchip,on-cmds";
                            rockchip,cmd_type = <LPDT>;
                            rockchip,dsi_id = <0>;
                            rockchip,cmd = <0x05 dcs_exit_sleep_mode>;
                            rockchip,cmd_delay = <120>;
                    };
                    rockchip,on-cmds16 {
                            compatible = "rockchip,on-cmds";
                            rockchip,cmd_type = <LPDT>;
                            rockchip,dsi_id = <0>;
                            rockchip,cmd = <0x05 dcs_set_display_on>;
                            rockchip,cmd_delay = <100>;
                    };

这里 dcs_exit_sleep_mode dcs_set_display_on 在 drivers/video/rockchip/transmitter/mipi_dsi.h 中有定义

#define dcs_set_display_on  0x29
#define dcs_exit_sleep_mode 0x11

所以表示的 0x05 0x11 表示的含义为,短包传输 发送 exit_sleep_mode 命令
这两个命令后的延时*相当重要*!!务必确认好。

4. 打开 CONFIG

根据 RK 手册中的要求
make menuconfig
打开三个宏

这里也可以顺手把 LVDS 的相关代码给关掉

 

5. 检查电压

先不要接上屏,编译完代码烧录后开机。
检查原理图上各个供电管脚的电压(DVDD、IOVDD 是否为 3.3V,VDD_LCDA 是否为 5-10V,VDD_LCDK 是否为 0V),确认电压正常后,关机,上屏,结合 开机log 看能否正常开机。

6. 调试顺序

6.1 背光有没有亮

背光没亮的话确认一下接上屏的时候,量一量 VDD_LCDA 的电压为多少(串联电路大概能到 20V+)
没有就去检查背光电路供电电压和 backlight 相关的配置

6.2 开机 以及 从休眠状态唤醒 都没有显示内容

之所以这样说是因为可能存在 休眠唤醒 能显示,但 开机 无法显示的情况
如果两种情况都没有显示,那么很有可能是 cmds 或者 timing 仍然有问题
1. 用示波器量波形看 DCLKP 的频率为多少,是否为 clock-frequency 中设置的(可能实际的会略低一点)
2. 量 RST 是否有一个 低-高 的变化,没有则是 rst 设置的触发方式可能反了
3. 在 RST 高低高后会开始传输数据,量 lanes 是否有数据输出。抓取数据需要专门的仪器,我们用示波器大致看看有没有数据输出就够了。

我在调试的时候就发现 lane 一直为低电平,没有数据传输,然后采取量 RST 发现唤醒屏后待到屏幕快灭了 RST 才会被拉高。跟代码发现 RK 平台的实现是

!你设置的触发电平
你设置的触发电平

但是我设置的触发电平是 低电平有效 ACTIVE_LOW

!ACTIVE_LOW
ACTIVE_LOW

即先高再低,所以是错的,改为 ACTIVE_HIGH 后正常。
但是虽然填的是 ACTIVE_HIGH ,但是应该还是属于低电平有效的,这里是 RK 平台 driver 的实现有问题。
修改后 lane 有数据传递了。

但是有数据传递仍然怎么样都没有显示。
这时候有极大可能是 cmds 有问题。
下面着重讲一下我 cmds 碰到的问题。

6.3 我碰到的 CMDS 问题

我当时拿到 MTK 平台参数的时候,有的参数超过了 32个字节(有个有36个字节,有个有39个字节),完成 dtsi 中 cmds 编写后
烧录,板子跑飞,空指针异常。
发现传递 这个超长 参数的时候有内存溢出情况。
于是跟代码发现 dcs_cmd.cmds 的大小为 int cmds[32],所以擅自想当然的将包拆成了 39 = 28+11,还将其中的延时设置为 0 。
这样当然是不行的。但是一切都是基于这个拆了包的 cmds 来调,走了不少弯路。
后来一切的其他参数都确定没问题了。
于是去联系原厂的工程师,说平台参数大小有限制,咨询拆包是否可行。他们说建议修改 cmds[32] 改成了 cmds[400] 。
修改后发现屏幕终于点亮了。
终于点亮了。
点亮了。

问题集锦

RK 手册中已经有相当一部分很有参考价值的了。
这里的一部分是自己碰到的,有的是查资料时候收集到觉得很有意义的,都放这里了。

1. 我调试中碰到的问题

  1. 在点亮屏后刚开始有开机 logo 闪烁,向右偏移了近半个屏幕的长度,等问题。
    重新确认 clock-frequence 后发现少打了一个 0 。
    修改后解决了 闪烁,大偏移 的问题。
  2. 最初偏移还是有点大,如下图。


  3. 稍微降低 hs_clk ,由 504 降低到 496 解决。
  4. 垂直方向会显示多一点内容,如下图。

    调整 VFP 后解决,将 VFP 增大为 15 。
  5. 下面会有黑边,如下图。


    稍微增大 VBP 后解决,将 VBP 增大为 15。
  6. 开机 android 最左边会被裁剪一部分,如下图。


    增大 HBP 后解决,将 HBP 由 10 增加到 30。
    至此屏幕已完美显示。

 

2. 其他一些杂散的需要确认的内容

是否有framebuffer輸出,要是改動了display這塊的clk很有可能沒有buffer輸出的,可以通過cat /dev/graphyics/fb0查看有沒有輸出字符。(我是通过google 插件 vysor 直接连接开发板看有没有内容显示,windows 平台也可以用 total control 软件来看)

3. 参数为 8 字节、16字节 传输会异常?错,可以正常传输。

看到一篇文章中说,数据 cmds 为 8 字节 和 16 字节 的时候,写命令和数据的函数要注意变化。
然后在调试的时候发现 如果 参数为这两种情况的时候, 传输模式会自动由 LP 模式 变成 HS 模式。但这只是个意外
跟踪代码后发现,其实是可以正常传输的,我这只是个意外而已:
[Android5.1][RK3288] LCD Mipi 初始化长包数据规范问题_Younix脏羊的博客-CSDN博客

4. 显示偏移、图像位置偏差

timing 中的参数设置有误。优先确认。
看着图像调节前扫、回扫进行左右上下移动

5. 白屏

随机出现白屏有可能是静电问题,把LCD拿到头发上擦几下,如果很容易出现白屏那肯定就是静电问题了。另外一个在有Backend IC的情况下,也有可能bypass没处理好。
結束開機logo至android動畫出現之間出現閃屏或者閃白光的情況。原因:在這個時間點kernel會會對屏再次初始化,我們可以軟件上屏蔽第一次初始化動作從而解决。

6. 屏在进出睡眠或者显示过程中白屏

喚醒屏幕閃白光問題,說白了是背光早亮了,很有可能是下序列mdelay太久,改小點就沒有這個問題了。根本原因屏幕初始化序列下慢了。
sleep out(0x11)和 display on(0x29)之间需要 mdelay(120ms)左右。

7. 花屏

说明 lcd 初始化成功,但是没有 rgb 刷过来。
timing 中的参数设置有误。优先确认 pclk。
花屏 还可能是总线速度有问题。
开机就花屏最简单的解决方式是,在 Init 结束的地方加一个刷黑屏的功能。也可以在睡眠函数里加延时函数。

8. 屏幕闪烁

  1. pclk 有问题
    在最开始的时候,我的 pclk 漏了一个 0 ,为之前的 1/10 此时就有图像闪烁问题。
  2. proch 有问题
    在调试完后,我尝试将 proch 增加到极限,发现会出现图像闪烁的问题。

9. 屏幕抖动

测时序,延时不足

10. 屏幕闪动

通过调节电压来稳定,一般调节的电压为VRL、VRH、VDV和VCM

11. 唤醒闪屏问题

这是由於每次重新RST下序列過程delay久了導致,适當減少delay時間

12. 屏幕唤醒显示灰色底面

寄存器没有使能外部升压电路

13. 水波纹

通常都是rgb interface polarity導致,需要調整pclk hsync vsync de極性使之符合平台極性

14. 调节对比度

VRL、VRH、VDV和VCM,这些电压也可以用来调节亮暗(对比度)
也可以通过调节Gamma值来实现,要调节的对象为 PRP、PRN、VRP、VRN 等

15. 确认有没有 FRAMEBUFFER 输出

要是改动了display这块的clk很有可能没有buffer输出的,可以通过cat /dev/graphyics/fb0 查看有没有输出字符
如果有说明是 mipi 还没有调通,如果没有说明是 fb 有问题

16. 图像颜色不正常

可能时钟型号极性反了
可能 VCOM 调节不正常
进行 GAMMA 校正

  • 8
    点赞
  • 71
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: 使用STC MCU的I/O口直接驱动段码LCD,涉及到以下几个步骤: 1. 准备工作:选择一款合适的段码LCD并获取其数据手册,了解其引脚定义和通信协议。确定STC MCU中可用的I/O口数量和引脚分配。 2. 连接电路:根据数据手册,将LCD的引脚和STC MCU的I/O口引脚相连接,包括数据线和控制线。按照需要还需要连接显示器的电源线。 3. 初始化:在程序中对相关的I/O口进行初始化配置,包括设置引脚的输入输出模式、上拉电阻以及时钟频率等参数。 4. 扫描程序:使用循环程序对LCD进行扫描。通常LCD显示器的驱动方式为多路复用,需要通过逐行扫描的方式来显示整个屏幕。循环中,先通过控制线给LCD发送扫描命令,然后通过数据线发送具体要显示的数据。 5. 显示数据:在每次扫描中,使用STC MCU的I/O口将要显示的数据发送给LCD。根据LCD的通信协议,可能需要先发送一些控制命令(如选择显示位置等),然后发送具体的段码数据。 6. 更新屏幕:循环进行扫描,逐行显示数据,并根据需要进行刷新屏幕。可以设置适当的延时时间来控制刷新频率,进而达到更新屏幕显示的目的。 总结:使用STC MCU的I/O口直接驱动段码LCD的原理是通过控制LCD的引脚信号,实现对LCD屏幕的扫描和显示。需要根据LCD的数据手册和STC MCU的引脚分配进行正确的连接和初始化配置,然后编写扫描程序来循环发送数据并更新屏幕显示。 ### 回答2: 用STC MCU的I/O口直接驱动段码LCD,需要理解LCD的工作原理和扫描程序的设计。 首先,段码LCD是一种基于液晶显示原理的显示器,它可以通过电压来控制液晶材料的透明度,从而显示出不同的图像或文字。 现代的段码LCD通常由多个分段组成,每个分段代表一个特定的字符、数字或符号。每个分段又由多个液晶单元组成,每个液晶单元可以分为多个段来控制显示的精度。 STC MCU的I/O口可以输出或输入数字信号,通过适当的编程和控制,可以将数字信号转换为液晶显示所需要的电压。一般来说,液晶显示需要的电压有高电平和低电平两种,通过不同的电压来控制液晶材料的透明度。 为了实现对段码LCD驱动,需要编写相应的扫描程序。扫描程序主要包含以下几个步骤: 1. 初始化:设置I/O口的输入输出方向和初始状态。 2. 显示设置:设置显示模式、字符或数字的显示位置等。 3. 数据准备:将要显示的数据存储到缓冲区或寄存器中,以备显示时使用。 4. 扫描循环:根据需要的显示模式、字符或数字的个数等,在循环中不断更新液晶单元的电压。可以使用计时器或延时函数来控制每个液晶单元的显示时间。 5. 清除:在每次显示周期结束后,清除屏幕上显示的内容,为下一次显示做准备。 通过以上的扫描程序,可以实现对段码LCD驱动,实现显示不同的字符、数字或符号。在编写程序时,需要根据具体的段码LCD型号和STC MCU的特点进行相应的调整和适配。同时,还需要注意液晶的使用、电压的控制以及程序的时序等问题,以确保显示效果的稳定和准确。 ### 回答3: STC MCU是一款常见的微控制器单片机,具有多个I/O口可以用于连接外部设备。要驱动段码LCD,可以使用其中的I/O口直接控制每个LCD的段码。 驱动段码LCD的原理是通过控制每个段的电平状态来显示所需的字符或图形。段码LCD通常由多个数字段和少量小数点组成,每个段用于表示特定的数字、字母或字符。使用STC MCU的I/O口,我们可以通过控制每个段的输入和输出数据来实现所需的显示。 扫描程序是通过循环控制其中的I/O口输出特定的数据来驱动段码LCD。通常情况下,LCD是通过多路复用扫描来实现对不同段的控制。在扫描程序中,我们需要设置LCD的工作模式并配置相应的I/O口为输出模式。 在程序中,我们需要定义每个字符或图形所需的段码数据,然后通过循环将每个段的数据逐个传输到LCD的对应I/O口上。扫描程序会根据设定的扫描频率循环执行,通过改变每个段的输入数据以实现显示效果。 使用STC MCU的I/O口直接驱动段码LCD的优点是简洁、高效、可靠。通过直接连接I/O口,我们无需外部驱动器或复杂的电路设计即可实现LCD驱动。同时,STC MCU提供了丰富的GPIO资源,使得我们可以连接多个段码LCD或其他外部设备,并进行复杂的控制。 需要注意的是,在编写扫描程序时,我们需要了解LCD的数据手册,确保正确设置每个段的输入和输出数据,以及合适的扫描频率,以获得所需的显示效果。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值