设为首页 加入收藏

TOP

AIR32F103(十) 在无系统环境和FreeRTOS环境集成LVGL(四)
2023-07-23 13:28:48 】 浏览:90
Tags:AIR32F103 FreeRTOS LVGL
lv_area_t *area, lv_color_t *color_p) { ST7735_WriteAddrWindow(area->x1, area->y1, area->x2, area->y2, (uint16_t *)color_p); // Indicate you are ready with the flushing lv_disp_flush_ready(disp); }

对应的 ST7735_WriteAddrWindow() 函数实现, 因为来源是16bit, SPI接口是8bit, 每一次调用分别写入两次

void ST7735_WriteAddrWindow(uint16_t x1, uint16_t y1, uint16_t x2, uint16_t y2, uint16_t *data)
{
  uint32_t tmp, i;
  if (x1 > x2)
  {
    tmp = x1; x1 = x2; x2 = tmp;
  }
  if (y1 > y2)
  {
    tmp = y1; y1 = y2; y2 = tmp;
  }
  tmp = (x2 - x1 + 1) * (y2 - y1 + 1);
  ST7735_CS_LOW;
  ST7735_SetAddrWindow(x1, y1, x2, y2);
  while (SPI_I2S_GetFlagStatus(SPI1, SPI_I2S_FLAG_TXE) == RESET);
  for(i = 0; i < tmp; i ++) 
  {
    SPI_I2S_SendData(SPI1, (uint8_t)(*data >> 8));
    while(SPI_I2S_GetFlagStatus(SPI1, SPI_I2S_FLAG_BSY) == SET);
    SPI_I2S_SendData(SPI1, (uint8_t)(*data & 0xFF));
    while(SPI_I2S_GetFlagStatus(SPI1, SPI_I2S_FLAG_BSY) == SET);
    data++;
  }
  ST7735_CS_HIGH;
}

5. 创建图像缓冲, 初始化LVGL

最小为1/10个屏幕尺寸所需数据大小

static lv_disp_draw_buf_t draw_buf;
// Declare a buffer for 1/10 screen size
static lv_color_t buf1[ST7735_WIDTH * ST7735_HEIGHT / 10];
// Descriptor of a display driver
static lv_disp_drv_t disp_drv;

在 main() 中进行初始化, 注意这部分官网给代码里的类型不太对, 这部分的代码已经修改

lv_init();
// Initialize the display buffer.
lv_disp_draw_buf_init(&draw_buf, buf1, NULL, ST7735_WIDTH * ST7735_HEIGHT / 10);

lv_disp_drv_init(&disp_drv);                /*Basic initialization*/
disp_drv.flush_cb = my_disp_flush;          /*Set your driver function*/
disp_drv.draw_buf = &draw_buf;              /*Assign the buffer to the display*/
disp_drv.hor_res = ST7735_WIDTH;            /*Set the horizontal resolution of the display*/
disp_drv.ver_res = ST7735_HEIGHT;           /*Set the vertical resolution of the display*/
lv_disp_drv_register(&disp_drv);            /*Finally register the driver*/

6. 主循环添加 lv_timer_handler()

因为这个 ST7735 没有触屏功能, 所以输入读取函数就省了. 在 main() while(1)主循环中加上 lv_timer_handler()

  while (1)
  {
    lv_timer_handler();
    Delay_Ms(10);
  }

6. 执行示例

经过以上的设置, LVGL就已经集成到项目中了, 可以运行LVGL自带的一些例子查看控件的显示效果

文字标签, 居中和滚动的效果

lv_example_label_1();

按钮效果

lv_example_btn_1();

源代码

以上LVGL整合示例的完整源代码已经提交到 GitHub: https://github.com/IOsetting/air32f103-template/tree/master/Examples/NonFreeRTOS/SPI/ST7735_LVGL

修改为 DMA 输出

上面的例子是使用 SPI_I2S_SendData() 函数传输图像数据的, 可以修改为 DMA 传输, 因为传输方式的变化, 外设初始化和图像更新要做对应的调整, 这里没有使用中断.

1. 外设调整

GPIO 不变, 启用 SPI 的 DMA

APP_SPI_Config()中启用SPI1 DMA

  /* Enable SPI1 DMA TX request */
  SPI_I2S_DMACmd(SPI1, SPI_I2S_DMAReq_Tx, ENABLE); 

开启 DMA 时钟

void APP_DMA_Configuration(void)
{
  RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1, ENABLE);
}

因为DMA每次传输的数量在变化, 所以DMA的初始化在图像输出的方法里

2. 修改图像更新方法

图像更新方法的变化比较大, 这里需要根据输入的坐标, 计算实际的数据长度, 并对DMA进行初始化, 然后启动传输, 等待完成后关闭DMA

void my_disp_flush(lv_disp_drv_t *disp, const lv_area_t *area, lv_color_t *color_p)
{
  uint16_t len;
  DMA_InitTypeDef initStructure;

  len = (area->x2 - area->x1 + 1) * (area->y2 - area->y1 + 1) * 2;

  ST7735_CS_LOW;
  ST7735_SetAddrWindow(area->x1, area->y1, area->x2, area->y2);
  /* DMA1 Channel3 (triggered by SPI1 Tx event) Config */
  DMA_DeInit(DMA1_Channel3);
  initStructure.DMA_BufferSize = len;
  initStructure.DMA_M2M = DMA_M2M_Disable;
  initStructure.DMA_DIR = DMA_DIR_PeripheralDST;
  initStructure.DMA_MemoryBaseAddr = (uint32_t)color_p;
  initStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_By
首页 上一页 1 2 3 4 5 下一页 尾页 4/5/5
】【打印繁体】【投稿】【收藏】 【推荐】【举报】【评论】 【关闭】 【返回顶部
上一篇手把手教你基于luatos的4G(LTE Ca.. 下一篇痞子衡嵌入式:在i.MXRT启动头FDC..

最新文章

热门文章

Hot 文章

Python

C 语言

C++基础

大数据基础

linux编程基础

C/C++面试题目