ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

LCD屏幕调光深度解析:DC调光与PWM调光的原理及MCU实现

LCD屏幕调光深度解析:DC调光与PWM调光的原理及MCU实现 你们有没有这种感觉手机屏幕买回来白天用着一切正常一到晚上关了灯刷两小时眼睛又干又酸甚至还有点涨痛。以前大家都以为是自己熬夜熬狠了直到“DC调光”和“PWM调光”这两个词被反复提起才知道问题可能出在屏幕本身。而在我做嵌入式开发的这些年里这个问题更是直接摆到过台面上——客户拿着样机说屏幕看着不舒服我第一反应就是查背光调光部分是怎么写的。这篇内容我打算从两个层面展开先讲清楚LCD屏幕的亮度到底是怎么来的DC调光和PWM调光在原理上差在哪再落回到实际工程聊聊在单片机驱动TFT LCD时怎么把这两种调光方式真正跑起来以及那些真正会影响使用感受的细节。不管你是准备买手机、挑显示器的普通用户还是要给设备选屏、写驱动的工程师这篇文章应该都能给你一个比较完整的答案。1. LCD亮度控制的技术底色1.1 屏幕上那一格一格的光到底怎么来要理解调光先得知道LCD是怎么发光的。很多人有个误区以为LCD屏幕本身会发光其实所有LCD都不发光它本质上是一块“光阀”。你看屏幕时看到的光来自屏幕最底下的背光层现在的设备基本都用LED灯条或者LED灯板来做背光。背光打亮之后光线穿过液晶层、彩色滤光片最后到达我们的眼睛。液晶层干的事就是控制光能不能透过去。你可以把液晶分子想象成一扇扇小百叶窗TFT阵列就是控制百叶窗开合角度的开关。每个像素点由红、绿、蓝三个子像素组成通过给TFT栅极加电压让液晶分子扭转不同的角度就能控制每个子像素的透光率从而混合出不同的颜色和明暗。所以这里有个很关键的概念要记住LCD屏幕上每个像素显示的“明暗”其实只是液晶在调节背光的透过率液晶本身并不产生光。也就是说屏幕的“底层亮度”完全由背光决定。这也是为什么LCD屏幕即使显示全黑画面也总觉得黑得不彻底——背光一直亮着只是被液晶挡掉了大部分而已。既然屏幕整体的亮度由背光决定那调光本质上就是在调背光。这就引出了我们这篇文章的核心话题调背光到底是用DC调光还是用PWM调光1.2 亮度调节的本质调背光还是调液晶有些刚入行的朋友会问既然TFT能控制透过率那我直接通过软件把所有像素的显示数据调暗不就能降低屏幕亮度吗这确实是一种“调亮度”的方式做嵌入式开发时用改变RGB灰度值来降低亮度也是很常见的做法。但我个人很不建议拿它当主调光手段来用。原因有两个。第一通过数据层面调暗像素会让画面细节大量丢失。一个255灰阶的白色如果软件上砍到128灰阶显示出来的白色就变成灰色了这是牺牲画质换亮度。第二屏幕的背光依然在全功率工作功耗一点都没降下来。对手机这种靠电池吃饭的设备来说这样的调光方式非常不划算。所以业界的主流方案都是直接控制背光LED的发光强度。而控制LED发光强度路径也就两条要么改变LED的工作电流要么让LED以很高的频率快速点亮和熄灭。前者就是DC调光后者就是PWM调光。后面关于“哪种更适合你的眼睛”的所有争论都围绕这两条路径展开。1.3 为什么说调光是嵌入式驱动里的“刚需”我在帮客户做产品方案的时候经常遇到一种情况硬件选型时大家都盯着分辨率、接口类型、色深这些参数没有人在意背光调光这一块。等样机做出来了测试人员晚上加个班发现屏幕亮得刺眼想调暗一点结果亮度一降就出现明显的闪烁感这才回过头来找调光方案的麻烦。调光这个环节看着不起眼但直接决定了产品的最终体验。强光环境下要求屏幕够亮才能在户外看清内容暗光环境下要求屏幕能调得很暗但又不能闪否则晚上用起来眼睛非常难受。在产品层面这直接和“护眼”挂钩很多品牌会在宣传页面专门标注“多少Hz高频PWM调光”、“DC调光无频闪”就是因为用户已经被频闪折磨过一轮了。对做MCU驱动LCD的工程师来说调光还是一个很现实的功耗问题。尤其在电池供电的设备里背光往往是整个系统里最耗电的模块之一一个合理的调光策略能让设备的续航有明显改善。这也是为什么这个话题虽然老但每隔一段时间就会被人拿出来讨论一次。2. DC调光与PWM调光两种方案的原理与对比2.1 PWM调光让背光快速“开-关”来平均亮度先讲PWM调光因为现在绝大多数LCD和OLED屏幕都在用这种方式。PWM的全称是Pulse Width Modulation脉冲宽度调制。它控制LED的方式不是把电流调小而是让LED以极高的频率在“完全点亮”和“完全熄灭”之间切换。用一个占空比的概念来衡量占空比50%就意味着在一个周期内LED亮一半时间、灭一半时间。虽然LED在物理上是不断在闪的但只要切换频率足够高快过人眼的临界融合频率人眼就感知不到闪烁只会觉得“光变暗了”。人眼有视觉暂留效应光信号会在大脑中整合成平均值所以50%占空比看起来就是亮度减半。频率方面不同设备的PWM调光频率差异很大。早年的手机屏幕PWM频率只有200Hz左右敏感的用户甚至能直接感受到屏幕在闪后来大家意识到这个问题慢慢做到了480Hz、960Hz现在高端设备上常见的是1440Hz、1920Hz甚至3840Hz的高频PWM调光。PWM调光最大的优势是亮度控制的线性度好且色温稳定。因为LED始终工作在额定的满电流状态下不会因为电流变化导致色温偏移这一点对显示品质非常重要。但它的问题也很突出——频闪客观存在只是感知不感知的问题。对于频闪敏感人群来说低频PWM调光在低亮度下会明显加重眼睛负担。2.2 DC调光直接压低电流改变亮度DC调光的思路就是字面意思用恒定直流电来驱动背光LED想调暗屏幕就直接降低LED的工作电流。电流大LED就更亮电流小LED就变暗。整个过程是连续变化的不存在“亮-灭-亮-灭”的切换所以理论上完全没有频闪。听起来DC调光似乎全面优于PWM调光但实际工程落地时DC调光也有不少坑。最典型的难题是LED在低电流下的色温漂移。白光LED本质上是在蓝光芯片上涂荧光粉色温表现和驱动电流有密切关系电流偏低时白光往往会偏暖偏黄。也就是说DC调光把屏幕亮度调低后画面颜色可能变得不够准。另一个问题是低电流下LED的均匀性变差。在生产过程中LED灯珠的Vf值存在离散性同一批次都很难做到完全一致。大电流时这一点差异被掩盖了但电流一降低不同灯珠之间的亮度差异就会显现出来屏幕可能看起来明暗不均。所以DC调光也不是没有代价的。2.3 两种调光方式的全面对比表我把两种调光方式放在一张表里看起来会更直观对比维度PWM调光DC调光调光原理高频开关LED用占空比控制平均亮度连续调节LED工作电流频闪问题存在开关频闪低频时人眼可感知无频闪对频闪敏感人群更友好色温稳定性高LED始终工作在额定电流下较低小电流下白光偏暖亮度均匀性好LED工作状态一致低亮度下不同灯珠差异可能放大驱动效率高LED始终处于高效工作区间低电流下LED效率下降电路复杂度简单一个MOS管加PWM信号即可需要可调恒流源或DAC加驱动电路控制精度占空比调节方便线性好非线性需要做校准适合场景手机、显示器等消费电子主流方案对频闪极敏感、有拍摄需求的场景你从表里能看出来两种方案本质上是两种取舍。PWM调光牺牲的是“闪”换来的是色彩稳定性和驱动效率DC调光牺牲的是低亮度下的色彩和均匀性换来的是无频闪的舒适体验。没有哪一方是绝对完美的。3. 在MCU上把两种调光跑起来3.1 PWM调光实现定时器输出与参数计算做嵌入式开发时我接触最多的场景是拿STM32这类MCU驱动1.8寸TFT LCD彩屏分辨率128x160主控通常是ST7735或者ILI9341。这类屏幕的背光引脚一般就是LEDA背光正极和LEDK背光负极而很多时候硬件工程师会直接用一个限流电阻把背光接到电源上这样一来背光就没法调节了。所以要实现PWM调光第一步得确认背光供电那边有没有接PWM控制电路。以STM32F103为例PWM调光的实现其实很直接。用定时器输出PWM波形接到背光驱动电路的控制端。比如用TIM3的通道1输出配置工作在20kHz的频率void Backlight_PWM_Init(void) { GPIO_InitTypeDef GPIO_InitStructure; TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure; TIM_OCInitTypeDef TIM_OCInitStructure; RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3, ENABLE); RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE); GPIO_InitStructure.GPIO_Pin GPIO_Pin_6; GPIO_InitStructure.GPIO_Mode GPIO_Mode_AF_PP; GPIO_InitStructure.GPIO_Speed GPIO_Speed_50MHz; GPIO_Init(GPIOA, GPIO_InitStructure); // 72MHz时钟预分频72计数频率1MHz TIM_TimeBaseStructure.TIM_Period 49; // 自动重载值1MHz/5020kHz TIM_TimeBaseStructure.TIM_Prescaler 71; // 预分频 (711)72 TIM_TimeBaseStructure.TIM_ClockDivision 0; TIM_TimeBaseStructure.TIM_CounterMode TIM_CounterMode_Up; TIM_TimeBaseInit(TIM3, TIM_TimeBaseStructure); TIM_OCInitStructure.TIM_OCMode TIM_OCMode_PWM1; TIM_OCInitStructure.TIM_OutputState TIM_OutputState_Enable; TIM_OCInitStructure.TIM_Pulse 25; // 占空比50% TIM_OCInitStructure.TIM_OCPolarity TIM_OCPolarity_High; TIM_OC1Init(TIM3, TIM_OCInitStructure); TIM_Cmd(TIM3, ENABLE); }计算过程很简单STM32F103的系统时钟是72MHzTIM3挂在APB1总线上预分频值设为71计数时钟就是1MHz自动重载值设为49输出频率就是1MHz除以50正好20kHz。想要50%占空比就把比较值设为25。为什么我习惯选20kHz正好卡在人耳可听频率的上限附近避免了PWM载波引起电感或电容啸叫。同时这个频率也远高于人眼可感知范围不会让人感到闪烁。如果你要做极低功耗的产品可以适当把频率降到1kHz到5kHz之间开关损耗会更小但要注意频率低于1kHz后某些敏感用户可能会察觉闪烁。3.2 DC调光实现DAC与线性驱动设计DC调光在MCU平台上的实现方式常见的有两种一种是用MCU自带的DAC模块输出可调电压控制后级的恒流驱动电路另一种是用DA转换芯片或者数字电位器本质上也差不多。我的建议是优先使用DAC加运放的方式因为它的线性度和稳定性相对可控。比如STM32F103系列没有内置DAC可以外挂一颗MCP4725这类I2C接口的12位DAC输出0到3.3V的模拟电压再去控制背光LED驱动芯片的模拟调光引脚。简单一点的场景可以直接用DAC输出控制一颗三极管或MOS管让背光电流随DAC电压变化。伪代码如下void Set_Backlight_DC(uint8_t brightness) { uint16_t dac_value; // 12位DAC0-4095对应0-3.3V dac_value (uint16_t)(brightness * 40.95f); I2C_Write_DAC(dac_value); // 通过I2C写入DAC芯片 }这里的brightness是0到100的亮度百分比乘以40.95映射到12位DAC的0到4095范围。如果LCD的背光LED额定电压和电流规格不同后级需要搭配专门的LED恒流驱动芯片来用DAC只是提供一个控制电压不直接驱动背光否则电流会失控烧掉LED灯珠。我一直想提醒大家的是如果你的产品没有特别强的低亮度色准要求只是希望“不闪”那用“PWM输出加一级RC低通滤波”也能得到近似DC调光的效果。把PWM先整成平滑的直流电平再去控制LED驱动这种方案成本低效果也还行适合预算有限的项目。但要注意RC滤波会带来响应延迟亮度切换的时候会有个渐变过程如果是做交互性很强的产品会有迟滞感。3.3 亮度曲线的gamma校正直接映射是错的这块内容属于经验之谈网上很多调光教程都没提到。如果你直接把用户设置的“亮度百分比”映射成PWM占空比或DAC输出值你会发现实际观感非常奇怪——低亮度区域稍微动一下屏幕变化就很剧烈到了高亮度区域怎么调都感觉差别不大。原因在于人眼对亮度的感知不是线性的。人眼在暗部的分辨能力更强在亮部的分辨能力更弱物理亮度翻一倍人眼感知到的“亮了一倍”并不会同步发生。所以科学的做法是加一个gamma曲线做校正。显示行业里常用的gamma值是2.2也就是说设置值S和实际物理亮度L之间应该满足这样的关系L等于S的2.2次方。在MCU上算浮点开销太大一般做成查找表。比如要支持0到100档亮度可以预先算好一张100项的gamma表烧录到代码里const uint8_t gamma_lut[101] { 0, 0, 0, 0, 1, 1, 1, 2, 2, 3, 3, 4, 5, 5, 6, 7, 8, 9, 10, 11, 12, 14, 15, 16, 18, 19, 21, 22, 24, 26, 28, 30, 32, 34, 36, 38, 40, 43, 45, 48, 50, 53, 56, 59, 61, 64, 67, 70, 73, 77, 80, 83, 87, 90, 94, 97, 101, 105, 108, 112, 116, 120, 124, 128, 132, 136, 141, 145, 149, 154, 158, 163, 167, 172, 177, 181, 186, 191, 196, 201, 206, 211, 216, 222, 227, 232, 238, 243, 249, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255 };这张表是gamma 2.2的近似结果一共101个值。用户设置“50%亮度”时应该查这张表得到对应的实际输出值而不是直接用50去映射。你看表里50档对应的值是53100档对应255这样校正之后用户看到的变化才是相对均匀的。做产品时我还习惯把gamma表和PWM频率解耦开gamma表只负责“设多少看起来是多少”PWM频率则固定在一个对人眼友好的值上不动。这样既保证了观感的一致性也避免了频繁修改定时器参数带来的不稳定。4. 场景化选型不同产品怎么选调光方案4.1 从人眼的角度直接回答“哪种更适合你的眼睛”回到文章标题那个问题哪种调光方式更适合你的眼睛我的看法是要分人、分场景。如果你对频闪不敏感日常使用手机电脑也从来没有觉得眼睛难受那PWM调光完全没问题它的色彩表现和亮度控制都更稳定。但如果你是一个对闪烁很敏感的人用低频PWM屏幕的设备超过半小时就觉得头晕眼花那你应该优先选择DC调光或者高频PWM调光的产品。从参数上看判断方法很粗暴看OLED屏幕的话尽量选高频PWM1440Hz以上的机型看LCD屏幕的话能选DC调光就选DC调光如果产品标注的是PWM调光就看频率低于1000Hz的建议直接避开。低频PWM在亮度调低时占空比会变得很小LED亮的时间极短、灭的时间很长这会带来非常明显的暗部闪烁那种情况下眼睛很容易疲劳。还要提一嘴环境光的影响。在明亮的户外PWM调光就算频率低一点也不太容易被人感知到因为人眼在亮环境下对闪烁的敏感度会下降。但在黑暗环境中瞳孔放大、视觉系统对光变化更敏感低频PWM的问题就会被放大。所以“晚上关灯玩手机”这个场景恰恰是对调光方案考验最严酷的场景。4.2 仪器仪表与嵌入式设备的选型建议做工业仪器仪表、家用小家电的嵌入式开发时选调光方案不能照搬手机的思路要考虑自己产品的实际情况。如果是7段数码管或者段码LCD这类不带背光的显示器件谈不上DC调光还是PWM调光它们是通过动态扫描方式驱动的调节亮度通常靠调整扫描占空比来实现效果影响的主要是对比度而不是均匀性。这类屏在强光下反而更清晰所以一般不需要复杂的背光调光策略。如果是TFT彩屏产品我的选型逻辑是这样的能选DC调光就先选DC调光特别是在那些需要长时间盯着看的设备上比如医疗监护仪、工控面板、收银终端。这类设备往往在室内环境使用环境光变化不大DC调光带来的色温变化几乎可以忽略但无频闪的舒适感对用户来说非常实在。如果是电池供电的便携设备我建议还是要优先考虑PWM调光因为DC调光在低亮度区域LED驱动效率偏低而且为了做模拟调光要多加一颗DAC占用PCB面积不说还增加成本。PWM调光一个芯片引脚就能搞定效率还高。4.3 高频PWM与混合调光的折中方案这几年消费电子领域有个趋势很多厂商在宣传“DC调光”时实际上用的是“高频PWM调光”比如1920Hz、3840Hz。严格来说这些还是PWM调光不是真正的DC调光但因为频率足够高人眼已经很难感知到频闪了在实际体验中和DC调光的差距很小。高频PWM的工程价值在于它保留了PWM调光在色温稳定性和驱动效率上的优势又尽量消除了频闪对用户的影响。所以如果你是在做一款以用户体验为核心的产品预算又不支持做复杂的DC调光电路那一颗能输出20kHz PWM的MCU加一颗低压降的LED驱动芯片就是性价比非常高的方案。还有一条路是混合调光这也是我在一些高端项目里用过的思路高亮度区间用DC调光保证色彩和均匀性亮度降到某个阈值以下切到PWM调光避免小电流下的色偏和不稳定。比如我最近做的一块7寸屏控制板驱动IC用的TPS61165它的模拟调光引脚和PWM调光引脚都引出来了我就在固件里做逻辑判断亮度大于30%走模拟调光小于30%切PWM频率定在20kHz。实测效果是低亮度下色偏明显比纯DC调光好频闪也感知不到。5. 常见问题与调试实录5.1 手机拍屏幕有条纹是屏幕坏了吗很多人在用手机拍别人的屏幕时会发现画面里有一道道横向的黑色条纹还以为是屏幕坏了。其实这是卷帘快门效应是手机相机的传感器逐行曝光导致的不是屏幕故障。你可以这么理解屏幕以PWM方式闪烁相机的曝光是一行一行进行的不同的行在不同时刻曝光自然就记录下了明暗交替的条纹。但这个方法也有用处我们可以用它来快速判断一块屏幕的调光方式。把相机快门速度调到1/4000秒以上去拍屏幕如果出现明显的黑条纹说明屏幕用PWM调光如果拍出来还是均匀的说明要么是DC调光要么PWM频率极高超出了相机采样的感知范围。条纹越稀疏说明PWM频率越高条纹越密频率越低。在项目验收时这个方法可以直接拿来检查供应商有没有虚标参数。工程师做产品时还要注意如果你用的是工业相机做视觉检测而产品屏幕背光恰好用了低频PWM调光拍摄画面里大概率会出现频闪条纹这会严重干扰检测算法的识别。解决方案是让背光PWM频率与相机曝光时间错开或者干脆给视觉检测工位单独配DC调光的屏幕。5.2 低频PWM导致眼睛疲劳用户售后反馈怎么处理做消费电子产品的朋友应该遇到过这种售后问题用户并不懂什么是PWM只会反馈“屏幕看着头晕”、“眼睛很累”。这种情况下单从硬件上去改调光方案已经来不及了软件上可以做几个缓解措施。第一个办法是限制背光最低亮度。很多设备在系统层面允许用户把亮度调到1%而PWM在这个占空比下闪烁感是特别明显的。把软件上的最低亮度限制在15%到20%之间虽然用户没法把屏幕调到特别暗了但至少避免了一部分频闪带来的不适。第二个办法是开启“降低白点值”这类功能用软件的方式降低显示内容的亮度而不是继续压低背光。比如iOS的“降低白点值”和Android的“灰度模式”本质上是让像素显示更暗而背光保持在一个相对舒服的占空比上。这个思路做嵌入式产品时同样适用。第三个办法是在系统更新里加入一个“护眼模式”本质是让背光PWM频率升高降低占空比的突变速度。如果产品用的MCU有硬件PWM模块改频率只是改几个寄存器的事软件层面的调整成本很低。5.3 出现“滋滋”声和斜纹水波纹的处理办法高频PWM调光在工程落地时还容易带出一个问题20kHz以下的PWM频率和扬声器、麦克风器件互相干扰或者直接让背光驱动电路里的电感发出“滋滋”声。这个声音频率落在人耳可听范围内听感非常难受。解决办法有三种思路。第一PWM频率往上调超过20kHz人耳就听不到了但要留意MCU里音频外设是否会被影响。第二检查背光LED驱动电路的电感和电容选型换用低噪音磁屏蔽电感或者在输出端并联一个高频陶瓷电容来吸收纹波。如果电感已经有啸叫用示波器去测量PWM波形看是否存在振铃有的话需要调整RC吸收电路。第三从软件上避免占空比瞬间大跳变每次调整亮度时让目标值通过渐变曲线慢慢变过去这样能减少激励电感的瞬态冲击也能减少啸叫。另外我还遇到过一种斜纹水波纹的现象屏幕显示纯色画面时能看到有规则的斜向纹理在缓慢滚动。排查下来问题出在背光PWM频率和面板的扫描刷新频率接近产生了差频干涉。LCD面板是靠TFT逐行扫描刷新的如果PWM频率恰好是扫描频率的整数倍附近就会形成这种可见的干涉条纹。解决办法是改变PWM频率让它尽量偏离面板扫描频率的公倍数区域。GOA类的面板因为栅极驱动集成在玻璃基板上扫描时序更容易受到负载影响出现这种问题的概率会高一些。5.4 常见问题速查表故障现象可能原因排查思路与解决方案屏幕肉眼可见闪烁PWM频率过低将PWM频率提升到1kHz以上或切到DC调光手机拍摄屏幕有条纹卷帘快门效应与PWM频闪叠加正常现象提高快门速度后条纹更明显即证实PWM调光暗光下屏幕颜色偏黄DC调光低电流下LED色温漂移低亮度切换PWM调光或软件校准色温背光有“滋滋”声PWM频率落在可听区或电感谐振频率升到20kHz以上检查电感/电容选型屏幕出现斜纹/水波纹PWM频率与面板扫描频率拍频调整PWM频率避开差频区间亮度调节不跟手RC滤波或渐变曲线时间过长减小滤波电容或缩短渐变步进延时低亮度画面不均匀LED灯珠Vf离散小电流差异放大提高最低亮度阈值或改用恒流驱动这里再分享一个做产品迭代时很实用的调试习惯每次改完调光策略不要只在台架上测拿一部手机用高速快门对着屏幕拍一段视频回放看有没有频闪痕迹。这个土办法比参数分析还直观能快速筛出那些“参数上正确但体验上翻车”的设计。我个人做了这么多年的嵌入式显示项目最大的感受是调光这件事参数好写体验难调。PWM频率、占空比、gamma表、电流精度每一项都看似简单组合在一起却决定了用户会不会在晚上刷十分钟屏幕就揉眼睛。所以我现在的习惯是只要项目没有极端的功耗限制背光PWM固定用20kHz亮度曲线用gamma表校正低亮度部分该切DC就切DC。如果条件不允许上DAC就在PWM输出后面挂一级RC滤波截止频率大概设在100Hz左右把高频分量滤掉输出近似直流的电平对看静态界面的仪器仪表来说完全够用。调光设计没有银弹但搞清楚原理之后你至少知道手里的每一寸光都是怎么来的也知道该把哪些参数留给眼睛去投票。
返回列表