给TM30供电

static void enable_power(void)
{
    GPIO_InitTypeDef output = {0};

    PeripheralEnable(PeripheralGPIOH, true);
    output.GPIO_Pin = GPIO_Pin_15;
    output.GPIO_Speed = GPIO_Speed_25MHz;
    output.GPIO_Mode = GPIO_Mode_OUT;
    output.GPIO_OType = GPIO_OType_PP;
    output.GPIO_PuPd = GPIO_PuPd_NOPULL;
    GPIO_Init(GPIOH, &output);
    GPIO_SetBits(GPIOH, GPIO_Pin_15);
}

初始化LTDC

参考:LTDC外设实现

其实就是分配一块内存当做显存,然后LTDC配置好之后会一直读这个显存然后一系列操作,比如ARGB8888裁成RGB666,输出到18根引脚上从而刷新屏幕。

lvgl初始化配置缓冲区

给两块内存地址给到lvgl

Buffer0:0x60000000
Buffer1:0x6004B000

每块显存大小:

240 × 320 × 4 = 307200字节 = 0x4B000
两块显存怎么交替工作

假设当前LTDC正在显示Buffer0:

LTDC:读取Buffer0,从屏幕顶部扫描到底部
LVGL:在Buffer1中绘制下一张完整画面

Buffer1绘制完成以后,LVGL调用:

display_flush()

里面执行:

LTDC_Layer1->CFBAR = published;
LTDC_ReloadConfig(LTDC_VBReload);

这里把LTDC下一帧要读取的地址设置为Buffer1。

但是不能立即切换,要等垂直消隐:

while ((LTDC->ISR & LTDC_ISR_RRIF) == 0U) {
}

垂直消隐到来后:

LTDC完成Buffer0这一帧
→ CFBAR切换到Buffer1
→ LTDC开始显示Buffer1
→ LVGL下一次可以改写Buffer0

配置DCMI

参考:001-z4-DCMI配置

取帧和截取


YUV数据转ARGB8888

略

96x96放大为240x240

略

LVGL绘制完成写入显存

略,lvgl内部直接做了,我们只需要给到地址lvgl就好了

切换LTDC的显存缓冲区地址

// 在lvgl驱动接口里面
// 在lvgl执行刷新操作时
TDC_Layer1->CFBAR = published;
LTDC_ReloadConfig(LTDC_VBReload);