# 屏驱回调函数 屏驱回调函数是上层驱动框架操作屏驱的唯一接口,接口里面会经常用到[寄存器的读写函数](lcdc-reg-read-write-func)去操作LCD, 屏驱回调函数主要包括如下函数(对于非必选的可以不实现,留空或赋值为NULL即可): |回调函数| 说明| |:---- | ---- | | [LCD_Init](lcd-cb-func-LCD-Init)| 【必选】,屏驱初始函数(包括复位,初始化程序等) | | [LCD_ReadID](lcd-cb-func-LCD-ReadID)| 【必选】,屏幕在位检测函数 | | [LCD_DisplayOn](lcd-cb-func-LCD-DisplayOn)| 【必选】,屏幕打开 | | [LCD_DisplayOff](lcd-cb-func-LCD-DisplayOff)| 【必选】,屏幕关闭 | | [LCD_SetRegion](lcd-cb-func-LCD-SetRegion)| 【必选】,设置屏幕接受数据时的区域(2A,2B 的区域)| | [LCD_WritePixel](lcd-cb-func-LCD-WritePixel)| 可选,写一个像素点到屏幕上| | [LCD_WriteMultiplePixels](lcd-cb-func-LCD-WriteMultiplePixels)| 【必选】,写批量像素点到屏幕上| | [LCD_ReadPixel](lcd-cb-func-LCD-ReadPixel)| 可选,读屏幕上的一个像素点数据,返回像素的RGB值| | [LCD_SetColorMode](lcd-cb-func-LCD-SetColorMode)| 可选,切换输出给屏幕的颜色格式| | [LCD_SetBrightness](lcd-cb-func-LCD-SetBrightness)| 可选,设置屏幕的亮度 | | [LCD_IdleModeOn](lcd-cb-func-LCD-IdleModeOn)| 可选,进入待机显示模式(低功耗模式) | | [LCD_IdleModeOff](lcd-cb-func-LCD-IdleModeOff)| 可选,退出待机显示模式(低功耗模式) | | [LCD_Rotate](lcd-cb-func-LCD-Rotate)| 可选,旋转屏幕一定角度 | | [LCD_TimeoutDbg](lcd-cb-func-LCD-TimeoutDbg)| 可选,批量送数超时后,屏幕自检 | | [LCD_TimeoutReset](lcd-cb-func-LCD-TimeoutReset)| 可选,批量送数超时后,屏幕复位 | | [LCD_ESDCheck](lcd-cb-func-LCD-ESDCheck) | 可选,屏幕定时ESD检测 | (lcdc-reg-read-write-func)= ## LCD控制器寄存器的读写接口 这些接口会自动根据LCD控制器根据`HAL_LCDC_Init`设置的接口类型、频率去跟屏幕通信: 1. 寄存器写函数`HAL_LCDC_WriteU8Reg`,`HAL_LCDC_WriteU16Reg`,`HAL_LCDC_WriteU32Reg` 2. 寄存器读函数`HAL_LCDC_ReadU8Reg`,`HAL_LCDC_ReadU16Reg`,`HAL_LCDC_ReadU32Reg` ```{note} 寄存器和数据的发送都是小端,例如某SPI屏幕写寄存器调用: uint8_t param[4] = {0xAA, 0xBB, 0xCC, 0xDD}; HAL_LCDC_WriteU32Reg(hlcdc, 0x78563412, ¶m, 4); 则在接口上传输的是按照0x12,0x34,0x56,0x78, 0xAA, 0xBB, 0xCC, 0xDD的字节顺序。 ``` (lcd-cb-func-LCD-Init)= ## LCD_Init 屏驱第一个调用的函数,初始化。 这里面主要是: 1. 调用`HAL_LCDC_Init`初始化LCD控制器,设定接口的类型、频率、数据格式等等。 2. 通过`BSP_LCD_Reset`接口复位屏幕,使用`LCD_DRIVER_DELAY_MS`来做延时。 3. 然后从厂家提供的屏幕初始化命令表里面,将命令用思澈的[寄存器写接口](lcdc-reg-read-write-func),送到屏幕上去。 下图是某个屏驱的截图: ```{figure} assets/LCD_Init_func.png :scale: 30 % ``` (lcd-cb-func-LCD-ReadID)= ## LCD_ReadID 屏幕在位检测函数,该函数返回的值,会跟屏驱注册时提供的LCD_ID去比较,如果相同,则屏驱框架认为该屏驱可用。 否则,就不会调用该屏驱。 这个就是[屏驱注册](lcd-driver-register)时提供的LCD_ID: ```c LCD_DRIVER_EXPORT2(nv3051f1, LCD_ID, &lcdc_int_cfg, &LCD_drv,2); ``` ```{note} 该函数可以直接返回注册的ID,适用于以下情况: 1. 只有1个屏幕,不需要兼容多个屏幕驱动的功能 2. 屏幕不支持读ID ``` (lcd-cb-func-LCD-DisplayOn)= ## LCD_DisplayOn 这个函数里面一般就是发送屏驱的Display on命令。命令格式参考屏驱IC的Datasheet。 (lcd-cb-func-LCD-DisplayOff)= ## LCD_DisplayOff 这个函数里面一般是发送屏驱的Display off命令。命令格式参考屏驱IC的Datasheet。 (lcd-cb-func-LCD-SetRegion)= ## LCD_SetRegion 这个函数是设置LCD控制器的输出区域,以及屏驱的接收区域。 1. 通过`HAL_LCDC_SetROIArea`设置LCD控制器的输出区域。 1. 发送屏驱的接收窗口命令,一般是2A,2B寄存器 一般情况下,这2个区域直接根据`SetRegion`传入的参数设置相同区域即可。如果是DPI, DSI video这种ramless屏幕,可以初始化设置1次,后面不需要重复设置。 [LCD控制器输出区域、屏驱接收区域、Framebuffer所在区域、3者的相对关系](lcd-lcdc-coordinates-relationship) (lcd-cb-func-LCD-WritePixel)= ## LCD_WritePixel 写1个像素点数据到屏幕上 (lcd-cb-func-LCD-WriteMultiplePixels)= ## LCD_WriteMultiplePixels 这个函数是设置Framebuffer的地址和所在区域,然后触发刷屏。 1. 通过`HAL_LCDC_LayerSetData`设置Framebuffer所在的地址以及坐标区域。 2. 通过`HAL_LCDC_SendLayerData2Reg_IT`先发送批量写数据的寄存器地址,然后发送RGB数据到屏幕。对于DPI、DSI video这种没有寄存器地址的,调用`HAL_LCDC_SendLayerData_IT`启动送RGB数据。 [LCD控制器输出区域、屏驱接收区域、Framebuffer所在区域、3者的相对关系](lcd-lcdc-coordinates-relationship) (lcd-cb-func-LCD-ReadPixel)= ## LCD_ReadPixel TODO. (lcd-cb-func-LCD-SetColorMode)= ## LCD_SetColorMode TODO. (lcd-cb-func-LCD-SetBrightness)= ## LCD_SetBrightness 设置屏幕的背光,一般有以下2种办法: 1. 直接修改屏幕的寄存器,来修改液晶的透明度。一般用在AMOLED屏幕上,大概是这样: ```c uint8_t bright = (uint8_t)((int)255 * br / 100); //百分比转换为0~255的值 LCD_WriteReg(hlcdc, 0x51, &bright, 1); //设置背光寄存器,一般是0x51 ``` 2. 修改背光设备“lcdlight”的亮度。这种一般是TFT屏幕才会用到,AMOLED屏幕则不需要。大概是这样: ```c rt_device_t device = rt_device_find("lcdlight"); //查找背光设备 if (device) { rt_err_t err = rt_device_open(device, RT_DEVICE_OFLAG_RDWR);//打开设备 uint8_t val = br; rt_device_write(device, 0, &val, 1); //设置背光值 rt_device_close(device); //关闭device(不会关闭背光) } ``` (lcd-cb-func-LCD-IdleModeOn)= ## LCD_IdleModeOn TODO. (lcd-cb-func-LCD-IdleModeOff)= ## LCD_IdleModeOff TODO. (lcd-cb-func-LCD-Rotate)= ## LCD_Rotate TODO. (lcd-cb-func-LCD-TimeoutDbg)= ## LCD_TimeoutDbg TODO. (lcd-cb-func-LCD-TimeoutReset)= ## LCD_TimeoutReset TODO. (lcd-cb-func-LCD-ESDCheck)= ## LCD_ESDCheck TODO.