过年时候写的,劣质古早 mcu 的 TFT 屏幕 +ILI9341 亮度控制方案

219 天前
 zxkmm

前言

亮度控制一般有两种方案,DC 调光和 PWM 调光。

但是某些奇怪的单片机设计直接把 TFT 屏的背光灯绑定在电源上,所以你只能开关背光,不能控制电压;所以只能被迫使用 PWM 调光。

然而对于单片机/RTOS 来说,每个 tick 都花一部分性能在控制方面可能有比较大的性能损耗,加上如果设备是无线电相关的话,PWM 带来的噪音可能会辐射到无线电部分导致未知的结果,所以只能采取第三种方案:伪颜色。

伪颜色

本质上 ILI9341 IC 的驱动当中是一个像素点一个像素点地画图

void lcd_write_pixel(ui::Color pixel) {
        lcd_write_data(pixel.v);
    }

这就相当简单了,直接把颜色通过浮点运算化为更“黑”的颜色即可实现“伪”亮度控制

void darken_color(ui::Color& pixel, float darken_level) {
    uint16_t r = (pixel.v >> 11) & 0x1F;
    uint16_t g = (pixel.v >> 5) & 0x3F;
    uint16_t b = pixel.v & 0x1F;

    r = static_cast<uint16_t>(r / darken_level);  // darken
    g = static_cast<uint16_t>(g / darken_level);
    b = static_cast<uint16_t>(b / darken_level);

    pixel.v = (r << 11) | (g << 5) | b;  // combine back
}

但是浮点运算在单片机上相当慢,最后出来而结果可以用,但是渲染速度肉眼可见的下降。最后我的方案是损失一些调控精度,用移位运算代替浮点运算

void darken_color(ui::Color& pixel, uint8_t darken_level_shift) {
        // TODO: 1. do we need edge control?
        // currently didn't see and issue without edge control
        // but maybe hurts screen hardware without one?

        // TODO: 2. de-color mode for accessibility
        // TODO: 3. high contrast mode for accessibility

        uint16_t r = (pixel.v >> 11) & 0x1F;  // extract
        uint16_t g = (pixel.v >> 5) & 0x3F;
        uint16_t b = pixel.v & 0x1F;

        r = r >> darken_level_shift;
        g = g >> darken_level_shift;
        b = b >> darken_level_shift;

        pixel.v = (r << 11) | (g << 5) | b;
    }
其中 darken_level_shift 是一个 uint8,0 代表 100%亮度,1 代表 50%亮度,以此类推

最后出来的结果终于可以用了:

void lcd_write_pixels(ui::Color pixel, size_t n) {
        if (get_dark_cover()) {
            darken_color(pixel, get_brightness());  // Darken
        }
void lcd_write_pixels_unrolled8(ui::Color pixel, size_t n) {
        if (get_dark_cover()) {
            darken_color(pixel, get_brightness());  // Darken 
        }

最后欢迎关注我的 github

https://github.com/zxkmm

952 次点击
所在节点   嵌入式开发
1 条回复
cd605426287
206 天前
6666 关注一 bo

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/1032958

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX