本文主要是介绍屏幕背光闪烁,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!
1、背景
由于硬件所选 背光芯片 在调到最大背光时出现闪烁不稳定的问题,需要监控背光芯片 IC/ TPS92380 的 lcdbl_fault gpio 引脚,该引脚正常 对外输出为高,异常为低,恢复正常会主动为高。该 IC 芯片走 pwm 控制背光。
2、解决方式
- 通过中断的方式监控该 ic 的 lcdbl_fault gpio 引脚
- 应用层设置背光最大的亮度值时,驱动层需要降低为实际最大输出值的90% ,以延长背光ic芯片的使用寿命。
3、pwm的简单介绍和应用
3.1 介绍
脉冲宽度调制(简称脉宽调制,通俗的讲就是调节脉冲的宽度。全称: Pulse Width Modulation),是电子电力应用中非常重要的一种控制技术。理解TA之前我们需要了解一下介个概念:
脉冲周期(T): 单位是时间,比如纳秒(ns)、微妙(μs)、毫秒(ms);
脉冲频率(F): 单位是赫兹Hz、千赫兹(kHz)等,与脉冲周期成倒数关系,F=1/T;
脉冲宽度(W): 简称“脉宽”,是脉冲高电平持续的时间。单位是时间比如纳秒微妙毫秒等;
占空比(D): 脉宽除以脉冲周期的值,百分数表示,比如50%。
以上几个概念之间的关系如下:
3.2 应用
工程应用中的PWM波是幅值、周期(或频率)不变,脉宽(或占空比)可调的脉冲波。例如 如果我们想要控制一个直流电机的转速,我们可以通过改变其两端电压即可;但是该种方法有很大的局限性,可调直流电源构造复杂、成本高昂,应用起来很不现实。所以我们采用另外的控制方式:电压源→驱动器→直流电机,电压源提供直流电压,不同的驱动器控制不同的直流电机,应用非常灵活。其中驱动器对电机的调速控制就是利用PWM。
可调直流电源控制与PWM控制都能调速,那么它们有什么相同之处呢?
电机为某相同转速时,红色代表驱动器输出幅值不变的PWM波,蓝色代表可调直流电源输出的电压。两者都是直接作用到负载。
有上面的图片得知:
当PWM波的占空比越大时,所对应的直流电压与PWM波的幅值越接近;反之与0V越接近;周期的红色PWM波脉宽下的矩形面积之和与蓝色直流电压的面积相等,即伏秒积相等:U红(幅值) × ton = U蓝 × T ,两端同时除以T,得到如下关系式:U红(幅值) × 占空比 = U蓝 。
例如当PWM波的幅值为24V,占空比为50%时,与直流电压12V作用到电机上所产生的效果是一模一样的,即速度相同;即24V×50%=12V。另外,既然满足这个关系,那PWM波的频率是不是可以随意了,答案当然不是,频率太低会导致电机运转不畅,振动大,噪音大;频率太高会导致驱动器开关损耗较大,甚至有电机会啸叫而不转的情况。一般1k~30k的PWM频率较为普遍,几百Hz的也有,实际上还是根据电机功率在测试时确定合适的PWM频率范围为宜。
这里只是 介绍了 pwm 在电机中的应用,当然了我们这里所说的背光调节也是其中的一种应用,其原理都是一样的。
4、实际操作
4.1、设备树配置
&qupv3_se5_i2c {
› icn6202@2d{
› › compatible = "chipone,icn6202"; › › reg = <0x2d>;
› › reset-gpio = <&tlmm 90 0>;
› › bl-fault-gpio = <&tlmm 24 0>;
› };
};
4.2、驱动中实现
bl_fault_gpio = of_get_named_gpio(np, "bl-fault-gpio", 0);
if(!gpio_is_valid(bl_fault_gpio)) {dev_err(dev, "gpio is invalid");return -1;
}
bl_fault_irq = gpio_to_irq(bl_fault_gpio);
ret = request_threaded_irq(ts->irq, NULL, bl_check_fault_interrupt,IRQF_TRIGGER_FALLING | IRQF_ONESHOT | IRQF_NO_SUSPEND,client->dev.driver->name, ts);
if (ret < 0) {
› dev_err(dev," request irq failed");
› goto exit_failed;
}
static irqreturn_t bl_check_fault_interrupt(int irq, void *dev_id)
{disable_irq_nosync(irq);dev_err(dev, " TPS92380 bl Ic error ");return IRQ_HANDLED;
}
4.3、调整背光的最大值
考虑到延长背光IC 的使用寿命,将用户态的背光最大值调整为实际最大值的90%。
static int dsi_panel_update_pwm_backlight(struct dsi_panel *panel, u32 bl_lvl)
{
› bl = &panel->bl_config;
› if (!bl->pwm_bl) { › › pr_err("pwm device not found\n");
› › return -EINVAL;
› }
› period_ns = bl->pwm_period_usecs * NSEC_PER_USEC;
› duty = bl_lvl * period_ns;
› duty /= bl->bl_max_level;
› pr_err("[%s] pwm config, duty=%d, period_ns=%d %d\n",panel->name,duty,period_ns, bl_lvl);// 在调用 pwm_config 设置背光前 ,判断如果 bl_lvl / bl->bl_max_level = 1 将 duty = period_nx * 90%
› if((bl_lvl / bl->bl_max_level) == 1){
› › duty = 9 * period_ns / 10;
› }
› rc = pwm_config(bl->pwm_bl, duty, period_ns);
› if (rc) {
› › pr_err("[%s] failed to change pwm config, rc=\n", panel->name,
› › › rc);
› › goto error;
› }
}
这篇关于屏幕背光闪烁的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!