ZHDA005 December   2025 MSPM33C321A , MSPM33C321A-Q1

 

  1.   1
  2.   摘要
  3.   商标
  4. 1概述
    1. 1.1 LVGL 项目设置
    2. 1.2 配置
    3. 1.3 初始化
    4. 1.4 LVGL 输出
    5. 1.5 LVGL 输入
    6. 1.6 LVGL 更新
  5. 2LVGL 示例
    1. 2.1 硬件连接
    2. 2.2 软件
    3. 2.3 LVGL 示例摘要
  6. 3总结
  7. 4修订历史记录

软件

下面描述了对 LVGL 示例所做的软件配置:

  • 配置
    • MCU:以下值是专门针对该示例配置的:
      • GPIO:本示例中有几个 GPIO 引脚配置为初始设置为高电平或低电平,如表 2-2 中所定义。这些值取决于显示屏及触控驱动器的要求。
        表 2-2 LVGL 示例 GPIO 引脚配置
        引脚名称 方向 初始值 分配的引脚

        LCD_SCS

        输出 设置 PB6
        LCD_SDC 输出 被清零 PB30
        LCD_RESET 输出 设置 PA10
        LCD_PWM 输出 被清零 PB3
        CTP_RST 输出 设置 PC4
        CTP_INT 输入 不适用 PC5
      • SYSCTL:SYSCTL 模块已配置成使用外部高频时钟输入作为 MCLK 的输入。HFXT 设置为以 40MHz 运行
      • I2C:所选的 I2C 外设 UC3 已配置为作为控制器运行并在快速模式 (400kHz) 下运行,欺诈 SDA 和 SCL 线路分别分配给 PA0 和 PA1
      • SPI:所选的 SPI 外设 UC2 已配置为用作控制器,在 40MHz 下运行,使用 CS1 作为芯片选择,并在 Motorola 4 线模式下运行,欺诈 SCLK、PICO、POCI 和 CS1 分配给 PA8、PA9、PB19 和 PB6
      • 计时器:所选的计时器模块 TIMG8_0 已配置为以 BUSCLK 为源,预分频为 40 倍,并以 1ms 的周期进行定期向下计数。中断已被配置成在计时器发生零事件时触发
    • LVGL:
      • 在此示例中,LVGL 已配置为所使用的 TFT 显示屏的规格。由于 LVGL 演示使用了许多不同的模块,因此许多可选字体和小工具都已启用。演示配置值 LV_USE_DEMO_WIDGETS 也经过专门启用,以便编译和运行 LVGL 演示。
        #define MY_DISP_HOR_RES        480
        #define MY_DISP_VER_RES        320
        ...
        #define LV_COLOR_DEPTH          16
        ...
        #define LV_MEM_SIZE   (48U * 1024U) // [bytes]
        ...
        #define LV_DRAW_COMPLEX 1
        ...
        #define LV_USE_DEMO_WIDGETS 1
  • 初始化
    • 需要先初始化的外设是之前通过 SysConfig 配置的外设
    • 接下来,用于触发系统节拍的计时器中断需要初始化
    • 在外设和计时器之后,需要初始化 LVGL 特定项
      • LVGL 初始化:LVGL 需要通过调用 lv_init 来进行初始化
      • 输出初始化:通过调用 lv_port_disp_init 来初始化 LVGL 显示驱动程序
        • 在本例中,lv_port_disp_init 遵循在节 1.3中定义的初始化步骤。刷新回调是在本节后面定义的
          void lv_port_disp_init(void)
          {
              disp_init(); // Initialize your display
          
              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*/
          
              static lv_disp_drv_t disp_drv;                         /*Descriptor of a display driver*/
              lv_disp_drv_init(&disp_drv);                    /*Basic initialization*/
          
              disp_drv.hor_res = MY_DISP_HOR_RES;
              disp_drv.ver_res = MY_DISP_VER_RES;
          
              disp_drv.flush_cb = disp_flush;
          
              disp_drv.draw_buf = &draw_buf_dsc_1;
          
              lv_disp_drv_register(&disp_drv); 
          }
      • 输入初始化:通过调用 lv_port_indev_init 来初始化 LVGL 输入器件驱动程序
        • 在本例中,lv_port_indev_init 遵循节 1.3中定义的初始化步骤。本节稍后会定义输入读取回调
          void lv_port_indev_init(void)
          {
              static lv_indev_drv_t indev_drv;
          
              touchpad_init(); //Initialize your touchpad
          
              lv_indev_drv_init(&indev_drv); //Register a touchpad input device
              indev_drv.type = LV_INDEV_TYPE_POINTER;
              indev_drv.read_cb = touchpad_read;
              indev_touchpad = lv_indev_drv_register(&indev_drv);
          }
    • 最后,系统节拍计时器启动
      int main(void)
      {
          SYSCFG_DL_init();
      
          NVIC_EnableIRQ(TIMER_0_INST_INT_IRQN);
      
          lv_init(); // init LVGL
          lv_port_disp_init();
          lv_port_indev_init();
      
          DL_TimerG_startCounter(TIMER_0_INST);
      
  • 输出
    • LVGL 通过调用先前在初始化部分中定义的刷新回调方法来发送像素数据。在此示例中,disp_flush 调用低级驱动程序代码 lvgl_LCD_Color_Fill,它处理 SPI 通信,然后通知 LVGL,刷新已准备就绪
      static void disp_flush(lv_disp_drv_t * disp_drv, const lv_area_t * area, lv_color_t * color_p)
      {
          lvgl_LCD_Color_Fill(area->x1, area->y1, area->x2, area->y2, color_p);
          lv_disp_flush_ready(disp_drv); //Inform the graphics library that you are ready with the flushing
      }
  • 输入
    • LVGL 通过调用先前在初始化部分中定义的输入读取回调方法来尝试读取用户输入。在此示例中,touchpad_read 调用处理 I2C 通信的低级驱动程序代码,以检查触控板是否已按下,然后在发生按下时处理按下的位置
      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;
      
          if(touchpad_is_pressed()) {
              touchpad_get_xy(&last_x, &last_y); //Save the pressed coordinates and the state
              data->state = LV_INDEV_STATE_PR;
          }
          else {
              data->state = LV_INDEV_STATE_REL;
          }
      
          data->point.x = last_x; //Set the last pressed coordinates
          data->point.y = last_y;
      }
      
  • 更新
    • LVGL 系统节拍是通过先前配置的 TIMG8_0 计时器中断而触发的。此中断每毫秒触发一次。
      void TIMER_0_INST_IRQHandler(void)
      {
          switch (DL_TimerG_getPendingInterrupt(TIMER_0_INST)) {
              case DL_TIMER_IIDX_ZERO:
      
                  lv_tick_inc(1);     //LVGL Heart Beat
      
                  break;
              default:
                  break;
          }
      }
    • LVGL 计时器触发在示例的主 while 循环中处理。为了不影响所有 CPU 处理,会有 320 个周期的延迟。
      while (1) {
              // update LVGL task
              lv_task_handler();
      
              delay_cycles(320);
          }
  • 主演示
    • 主演示在 lv_demo_widgets 中定义,它包含在 LVGL 库中。此演示展示了 LVGL 中包含的主要小部件。为了使用此演示,本演示的主源文件中包含了演示的头文件。
      #include "lv_demo_widgets.h"
      ...
      int main(void)
      {
      ...
          lv_demo_widgets();
      ...
      }