惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

The GitHub Blog
The GitHub Blog
有赞技术团队
有赞技术团队
Apple Machine Learning Research
Apple Machine Learning Research
V
V2EX
Engineering at Meta
Engineering at Meta
美团技术团队
H
Hackread – Cybersecurity News, Data Breaches, AI and More
博客园 - 司徒正美
I
InfoQ
S
SegmentFault 最新的问题
博客园 - 叶小钗
N
Netflix TechBlog - Medium
Y
Y Combinator Blog
IT之家
IT之家
博客园 - Franky
大猫的无限游戏
大猫的无限游戏
人人都是产品经理
人人都是产品经理
T
The Blog of Author Tim Ferriss
月光博客
月光博客
The Cloudflare Blog
U
Unit 42
GbyAI
GbyAI
L
LangChain Blog
Microsoft Azure Blog
Microsoft Azure Blog

嵌入式开发

求推荐支持 eBPF 的国产 ARM 开发板 求个长期合作的逆向开发 ******野火开发板 stm32 教程错误很多***** 嵌入式开发能不能借助 AI 编写程序 有没有类似 ESP32 的芯片,内存要大的? 有干嵌入式的老哥吗? stm32+jlink,使用 swd 调试时经常蓝屏是怎么回事 有干嵌入式的老哥吗,有一个 keil 的问题 =RS485 总线冲突 Gemini 和 Chatgpt 给出不同的答案=== 嵌入式软件工程师如何提升自己? ST-Link 在 CLion 下载失败求助 个人认为嵌入式领域最无用的发明---色环电阻 v 嵌入式设备适合用 vlc 吗 有玩 mcuboot 的吗,可否帮忙看看我的应用为啥启动不了。 解析 pads pt9 格式文件,大家有没有什么好办法解析,可以有偿 请教嵌入式自学路径 嵌入式 AI 系统 SDK 从开发一个六足机器人入手,要怎么做 请教实现 嵌入式二维码扫描的问题, 新手, 非常新 0 基础嵌入式开发学习 嵌入式软件(单片机)相关问题 ESP32C6 系列教学视频,每天增加,大概 20 集,如果有用的可以下载 嵌入式入职没人带 ,如何提升自己的开发工作经验呢?提升能力?有没有教程推荐 想给和家亲摄像头刷 OpenIPC,求助 u-boot 相关问题 嵌入式软硬件交流贴 嵌入式设备(无任何界面,带喇叭)的语音通话技术选型 需要开发吸顶灯和可视化门铃,有人接单么 业余想学习和玩一下单片机,求助一下 最近的想法<打造下一代的嵌入式软件开发 IDE> 想将投影仪接入米家,请教一下 ESP32 重放投影仪蓝牙遥控器的按键,用于控制投影仪的开关 想学嵌入式,黑马的嵌入式培训怎么样?
过年时候写的,劣质古早 mcu 的 TFT 屏幕 +ILI9341 亮度控制方案
zxkmm · 2024-04-16 · via 嵌入式开发

前言

亮度控制一般有两种方案,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