当前位置: 首页 > news >正文

网站模板与网站定制版的区别房地产怎么做网站推广

网站模板与网站定制版的区别,房地产怎么做网站推广,松岗网站的建设,大型网站建设的价格一、LVGL刷新显示#xff08;画点 OR 区域刷新颜色#xff09; 原来LCD的区域填充#xff0c;由于没用到DMA就是普通的遍历区域块的坐标#xff0c;需要传入的坐标就是显示区域的x轴起始与x轴尾部。y轴的起始与y轴的尾部。 怎么实现呢#xff1f; SPI不加DMA实现区域填充…一、LVGL刷新显示画点 OR 区域刷新颜色 原来LCD的区域填充由于没用到DMA就是普通的遍历区域块的坐标需要传入的坐标就是显示区域的x轴起始与x轴尾部。y轴的起始与y轴的尾部。 怎么实现呢 SPI不加DMA实现区域填充 首先确定要填充的y轴地址 确定y轴 然后在x轴起始位置向spi接口里连续写字节这时候不用去变寄存器的地址因为它会自增的。x轴的一行写完了再写y的下一个像素行。 /******************************************************************************函数说明在指定区域填充颜色入口数据xsta,ysta 起始坐标xend,yend 终止坐标color 要填充的颜色返回值 无 ******************************************************************************/ void LCD_Fill(u16 xsta,u16 ysta,u16 xend,u16 yend,u16 color) { u16 i,j; LCD_Address_Set(xstaOFFSET_X,ystaOFFSET_Y,xendOFFSET_X-1,yend-1OFFSET_Y);//设置显示范围for(iysta;iyend;i){ for(jxsta;jxend;j){LCD_WR_DATA(color);}} } |||||||||||||||||||||||||||||||||||||||||||||||||||| |||||||||||||||||||||||||||||||||||||||||||||||||||| 在LVGL里为了加快数据的传输启用SPI发送的DMA功能 SPI加DMA实现快速填充 /******************************************************************************函数说明在指定区域填充颜色入口数据xsta,ysta 起始坐标xend,yend 终止坐标color 要填充的颜色返回值 无 ******************************************************************************/ void LCD_Color_Fill(u16 xsta,u16 ysta,u16 xend,u16 yend,u16 *color_p) {u16 width,height; width xend-xsta1;height yend-ysta1;uint32_t size width * height;LCD_Address_Set(xsta,ystaOFFSET_Y,xend,yendOFFSET_Y);hspi1.Init.DataSize SPI_DATASIZE_16BIT;//切换成16位hspi1.Instance-CR1|SPI_CR1_DFF;//切换成16位HAL_SPI_Transmit_DMA(hspi1,(uint8_t*)color_p,size);//启动DMA传输while(__HAL_DMA_GET_COUNTER(hdma_spi1_tx)!0);//没传输完毕就不退出whilehspi1.Init.DataSize SPI_DATASIZE_8BIT;//切换回8位模式hspi1.Instance-CR1~SPI_CR1_DFF;//切换回8位模式} 为什么宽或高是end-sta1   数数 1~3有几个数就知道了 1 2 3 3-1  至于为什么采用半字的形式传输 也就是16位 我记得正点原子的LCD驱动芯片好像也是ST7789  这里涉及一个像素565 红绿蓝的问题 刚好组合为16位  然后就是开启SPI DMA传输的函数 HAL_SPI_Transmit_DMA(hspi1,(uint8_t*)color_p,size); 通过 SPI 使用 DMA 方式传输颜色数据到 LCD。这里将指向颜色数据的指针color_p转换为uint8_t*类型因为 DMA 通常以字节为单位传输数据。参数size指定了要传输的字节数 这是AI的解释我认为不完全正确 在SPI的驱动里我们设置了DMA是半字传输方式。但是这里强转成8位是让我摸不到头脑的。地址先不管它了我理解的是8位指针自增 它就加1个字节16位自增加2个字节。看来它们并不是完全相关可能用了什么手法吧。反正传入的是起始地址在32位中指针大小就为4个字节。强转成8位还是4个字节。  LVGL原文件里的填充函数 /*Flush the content of the internal buffer the specific area on the display*You can use DMA or any hardware acceleration to do this operation in the background but*lv_disp_flush_ready() has to be called when finished.*/ static void disp_flush(lv_disp_drv_t * disp_drv, const lv_area_t * area, lv_color_t * color_p) {/*The most simple case (but also the slowest) to put all pixels to the screen one-by-one*/int32_t x;int32_t y;for(y area-y1; y area-y2; y) {for(x area-x1; x area-x2; x) {/*Put a pixel to the display. For example:*//*put_px(x, y, *color_p)*/color_p;}}/*IMPORTANT!!!*Inform the graphics library that you are ready with the flushing*/lv_disp_flush_ready(disp_drv); } 我们可以看到 LVGL的移植   这就是需要1个画点函数 在某个像素16位 进行上色发送2个字节数据 画点函数的实现 /******************************************************************************函数说明在指定位置画点入口数据x,y 画点坐标color 点的颜色返回值 无 ******************************************************************************/ void LCD_DrawPoint(u16 x,u16 y,u16 color) {LCD_Address_Set(x,y,x,y);//设置光标位置 LCD_WR_DATA(color); } 但是这样就慢了啊 如果我们是对区域操作可以节省很多时间。画点得不停的换寄存器地址 而这种设置一个区域再向里面填充会大大提高刷新的速率。 于是我们在LVGL的绑定函数disp移植的时候需要把template注释掉里要这么改 //开启DMA以加速数据传输 static void disp_flush(lv_disp_drv_t * disp_drv, const lv_area_t * area, lv_color_t * color_p) {/*The most simple case (but also the slowest) to put all pixels to the screen one-by-one*/LCD_Color_Fill(area-x1,area-y1,area-x2,area-y2,(u16*)color_p);/*IMPORTANT!!!*Inform the graphics library that you are ready with the flushing*/lv_disp_flush_ready(disp_drv); } 二、LVGL的端口显示初始化 1 首先他告诉我们要初始化我们的显示器 当然我们是在LCD里进行初始化。这里就空着 2 接着创建一个内存空间用于画画 他给了很大一段注释  /**     * LVGL 需要一个缓冲区它在内部在此绘制小部件。     * 稍后这个缓冲区将传递给你的显示驱动程序的flush_cb以将其内容复制到你的显示器上。     * 缓冲区必须大于 1 个显示行。 * 有三种缓冲配置     * 1. 创建一个缓冲区     *      LVGL 将在此绘制显示器的内容并将其写入你的显示器。     *     * 2. 创建两个缓冲区     *      LVGL 将显示器的内容绘制到一个缓冲区并写入你的显示器。     *      你应该使用 DMA 将缓冲区的内容写入显示器。     *      这将使 LVGL 在从第一个缓冲区发送数据时能够将屏幕的下一部分绘制到另一个缓冲区。这使得渲染和刷新并行进行。     *     * 3. 双缓冲     *      设置两个屏幕大小的缓冲区并设置 disp_drv.full_refresh 1。     *      这样LVGL 将始终在flush_cb中提供整个渲染后的屏幕     *      而你只需要更改帧缓冲区的地址。     */ void lv_port_disp_init(void) {/*-------------------------* Initialize your display* -----------------------*/disp_init();/*-----------------------------* Create a buffer for drawing*----------------------------*//*** LVGL requires a buffer where it internally draws the widgets.* Later this buffer will passed to your display drivers flush_cb to copy its content to your display.* The buffer has to be greater than 1 display row** There are 3 buffering configurations:* 1. Create ONE buffer:* LVGL will draw the displays content here and writes it to your display** 2. Create TWO buffer:* LVGL will draw the displays content to a buffer and writes it your display.* You should use DMA to write the buffers content to the display.* It will enable LVGL to draw the next part of the screen to the other buffer while* the data is being sent form the first buffer. It makes rendering and flushing parallel.** 3. Double buffering* Set 2 screens sized buffers and set disp_drv.full_refresh 1.* This way LVGL will always provide the whole rendered screen in flush_cb* and you only need to change the frame buffers address.*//* Example for 1) */static lv_disp_draw_buf_t draw_buf_dsc_1;static lv_color_t buf_1[MY_DISP_HOR_RES * 10]; /*A buffer for 10 rows*/lv_disp_draw_buf_init(draw_buf_dsc_1, buf_1, NULL, MY_DISP_HOR_RES * 10); /*Initialize the display buffer*//* Example for 2) */static lv_disp_draw_buf_t draw_buf_dsc_2;static lv_color_t buf_2_1[MY_DISP_HOR_RES * 10]; /*A buffer for 10 rows*/static lv_color_t buf_2_2[MY_DISP_HOR_RES * 10]; /*An other buffer for 10 rows*/lv_disp_draw_buf_init(draw_buf_dsc_2, buf_2_1, buf_2_2, MY_DISP_HOR_RES * 10); /*Initialize the display buffer*//* Example for 3) also set disp_drv.full_refresh 1 below*/static lv_disp_draw_buf_t draw_buf_dsc_3;static lv_color_t buf_3_1[MY_DISP_HOR_RES * MY_DISP_VER_RES]; /*A screen sized buffer*/static lv_color_t buf_3_2[MY_DISP_HOR_RES * MY_DISP_VER_RES]; /*Another screen sized buffer*/lv_disp_draw_buf_init(draw_buf_dsc_3, buf_3_1, buf_3_2, MY_DISP_VER_RES * LV_VER_RES_MAX); /*Initialize the display buffer*//*-----------------------------------* Register the display in LVGL*----------------------------------*/static lv_disp_drv_t disp_drv; /*Descriptor of a display driver*/lv_disp_drv_init(disp_drv); /*Basic initialization*//*Set up the functions to access to your display*//*Set the resolution of the display*/disp_drv.hor_res 480;disp_drv.ver_res 320;/*Used to copy the buffers content to the display*/disp_drv.flush_cb disp_flush;/*Set a display buffer*/disp_drv.draw_buf draw_buf_dsc_1;/*Required for Example 3)*///disp_drv.full_refresh 1/* Fill a memory array with a color if you have GPU.* Note that, in lv_conf.h you can enable GPUs that has built-in support in LVGL.* But if you have a different GPU you can use with this callback.*///disp_drv.gpu_fill_cb gpu_fill;/*Finally register the driver*/lv_disp_drv_register(disp_drv); } 这里他给出了三种模式我们采取第2种我觉得就是1个备胎1个正主俩人轮流当备胎。一个DMA还在搬运的时候另一个Buffer已经填充了。当这个搬运完就该搬运下一个了。 2.1 首先把他提供的实例初始化了 /*Used to copy the buffers content to the display*/disp_drv.flush_cb disp_flush; static lv_disp_drv_t disp_drv; /*Descriptor of a display driver*/lv_disp_drv_init(disp_drv); /*Basic initialization*/ 我们在配置IO属性的时候都是把成员全部初始化之后才回去初始化整个实例。这有些不太一样先初始化实例再逐个成员进行修改。 2.2 设置函数去获取你的显示器没太懂什么意思 2.3  设置显示器分辨率 disp_drv.hor_res LCD_W;disp_drv.ver_res LCD_H; 2.4 用于将缓冲区的内容复制到显示器 /*Used to copy the buffers content to the display*/disp_drv.flush_cb disp_flush; 2.5 设置一个显示缓冲区 这里利用宏进行条件编译 使用的是模式2  两个Buff缓冲区 每个大小为 整个屏幕的十分之一。当然最小不要小于一行像素的大小 #define BUFFER_METHOD 2 //他这里缓冲区大小是整个分辨率大小除10 #if BUFFER_METHOD 1/* Example for 1) */static lv_disp_draw_buf_t draw_buf_dsc_1;static lv_color_t buf_1[LCD_W * LCD_H / 10]; /*A buffer for 10 rows*/lv_disp_draw_buf_init(draw_buf_dsc_1, buf_1, NULL, LCD_W * LCD_H / 10); /*Initialize the display buffer*//*Set a display buffer*/disp_drv.draw_buf draw_buf_dsc_1; #elif BUFFER_METHOD 2/* Example for 2) */static lv_disp_draw_buf_t draw_buf_dsc_2;static lv_color_t buf_2_1[LCD_W * LCD_H / 10]; /*A buffer for 10 rows*/static lv_color_t buf_2_2[LCD_W * LCD_H / 10]; /*An other buffer for 10 rows*/lv_disp_draw_buf_init(draw_buf_dsc_2, buf_2_1, buf_2_2, LCD_W * LCD_H / 10); /*Initialize the display buffer*//*Set a display buffer*/disp_drv.draw_buf draw_buf_dsc_2; #elif BUFFER_METHOD 3/* Example for 3) also set disp_drv.full_refresh 1 below*/static lv_disp_draw_buf_t draw_buf_dsc_3;static lv_color_t buf_3_1[LCD_W * LCD_H]; /*A screen sized buffer*/static lv_color_t buf_3_2[LCD_W * LCD_H]; /*An other screen sized buffer*/lv_disp_draw_buf_init(draw_buf_dsc_3, buf_3_1, buf_3_2, LCD_W * LCD_H); /*Initialize the display buffer*//*Required for Example 3)*/disp_drv.full_refresh 1;/*Set a display buffer*/disp_drv.draw_buf draw_buf_dsc_3; #endif // 0 这里的两个静态定义不太懂啊我们去定义看看 2.5.1 lv_disp_draw_buf_t 这个是个结构体的别名   用于保存显示缓冲区信息的结构。 static lv_disp_draw_buf_t draw_buf_dsc_2;static lv_color_t buf_2_1[LCD_W * LCD_H / 10]; /*A buffer for 10 rows*/static lv_color_t buf_2_2[LCD_W * LCD_H / 10]; /*An other buffer for 10 rows*/lv_disp_draw_buf_init(draw_buf_dsc_2, buf_2_1, buf_2_2, LCD_W * LCD_H / 10); /*Initialize the display buffer*/ 最后通过初始化函数将这个实例初始化了参数一结构体地址参数二buff1参数三buff2参数4 估计是1个buff的像素个数 /*** Initialize a display buffer* param draw_buf pointer lv_disp_draw_buf_t variable to initialize* param buf1 A buffer to be used by LVGL to draw the image.* Always has to specified and cant be NULL.* Can be an array allocated by the user. E.g. static lv_color_t disp_buf1[1024 * 10]* Or a memory address e.g. in external SRAM* param buf2 Optionally specify a second buffer to make image rendering and image flushing* (sending to the display) parallel.* In the disp_drv-flush you should use DMA or similar hardware to send* the image to the display in the background.* It lets LVGL to render next frame into the other buffer while previous is being* sent. Set to NULL if unused.* param size_in_px_cnt size of the buf1 and buf2 in pixel count.*/ void lv_disp_draw_buf_init(lv_disp_draw_buf_t * draw_buf, void * buf1, void * buf2, uint32_t size_in_px_cnt) {lv_memset_00(draw_buf, sizeof(lv_disp_draw_buf_t));draw_buf-buf1 buf1;draw_buf-buf2 buf2;draw_buf-buf_act draw_buf-buf1;draw_buf-size size_in_px_cnt; }2.5.2 lv_color_t typedef LV_CONCAT3(lv_color, LV_COLOR_DEPTH, _t) lv_color_t; x ## y ## z这是宏的具体实现。在 C 和 C 中##是预处理器的连接运算符。它将前后的两个标记token连接成一个新的标记。这里的作用是将参数 x、y 和 z 连接在一起。 结果就是 将这三个参数 lv_colorLV_COLOR_DEPTH _t 我们找到 #define LV_COLOR_DEPTH 16 宏定义 于是就有 lv_color16 _t 然后我们找到这是个内联函数  #elif LV_COLOR_DEPTH 16return color.full; 这个名为lv_color_to16的函数是一个内联函数用于将输入的lv_color_t类型的颜色值转换为 16 位颜色值。 然后我们用这个lv_color_t定义的变量 如果是18等等都被转换成16位的。 当LV_COLOR_DEPTH为 16 时直接返回输入颜色的full成员因为输入颜色已经是 16 位深度无需进行转换。 2.6 如果你的芯片支持GPU的话 /* Fill a memory array with a color if you have GPU.* Note that, in lv_conf.h you can enable GPUs that has built-in support in LVGL.* But if you have a different GPU you can use with this callback.*///disp_drv.gpu_fill_cb gpu_fill; 2.7  最后注册这个驱动 /*Finally register the driver*/lv_disp_drv_register(disp_drv); 整个流程下来这个显示函数的内容就这么多按照注释也可以一步步操作下面给出整个C文件 lv_port_disp.c /*** file lv_port_disp_templ.c**///这段代码是用于将 LVGLLight and Versatile Graphics Library//图形库与特定的显示设备进行适配的初始化代码。它主要完成了显示设备的初始化、//为 LVGL 创建用于绘图的缓冲区、设置将缓冲区内容刷新到显示设备的函数//以及将显示驱动注册到 LVGL 等一系列操作 // 以便能够在该显示设备上正确地显示 LVGL 绘制的图形界面。 //把像素分辨率、画点函数和申请的内存大小填充就ok了/*Copy this file as lv_port_disp.c and set this value to 1 to enable content*/ #if 1/********************** INCLUDES*********************/ #include lv_port_disp.h #include lvgl.h#include lcd.h #include lcd_init.h/********************** DEFINES*********************//*********************** TYPEDEFS**********************//*********************** STATIC PROTOTYPES**********************/ static void disp_init(void);static void disp_flush(lv_disp_drv_t * disp_drv, const lv_area_t * area, lv_color_t * color_p); //static void gpu_fill(lv_disp_drv_t * disp_drv, lv_color_t * dest_buf, lv_coord_t dest_width, // const lv_area_t * fill_area, lv_color_t color);/*********************** STATIC VARIABLES**********************//*********************** MACROS**********************//*********************** GLOBAL FUNCTIONS**********************/void lv_port_disp_init(void) {/*-------------------------* Initialize your display* -----------------------*/// 这里进行你的屏幕初始化disp_init();/*-----------------------------* Create a buffer for drawing*----------------------------*//*** LVGL requires a buffer where it internally draws the widgets.* Later this buffer will passed to your display drivers flush_cb to copy its content to your display.* The buffer has to be greater than 1 display row** There are 3 buffering configurations:* 1. Create ONE buffer:* LVGL will draw the displays content here and writes it to your display** 2. Create TWO buffer:* LVGL will draw the displays content to a buffer and writes it your display.* You should use DMA to write the buffers content to the display.* It will enable LVGL to draw the next part of the screen to the other buffer while* the data is being sent form the first buffer. It makes rendering and flushing parallel.** 3. Double buffering* Set 2 screens sized buffers and set disp_drv.full_refresh 1.* This way LVGL will always provide the whole rendered screen in flush_cb* and you only need to change the frame buffers address.*/static lv_disp_drv_t disp_drv; /*Descriptor of a display driver*/lv_disp_drv_init(disp_drv); /*Basic initialization*//*Set up the functions to access to your display*//*Set the resolution of the display*/disp_drv.hor_res LCD_W;disp_drv.ver_res LCD_H;/*Used to copy the buffers content to the display*/// disp_flush的函数实现看下面disp_drv.flush_cb disp_flush;// 这里是LVGL画面渲染所使用的缓存空间分配总共有三种方式// 你也可以改为malloc分配空间 #define BUFFER_METHOD 2 //他这里缓冲区大小是整个分辨率大小除10 #if BUFFER_METHOD 1/* Example for 1) */static lv_disp_draw_buf_t draw_buf_dsc_1;static lv_color_t buf_1[LCD_W * LCD_H / 10]; /*A buffer for 10 rows*/lv_disp_draw_buf_init(draw_buf_dsc_1, buf_1, NULL, LCD_W * LCD_H / 10); /*Initialize the display buffer*//*Set a display buffer*/disp_drv.draw_buf draw_buf_dsc_1; #elif BUFFER_METHOD 2/* Example for 2) */static lv_disp_draw_buf_t draw_buf_dsc_2;static lv_color_t buf_2_1[LCD_W * LCD_H / 10]; /*A buffer for 10 rows*/static lv_color_t buf_2_2[LCD_W * LCD_H / 10]; /*An other buffer for 10 rows*/lv_disp_draw_buf_init(draw_buf_dsc_2, buf_2_1, buf_2_2, LCD_W * LCD_H / 10); /*Initialize the display buffer*//*Set a display buffer*/disp_drv.draw_buf draw_buf_dsc_2; #elif BUFFER_METHOD 3/* Example for 3) also set disp_drv.full_refresh 1 below*/static lv_disp_draw_buf_t draw_buf_dsc_3;static lv_color_t buf_3_1[LCD_W * LCD_H]; /*A screen sized buffer*/static lv_color_t buf_3_2[LCD_W * LCD_H]; /*An other screen sized buffer*/lv_disp_draw_buf_init(draw_buf_dsc_3, buf_3_1, buf_3_2, LCD_W * LCD_H); /*Initialize the display buffer*//*Required for Example 3)*/disp_drv.full_refresh 1;/*Set a display buffer*/disp_drv.draw_buf draw_buf_dsc_3; #endif // 0/*-----------------------------------* Register the display in LVGL*----------------------------------*//* Fill a memory array with a color if you have GPU.* Note that, in lv_conf.h you can enable GPUs that has built-in support in LVGL.* But if you have a different GPU you can use with this callback.*///disp_drv.gpu_fill_cb gpu_fill;/*Finally register the driver*/lv_disp_drv_register(disp_drv); }/*********************** STATIC FUNCTIONS**********************//*Initialize your display and the required peripherals.*/ static void disp_init(void) {/*You code here*/ }/*Flush the content of the internal buffer the specific area on the display*You can use DMA or any hardware acceleration to do this operation in the background but*lv_disp_flush_ready() has to be called when finished.*/ //开启DMA以加速数据传输 static void disp_flush(lv_disp_drv_t * disp_drv, const lv_area_t * area, lv_color_t * color_p) {/*The most simple case (but also the slowest) to put all pixels to the screen one-by-one*/LCD_Color_Fill(area-x1,area-y1,area-x2,area-y2,(u16*)color_p);/*IMPORTANT!!!*Inform the graphics library that you are ready with the flushing*/lv_disp_flush_ready(disp_drv); }/*OPTIONAL: GPU INTERFACE*//*If your MCU has hardware accelerator (GPU) then you can use it to fill a memory with a color*/ //static void gpu_fill(lv_disp_drv_t * disp_drv, lv_color_t * dest_buf, lv_coord_t dest_width, // const lv_area_t * fill_area, lv_color_t color) //{ // /*Its an example code which should be done by your GPU*/ // int32_t x, y; // dest_buf dest_width * fill_area-y1; /*Go to the first line*/ // // for(y fill_area-y1; y fill_area-y2; y) { // for(x fill_area-x1; x fill_area-x2; x) { // dest_buf[x] color; // } // dest_bufdest_width; /*Go to the next line*/ // } //}#else /*Enable this file at the top*//*This dummy typedef exists purely to silence -Wpedantic.*/ typedef int keep_pedantic_happy; #endif三、图形库与触摸输入设备这里具体是 CST816 触摸屏进行适配 源文件  /*** file lv_port_indev_templ.c**//*Copy this file as lv_port_indev.c and set this value to 1 to enable content*/ #if 0/********************** INCLUDES*********************/ #include lv_port_indev_template.h #include ../../lvgl.h/********************** DEFINES*********************//*********************** TYPEDEFS**********************//*********************** STATIC PROTOTYPES**********************/static void touchpad_init(void); static void touchpad_read(lv_indev_drv_t * indev_drv, lv_indev_data_t * data); static bool touchpad_is_pressed(void); static void touchpad_get_xy(lv_coord_t * x, lv_coord_t * y);static void mouse_init(void); static void mouse_read(lv_indev_drv_t * indev_drv, lv_indev_data_t * data); static bool mouse_is_pressed(void); static void mouse_get_xy(lv_coord_t * x, lv_coord_t * y);static void keypad_init(void); static void keypad_read(lv_indev_drv_t * indev_drv, lv_indev_data_t * data); static uint32_t keypad_get_key(void);static void encoder_init(void); static void encoder_read(lv_indev_drv_t * indev_drv, lv_indev_data_t * data); static void encoder_handler(void);static void button_init(void); static void button_read(lv_indev_drv_t * indev_drv, lv_indev_data_t * data); static int8_t button_get_pressed_id(void); static bool button_is_pressed(uint8_t id);/*********************** STATIC VARIABLES**********************/ lv_indev_t * indev_touchpad; lv_indev_t * indev_mouse; lv_indev_t * indev_keypad; lv_indev_t * indev_encoder; lv_indev_t * indev_button;static int32_t encoder_diff; static lv_indev_state_t encoder_state;/*********************** MACROS**********************//*********************** GLOBAL FUNCTIONS**********************/void lv_port_indev_init(void) {/*** Here you will find example implementation of input devices supported by LittelvGL:* - Touchpad* - Mouse (with cursor support)* - Keypad (supports GUI usage only with key)* - Encoder (supports GUI usage only with: left, right, push)* - Button (external buttons to press points on the screen)** The ..._read() function are only examples.* You should shape them according to your hardware*/static lv_indev_drv_t indev_drv;/*------------------* Touchpad* -----------------*//*Initialize your touchpad if you have*/touchpad_init();/*Register a touchpad input device*/lv_indev_drv_init(indev_drv);indev_drv.type LV_INDEV_TYPE_POINTER;indev_drv.read_cb touchpad_read;indev_touchpad lv_indev_drv_register(indev_drv);/*------------------* Mouse* -----------------*//*Initialize your mouse if you have*/mouse_init();/*Register a mouse input device*/lv_indev_drv_init(indev_drv);indev_drv.type LV_INDEV_TYPE_POINTER;indev_drv.read_cb mouse_read;indev_mouse lv_indev_drv_register(indev_drv);/*Set cursor. For simplicity set a HOME symbol now.*/lv_obj_t * mouse_cursor lv_img_create(lv_scr_act());lv_img_set_src(mouse_cursor, LV_SYMBOL_HOME);lv_indev_set_cursor(indev_mouse, mouse_cursor);/*------------------* Keypad* -----------------*//*Initialize your keypad or keyboard if you have*/keypad_init();/*Register a keypad input device*/lv_indev_drv_init(indev_drv);indev_drv.type LV_INDEV_TYPE_KEYPAD;indev_drv.read_cb keypad_read;indev_keypad lv_indev_drv_register(indev_drv);/*Later you should create group(s) with lv_group_t * group lv_group_create(),*add objects to the group with lv_group_add_obj(group, obj)*and assign this input device to group to navigate in it:*lv_indev_set_group(indev_keypad, group);*//*------------------* Encoder* -----------------*//*Initialize your encoder if you have*/encoder_init();/*Register a encoder input device*/lv_indev_drv_init(indev_drv);indev_drv.type LV_INDEV_TYPE_ENCODER;indev_drv.read_cb encoder_read;indev_encoder lv_indev_drv_register(indev_drv);/*Later you should create group(s) with lv_group_t * group lv_group_create(),*add objects to the group with lv_group_add_obj(group, obj)*and assign this input device to group to navigate in it:*lv_indev_set_group(indev_encoder, group);*//*------------------* Button* -----------------*//*Initialize your button if you have*/button_init();/*Register a button input device*/lv_indev_drv_init(indev_drv);indev_drv.type LV_INDEV_TYPE_BUTTON;indev_drv.read_cb button_read;indev_button lv_indev_drv_register(indev_drv);/*Assign buttons to points on the screen*/static const lv_point_t btn_points[2] {{10, 10}, /*Button 0 - x:10; y:10*/{40, 100}, /*Button 1 - x:40; y:100*/};lv_indev_set_button_points(indev_button, btn_points); }/*********************** STATIC FUNCTIONS**********************//*------------------* Touchpad* -----------------*//*Initialize your touchpad*/ static void touchpad_init(void) {/*Your code comes here*/ }/*Will be called by the library to read the touchpad*/ static void touchpad_read(lv_indev_drv_t * indev_drv, lv_indev_data_t * data) {static lv_coord_t last_x 0;static lv_coord_t last_y 0;/*Save the pressed coordinates and the state*/if(touchpad_is_pressed()) {touchpad_get_xy(last_x, last_y);data-state LV_INDEV_STATE_PR;} else {data-state LV_INDEV_STATE_REL;}/*Set the last pressed coordinates*/data-point.x last_x;data-point.y last_y; }/*Return true is the touchpad is pressed*/ static bool touchpad_is_pressed(void) {/*Your code comes here*/return false; }/*Get the x and y coordinates if the touchpad is pressed*/ static void touchpad_get_xy(lv_coord_t * x, lv_coord_t * y) {/*Your code comes here*/(*x) 0;(*y) 0; }/*------------------* Mouse* -----------------*//*Initialize your mouse*/ static void mouse_init(void) {/*Your code comes here*/ }/*Will be called by the library to read the mouse*/ static void mouse_read(lv_indev_drv_t * indev_drv, lv_indev_data_t * data) {/*Get the current x and y coordinates*/mouse_get_xy(data-point.x, data-point.y);/*Get whether the mouse button is pressed or released*/if(mouse_is_pressed()) {data-state LV_INDEV_STATE_PR;} else {data-state LV_INDEV_STATE_REL;} }/*Return true is the mouse button is pressed*/ static bool mouse_is_pressed(void) {/*Your code comes here*/return false; }/*Get the x and y coordinates if the mouse is pressed*/ static void mouse_get_xy(lv_coord_t * x, lv_coord_t * y) {/*Your code comes here*/(*x) 0;(*y) 0; }/*------------------* Keypad* -----------------*//*Initialize your keypad*/ static void keypad_init(void) {/*Your code comes here*/ }/*Will be called by the library to read the mouse*/ static void keypad_read(lv_indev_drv_t * indev_drv, lv_indev_data_t * data) {static uint32_t last_key 0;/*Get the current x and y coordinates*/mouse_get_xy(data-point.x, data-point.y);/*Get whether the a key is pressed and save the pressed key*/uint32_t act_key keypad_get_key();if(act_key ! 0) {data-state LV_INDEV_STATE_PR;/*Translate the keys to LVGL control characters according to your key definitions*/switch(act_key) {case 1:act_key LV_KEY_NEXT;break;case 2:act_key LV_KEY_PREV;break;case 3:act_key LV_KEY_LEFT;break;case 4:act_key LV_KEY_RIGHT;break;case 5:act_key LV_KEY_ENTER;break;}last_key act_key;} else {data-state LV_INDEV_STATE_REL;}data-key last_key; }/*Get the currently being pressed key. 0 if no key is pressed*/ static uint32_t keypad_get_key(void) {/*Your code comes here*/return 0; }/*------------------* Encoder* -----------------*//*Initialize your keypad*/ static void encoder_init(void) {/*Your code comes here*/ }/*Will be called by the library to read the encoder*/ static void encoder_read(lv_indev_drv_t * indev_drv, lv_indev_data_t * data) {data-enc_diff encoder_diff;data-state encoder_state; }/*Call this function in an interrupt to process encoder events (turn, press)*/ static void encoder_handler(void) {/*Your code comes here*/encoder_diff 0;encoder_state LV_INDEV_STATE_REL; }/*------------------* Button* -----------------*//*Initialize your buttons*/ static void button_init(void) {/*Your code comes here*/ }/*Will be called by the library to read the button*/ static void button_read(lv_indev_drv_t * indev_drv, lv_indev_data_t * data) {static uint8_t last_btn 0;/*Get the pressed buttons ID*/int8_t btn_act button_get_pressed_id();if(btn_act 0) {data-state LV_INDEV_STATE_PR;last_btn btn_act;} else {data-state LV_INDEV_STATE_REL;}/*Save the last pressed buttons ID*/data-btn_id last_btn; }/*Get ID (0, 1, 2 ..) of the pressed button*/ static int8_t button_get_pressed_id(void) {uint8_t i;/*Check to buttons see which is being pressed (assume there are 2 buttons)*/for(i 0; i 2; i) {/*Return the pressed buttons ID*/if(button_is_pressed(i)) {return i;}}/*No button pressed*/return -1; }/*Test if id button is pressed or not*/ static bool button_is_pressed(uint8_t id) {/*Your code comes here*/return false; }#else /*Enable this file at the top*//*This dummy typedef exists purely to silence -Wpedantic.*/ typedef int keep_pedantic_happy; #endif3.1 lv_port_indev_init函数 /**  * 在此处您将找到 LittlevGL 支持的输入设备的示例实现  *  - 触摸板  *  - 鼠标支持光标  *  - 小键盘仅使用按键支持 GUI 使用  *  - 编码器仅支持以下操作来使用 GUI左、右、按下  *  - 按钮用于在屏幕上按下点的外部按钮  *  * ..._read()函数仅为示例。  * 您应根据您的硬件对其进行调整。  */ 我们只用到了触摸IC的功能 也就是触摸板 只需要这部分就可以 其他的都可以条件编译或者注释或者删除掉 void lv_port_indev_init(void) {/*** Here you will find example implementation of input devices supported by LittelvGL:* - Touchpad* - Mouse (with cursor support)* - Keypad (supports GUI usage only with key)* - Encoder (supports GUI usage only with: left, right, push)* - Button (external buttons to press points on the screen)** The ..._read() function are only examples.* You should shape them according to your hardware*/static lv_indev_drv_t indev_drv;/*------------------* Touchpad* -----------------*//*Initialize your touchpad if you have*/touchpad_init();/*Register a touchpad input device*/lv_indev_drv_init(indev_drv);indev_drv.type LV_INDEV_TYPE_POINTER;indev_drv.read_cb touchpad_read;indev_touchpad lv_indev_drv_register(indev_drv);} 初始化的操作依然实在驱动那块就做了。  /*Initialize your touchpad*/ static void touchpad_init(void) {/*Your code comes here*/ } 然后就是注册一个触摸板输入设备注册设备可让我想起来学linux驱动开发那会了 LVGL帮我们实现了这个读取回调函数 /*Will be called by the library to read the touchpad*/ static void touchpad_read(lv_indev_drv_t * indev_drv, lv_indev_data_t * data) {static lv_coord_t last_x 0;static lv_coord_t last_y 0;/*Save the pressed coordinates and the state*/if(touchpad_is_pressed()) {touchpad_get_xy(last_x, last_y);data-state LV_INDEV_STATE_PR;} else {data-state LV_INDEV_STATE_REL;}/*Set the last pressed coordinates*/data-point.x last_x;data-point.y last_y; } 3.2 我么需要实现的另外两个函数 /*Return true is the touchpad is pressed*/ static bool touchpad_is_pressed(void) {/*Your code comes here*/return false; }/*Get the x and y coordinates if the touchpad is pressed*/ static void touchpad_get_xy(lv_coord_t * x, lv_coord_t * y) {/*Your code comes here*/(*x) 0;(*y) 0; }返回触摸状态是否按压 和 坐标位置 我们在驱动中定义了一个位置结构体并实例化了其中保存的就是x和y的坐标 3.2.1 touchpad_is_pressed /*Return true is the touchpad is pressed*/ static bool touchpad_is_pressed(void) {//通过调用CST816_Get_FingerNum函数获取 CST816 触摸屏上当前触摸的手指个数信息/*Your code comes here*///如果获取到的手指个数既不是 0x00可能表示没有触摸//也不是 0xFF可能表示触摸屏处于睡眠状态等特殊情况//则返回true表示触摸设备被按下if(CST816_Get_FingerNum()!0x00 CST816_Get_FingerNum()!0xFF){return true;}else{return false;} }3.2.2 touchpad_get_xy /*Get the x and y coordinates if the touchpad is pressed*/ static void touchpad_get_xy(lv_coord_t * x, lv_coord_t * y) {/*Your code comes here*/ //这个函数用于获取触摸设备被按下时触摸点的坐标值CST816_Get_XY_AXIS();(*x) CST816_Instance.X_Pos;(*y) CST816_Instance.Y_Pos; }到这关于触摸输入设备就完了。 当然8.2版本的LVGL还有一个文件 是跟文件系统有关的。 由于暂时没有使用到就不做过多的了解。 四、lvgl的裁剪文件lv_conf.h 这个文件从哪找呢就在你下载的源代码的根目录 打开文件会出现  /*  * 将此文件复制为lv_conf.h  * 1. 紧邻lvgl文件夹  * 2. 或者其他任何位置并  *    - 定义LV_CONF_INCLUDE_SIMPLE  *    - 将路径添加为包含路径  */ 其中的内容就是对lvgl的功能进行裁剪比如什么滑块支不支持gifpng各种东西。我想先用lvgl做个鸡哥的gif出来哈哈 大致手表的配置如下 //做一些LVGL的配置裁剪的功能 //改了字体改了刷新频率10ms改了小组件的开关额外组件主题 支持更多字体大小 修改了刷新率原来是30ms一刷现在是10ms 毕竟开了DMA必须加快刷新 取消了一些没用到的小组件 不使用基础主题和单色主题。 下一篇文章我打算先移植玩玩然后对lvgl8.2的各种c文件具体干什么打个标签方便以后裁剪。 五、移植LVGL全过程 5.1 github或镜像或压缩包下载并解压得到源代码 https://github.com/lvgl/lvgl/tree/release/v8.2 版本选择在这release 5.2 得到源代码 5.3 保留如下文件及文件夹或者不对文件做任何操作毕竟我们只是后期可以裁剪只对需要的文件编译 再次进入examples文件夹内 只保留这个接口文件夹 porting 当然examples里面是丰富的例程以后需要还是可以看看的 把内部文件全部剪切走在根目录下新建lvgl_porting文件夹 并将裁剪头文件改名 src里面包含的就是一些组件等功能的实现当然也可以头文件与c文件分离但是也可以不做。 然后就是把接口文件改名并删除掉不需要的接口 这样一份可以加入LVGL工程的模板就以基本完工然后就是前面的裁剪添加绘制函数和缓冲模式与触摸的坐标与状态获取。
http://www.hkea.cn/news/14282867/

相关文章:

  • 网站开发 百度编辑器鹤壁网站推广公司
  • 天津建设合同怎么在网站录入html5国内网站
  • 网站整站下载器 全站克隆页面图片视频下载 仿站专用源码工具软件电子商务网站规划原则
  • win2008r2做网站服务器windows下搭建wordpress
  • 中国工厂网站官方网站软件开发net教程免费
  • 网站建设的一般流程是购销网站建设视频百度云
  • 石狮app网站开发企业网站如何进行seo
  • 做网站 注意自己怎么注册域名
  • 上海个人网站备案wordpress 自定义布局
  • 长长沙网站制作中文网页模板免费
  • 沈阳专业网站制作团队做游戏网站要通过什么审核
  • 重庆网站定制开发一凡招聘 建筑人才网
  • 玉树电子商务网站建设黄页网页的推广网站
  • 题库网站建设的绩效指标wordpress微信域名回调
  • 建筑网站的功能模块企业所得税交多少
  • 门户网站的分类建筑施工模板
  • 网站模板用什么打开福州网站建设方案优化
  • 申请网页空间的网站运城推广型网站开发
  • 企业网站推广有哪些方式中英双语营销型网站
  • 网站推广怎么做关键词活动手机网站开发
  • 聊城做网站中企动力做销售的经历
  • 网站开发合同怎么写网站上线模板
  • 网加做网站推广阿里巴巴网站域名注册
  • 百度如何验证网站惠州企业网站设计
  • 网站报价收费单网站排行榜
  • 中国建设银行龙卡网站带地板翻转的网站怎么做
  • 四平做网站营销型网站代理
  • 网站建设与维护 教学大纲郴州网络有限公司
  • 网站内容策划方案百度运营培训班
  • 公司网站建设宣传公司浙江国有建设用地出让网站