基于RA8D1MIPIDSI实现LVGL

原创 瑞萨MCU小百科 2024-03-13 12:03


1

介绍


本文介绍由e2 studio自动生成的FSP LVGL pack的使用说明,Pack的生成方法可以参考前面的介绍文章。用户可以通过添加该pack,以可视化的形式添加和配置Little VGL,包括Little VGL的分辨率、色深、DPI以及官方的demo等进行配置。用户不用再做移植Little VGL的源代码,不用再繁琐的添加各个头文件。本次实验所用硬件为EK-RA8D1,如下图。确保板子的SW1-7切换到“ON”



Pack下载链接

复制网址到浏览器中打开:

https://gitee.com/recn-mcu-ae/lvgl-ra-8.3.6-pack/tree/master/internal/projectgen/ra/packs


2

软件架构


通过pack生成的代码主要在ra→fsp→src→rm_lvgl_prot和ra→lvgl两个路径下


3

安装教程


1

打开e2 studio菜单中“File”→“Import... ”


2

在弹出的“Import”对话框中,选择“General”→“CMSIS Pack”,点击“Next”


3

在弹出的“Import CMSIS Pack”对话框中,点击“Specify pack file”右侧“...”,指定需要添加的pack文件


4

“Specify device family”选择“RA”,点击Finish


4

使用说明


1

重新打开e2 studio

2

新建工程,新建工程步骤不再赘述,FSP版本选择5.1.0及以上,Board选择EK-RA8D1

3

新建好工程后,添加LVGL的stack,这时候会提示GLCDC的时钟没有打开,切换到clocks选项卡,enable LCD的clock,选择PLL1P,让LCD时钟输出为240MHz即可。


添加MIPI DSI driver,左键点击Add MIPI DSI Output(Optional)→New→MIPI Display(r_mipi_dsi):


NOTE

Enable LCD的clock后,r_glcdc的红色提示会消失。


修改LVGL显示分辨率:480*854,enable 2D


使能touch


修改glcdc的名字为g_display_lvgl


4

添加2D驱动,如果上述步骤没有enable 2D,此步骤可以跳过。New Stack→Graphics→D/AVE 2D Port Interface


添加完2D stack后,在BSP选项卡中heap给2D使用,同时加大stack的值为0x2000


5

添加I2C驱动


修改I2C的配置,Name: g_i2c_master1, Channel: 1, Slave address: 0x5D, Callback: g_i2c_master1_cb, Interrupt Priority Level:Priority 12


6

添加GPIO中断,修改irq的配置:Name:g_external_irq3,Channel:3,Callback:touch_irq_cb


P510设为input模式,IRQ选择为IRQ3


7

配置引脚,改变SDRAM的引脚驱动能力:PA00 -- H, PA08 -- H, PA09 -- HH, PA10 -- H, P404设为输出模式,初始化为高电平,PA01设为输出模式,初始化为高电平

8

点击Generate Project Content,生成代码

9

添加应用代码,做一个LVGL下拉控件。修改 hal_entry.c如下:

上下滑动查看更多

左右滑动查看完整代码内容

#include "hal_data.h"#include "dsi_layer.h"#include "lvgl.h"#include "lv_demos.h"
FSP_CPP_HEADERvoid R_BSP_WarmStart(bsp_warm_start_event_t event);FSP_CPP_FOOTER

#define RGB_565_REG    (0x1F << 11)#define RGB_565_GREEN  (0x3F << 5)#define RGB_565_BLUE   (0x1F << 0)
/* Global variable to keep track of requested application */void SysTick_Handler(void);
#define LVGL_TICK_MS 1Ustatic volatile uint32_t s_tick        = 0U;static volatile bool s_lvglTaskPending = false;#define LVGL_TASK_PERIOD_TICK 3Ustatic void DEMO_SetupTick(void){if (0 != SysTick_Config(SystemCoreClock / (LVGL_TICK_MS * 1000U))){while (1);}}
void SysTick_Handler(void){s_tick++;lv_tick_inc(LVGL_TICK_MS);
if ((s_tick % LVGL_TASK_PERIOD_TICK) == 0U){s_lvglTaskPending = true;}}
#if LV_BUILD_EXAMPLES
static void event_handler(lv_event_t * e){lv_event_code_t code = lv_event_get_code(e);lv_obj_t * obj = lv_event_get_target(e);if(code == LV_EVENT_VALUE_CHANGED) {char buf[32];lv_dropdown_get_selected_str(obj, buf, sizeof(buf));LV_LOG_USER("Option: %s", buf);}}
void lv_example_dropdown_1(void){
/*Create a normal drop down list*/lv_obj_t * dd = lv_dropdown_create(lv_scr_act());lv_dropdown_set_options(dd, "Apple\n""Banana\n""Orange\n""Cherry\n""Grape\n""Raspberry\n""Melon\n""Orange\n""Lemon\n""Nuts");
lv_obj_align(dd, LV_ALIGN_TOP_MID, 0, 20);lv_obj_add_event_cb(dd, event_handler, LV_EVENT_ALL, NULL);}#endif
/*******************************************************************************************************************//**main() is generated by the RA Configuration editor and is used to generate threads if an RTOS is used.  This functionis called by main() when no RTOS is used.**********************************************************************************************************************/void hal_entry(void){
/* TODO: add your own code here */fsp_err_t  err;/* Fill the Frame buffer with Blue, to zero out info from previous execution runs */uint32_t count;
uint16_t * p = (uint16_t *)&fb_background[0][0];for (count = 0; count < sizeof(fb_background)/2; count++){*p++ = RGB_565_REG;}
DEMO_SetupTick();lv_init();
lv_port_disp_init();#if Touch_Enablelv_port_indev_init();#endif
lv_example_dropdown_1();#if LV_USE_DEMO_WIDGETS//       lv_demo_widgets();#endif
#if LV_USE_DEMO_STRESSlv_demo_stress();#endif#if LV_USE_DEMO_BENCHMARKlv_demo_benchmark();#endif#if LV_USE_DEMO_MUSIClv_demo_music();#endif//    lv_task_handler();/* handle the tasks of LVGL */while(1){while (!s_lvglTaskPending){}s_lvglTaskPending = false;lv_task_handler();}


#if BSP_TZ_SECURE_BUILD/* Enter non-secure code */R_BSP_NonSecureEnter();#endif}
/*******************************************************************************************************************//**This function is called at various points during the startup process.  This implementation uses the event that iscalled right before main() to set up the pins.** @param[in]  event    Where at in the start up process the code is currently at**********************************************************************************************************************/void R_BSP_WarmStart(bsp_warm_start_event_t event){if (BSP_WARM_START_RESET == event){#if BSP_FEATURE_FLASH_LP_VERSION != 0
/* Enable reading from data flash. */R_FACI_LP→DFLCTL = 1U;
/* Would normally have to wait tDSTOP(6us) for data flash recovery. Placing the enable here, before clock andC runtime initialization, should negate the need for a delay since the initialization will typically take more than 6us. */#endif}
if (BSP_WARM_START_POST_C == event){/* C runtime environment and system clocks are setup. */
/* Configure pins. */R_IOPORT_Open (&g_ioport_ctrl, &IOPORT_CFG_NAME);
bsp_sdram_init(); //SDRAM pins need to be set to HIGH drive strength in pin configuration}}
#if BSP_TZ_SECURE_BUILD
FSP_CPP_HEADERBSP_CMSE_NONSECURE_ENTRY void template_nonsecure_callable ();
/* Trustzone Secure Projects require at least one nonsecure callable function in order to build (Remove this if it is not required to build). */BSP_CMSE_NONSECURE_ENTRY void template_nonsecure_callable (){
}FSP_CPP_FOOTER
#endif

10

编译,下载到EK-RA8D1,连接MIPI屏,会得到以下结果:


至此,已经完成LVGL的移植以及测试。下面我们直接配置FSP,把官方的demo使能起来:打开configuration.xml,配置如下:


配置完成后,点击Generate Project Content。修改hal_entry.c:

上下滑动查看更多

左右滑动查看完整代码内容

 #include "hal_data.h" #include "dsi_layer.h" #include "lvgl.h" #include "lv_demos.h"
FSP_CPP_HEADER void R_BSP_WarmStart(bsp_warm_start_event_t event); FSP_CPP_FOOTER

#define RGB_565_REG    (0x1F << 11) #define RGB_565_GREEN  (0x3F << 5) #define RGB_565_BLUE   (0x1F << 0)
/* Global variable to keep track of requested application */ void SysTick_Handler(void);
#define LVGL_TICK_MS 1U static volatile uint32_t s_tick        = 0U; static volatile bool s_lvglTaskPending = false; #define LVGL_TASK_PERIOD_TICK 3U static void DEMO_SetupTick(void){    if (0 != SysTick_Config(SystemCoreClock / (LVGL_TICK_MS * 1000U)))    {        while (1)            ;    } }
void SysTick_Handler(void){    s_tick++;    lv_tick_inc(LVGL_TICK_MS);
   if ((s_tick % LVGL_TASK_PERIOD_TICK) == 0U)    {        s_lvglTaskPending = true;    } }
#if LV_BUILD_EXAMPLES
static void event_handler(lv_event_t * e){    lv_event_code_t code = lv_event_get_code(e);    lv_obj_t * obj = lv_event_get_target(e);    if(code == LV_EVENT_VALUE_CHANGED) {        char buf[32];        lv_dropdown_get_selected_str(obj, buf, sizeof(buf));        LV_LOG_USER("Option: %s", buf);    } }
void lv_example_dropdown_1(void){
   /*Create a normal drop down list*/    lv_obj_t * dd = lv_dropdown_create(lv_scr_act());    lv_dropdown_set_options(dd, "Apple\n"                            "Banana\n"                            "Orange\n"                            "Cherry\n"                            "Grape\n"                            "Raspberry\n"                            "Melon\n"                            "Orange\n"                            "Lemon\n"                            "Nuts");
   lv_obj_align(dd, LV_ALIGN_TOP_MID, 0, 20);    lv_obj_add_event_cb(dd, event_handler, LV_EVENT_ALL, NULL); } #endif
/*******************************************************************************************************************//**  * main() is generated by the RA Configuration editor and is used to generate threads if an RTOS is used.  This function  * is called by main() when no RTOS is used.  **********************************************************************************************************************/ void hal_entry(void){
   /* TODO: add your own code here */    fsp_err_t  err;    /* Fill the Frame buffer with Blue, to zero out info from previous execution runs */    uint32_t count;
   uint16_t * p = (uint16_t *)&fb_background[0][0];    for (count = 0; count < sizeof(fb_background)/2; count++)    {        *p++ = RGB_565_REG;    }
   DEMO_SetupTick(); //为lvgl提供心跳    lv_init();    lv_port_disp_init(); #if Touch_Enable    lv_port_indev_init(); #endif
//       lv_example_dropdown_1(); #if LV_USE_DEMO_WIDGETS    lv_demo_widgets(); #endif
#if LV_USE_DEMO_STRESS    lv_demo_stress(); #endif #if LV_USE_DEMO_BENCHMARK    lv_demo_benchmark(); #endif #if LV_USE_DEMO_MUSIC    lv_demo_music(); #endif //    lv_task_handler();    /* handle the tasks of LVGL */    while(1)    {        while (!s_lvglTaskPending)        {        }        s_lvglTaskPending = false;        lv_task_handler();    }


#if BSP_TZ_SECURE_BUILD    /* Enter non-secure code */    R_BSP_NonSecureEnter(); #endif }
   /*******************************************************************************************************************//**    * This function is called at various points during the startup process.  This implementation uses the event that is    * called right before main() to set up the pins.    *    * @param[in]  event    Where at in the start up process the code is currently at    **********************************************************************************************************************/    void R_BSP_WarmStart(bsp_warm_start_event_t event){        if (BSP_WARM_START_RESET == event)        {    #if BSP_FEATURE_FLASH_LP_VERSION != 0
           /* Enable reading from data flash. */            R_FACI_LP→DFLCTL = 1U;
           /* Would normally have to wait tDSTOP(6us) for data flash recovery. Placing the enable here, before clock and            * C runtime initialization, should negate the need for a delay since the initialization will typically take more than 6us. */    #endif        }
       if (BSP_WARM_START_POST_C == event)        {            /* C runtime environment and system clocks are setup. */
           /* Configure pins. */            R_IOPORT_Open (&g_ioport_ctrl, &IOPORT_CFG_NAME);
           bsp_sdram_init(); //SDRAM pins need to be set to HIGH drive strength in pin configuration        }    }
   #if BSP_TZ_SECURE_BUILD
   FSP_CPP_HEADER    BSP_CMSE_NONSECURE_ENTRY void template_nonsecure_callable ();
   /* Trustzone Secure Projects require at least one nonsecure callable function in order to build (Remove this if it is not required to build). */    BSP_CMSE_NONSECURE_ENTRY void template_nonsecure_callable (){
   }    FSP_CPP_FOOTER
   #endif


编译,下载。得到结果如下:


如果实验过程有问题,可以下载本仓库中e2studio_project\下的RA8D1_simple_demo和RA8D1_widgets_demo两个完整的工程做对比。


基于RA8D1的LVGL FSP配置以及使用已经介绍完毕。


您可识别下方二维码或复制网址到浏览器中打开进入瑞萨技术论坛:

https://community-ja.renesas.com/zh/forums-groups/mcu-mpu/


1

END

1


推荐阅读

RA8D1 CEU介绍与使用说明

LVGL Pack自动生成指导手册(上)

LVGL Pack自动生成指导手册(下)

更多精彩内容,请点击

评论
  • TOF多区传感器: ND06   ND06是一款微型多区高集成度ToF测距传感器,其支持24个区域(6 x 4)同步测距,测距范围远达5m,具有测距范围广、精度高、测距稳定等特点。适用于投影仪的无感自动对焦和梯形校正、AIoT、手势识别、智能面板和智能灯具等多种场景。                 如果用ND06进行手势识别,只需要经过三个步骤: 第一步&
    esad0 2024-12-04 11:20 50浏览
  •         温度传感器的精度受哪些因素影响,要先看所用的温度传感器输出哪种信号,不同信号输出的温度传感器影响精度的因素也不同。        现在常用的温度传感器输出信号有以下几种:电阻信号、电流信号、电压信号、数字信号等。以输出电阻信号的温度传感器为例,还细分为正温度系数温度传感器和负温度系数温度传感器,常用的铂电阻PT100/1000温度传感器就是正温度系数,就是说随着温度的升高,输出的电阻值会增大。对于输出
    锦正茂科技 2024-12-03 11:50 106浏览
  • 11-29学习笔记11-29学习笔记习学习笔记&记录学习学习笔记&记录学习学习笔记&记录学习学习笔记&记录学习笔记&记录学习习笔记&记学习学习笔记&记录学习学习笔记&记录学习习笔记&记录学习学习笔记&记录学习学习笔记记录学习学习笔记&记录学习学习笔记&记录学习学习笔记&记录学习学习笔记&记录学习学习笔记&记录学习习笔记&记录学习学习笔记&记录学习学习笔记&记录学习学习笔记&记录学习学习笔记&记录学习学习笔记&记录学习学习笔记&记录学习学习笔记&学习学习笔记&记录学习学习笔记&记录学习学习笔记&记
    youyeye 2024-12-02 23:58 71浏览
  • 当前,智能汽车产业迎来重大变局,随着人工智能、5G、大数据等新一代信息技术的迅猛发展,智能网联汽车正呈现强劲发展势头。11月26日,在2024紫光展锐全球合作伙伴大会汽车电子生态论坛上,紫光展锐与上汽海外出行联合发布搭载紫光展锐A7870的上汽海外MG量产车型,并发布A7710系列UWB数字钥匙解决方案平台,可应用于数字钥匙、活体检测、脚踢雷达、自动泊车等多种智能汽车场景。 联合发布量产车型,推动汽车智能化出海紫光展锐与上汽海外出行达成战略合作,联合发布搭载紫光展锐A7870的量产车型
    紫光展锐 2024-12-03 11:38 101浏览
  • RDDI-DAP错误通常与调试接口相关,特别是在使用CMSIS-DAP协议进行嵌入式系统开发时。以下是一些可能的原因和解决方法: 1. 硬件连接问题:     检查调试器(如ST-Link)与目标板之间的连接是否牢固。     确保所有必要的引脚都已正确连接,没有松动或短路。 2. 电源问题:     确保目标板和调试器都有足够的电源供应。     检查电源电压是否符合目标板的规格要求。 3. 固件问题: &n
    丙丁先生 2024-12-01 17:37 100浏览
  • 概述 说明(三)探讨的是比较器一般带有滞回(Hysteresis)功能,为了解决输入信号转换速率不够的问题。前文还提到,即便使能滞回(Hysteresis)功能,还是无法解决SiPM读出测试系统需要解决的问题。本文在说明(三)的基础上,继续探讨为SiPM读出测试系统寻求合适的模拟脉冲检出方案。前四代SiPM使用的高速比较器指标缺陷 由于前端模拟信号属于典型的指数脉冲,所以下降沿转换速率(Slew Rate)过慢,导致比较器检出出现不必要的问题。尽管比较器可以使能滞回(Hysteresis)模块功
    coyoo 2024-12-03 12:20 108浏览
  • 光伏逆变器是一种高效的能量转换设备,它能够将光伏太阳能板(PV)产生的不稳定的直流电压转换成与市电频率同步的交流电。这种转换后的电能不仅可以回馈至商用输电网络,还能供独立电网系统使用。光伏逆变器在商业光伏储能电站和家庭独立储能系统等应用领域中得到了广泛的应用。光耦合器,以其高速信号传输、出色的共模抑制比以及单向信号传输和光电隔离的特性,在光伏逆变器中扮演着至关重要的角色。它确保了系统的安全隔离、干扰的有效隔离以及通信信号的精准传输。光耦合器的使用不仅提高了系统的稳定性和安全性,而且由于其低功耗的
    晶台光耦 2024-12-02 10:40 120浏览
  • 遇到部分串口工具不支持1500000波特率,这时候就需要进行修改,本文以触觉智能RK3562开发板修改系统波特率为115200为例,介绍瑞芯微方案主板Linux修改系统串口波特率教程。温馨提示:瑞芯微方案主板/开发板串口波特率只支持115200或1500000。修改Loader打印波特率查看对应芯片的MINIALL.ini确定要修改的bin文件#查看对应芯片的MINIALL.ini cat rkbin/RKBOOT/RK3562MINIALL.ini修改uart baudrate参数修改以下目
    Industio_触觉智能 2024-12-03 11:28 84浏览
  • 最近几年,新能源汽车愈发受到消费者的青睐,其销量也是一路走高。据中汽协公布的数据显示,2024年10月,新能源汽车产销分别完成146.3万辆和143万辆,同比分别增长48%和49.6%。而结合各家新能源车企所公布的销量数据来看,比亚迪再度夺得了销冠宝座,其10月新能源汽车销量达到了502657辆,同比增长66.53%。众所周知,比亚迪是新能源汽车领域的重要参与者,其一举一动向来为外界所关注。日前,比亚迪汽车旗下品牌方程豹汽车推出了新车方程豹豹8,该款车型一上市就迅速吸引了消费者的目光,成为SUV
    刘旷 2024-12-02 09:32 119浏览
  • 作为优秀工程师的你,已身经百战、阅板无数!请先醒醒,新的项目来了,这是一个既要、又要、还要的产品需求,ARM核心板中一个处理器怎么能实现这么丰富的外围接口?踌躇之际,你偶阅此文。于是,“潘多拉”的魔盒打开了!没错,USB资源就是你打开新世界得钥匙,它能做哪些扩展呢?1.1  USB扩网口通用ARM处理器大多带两路网口,如果项目中有多路网路接口的需求,一般会选择在主板外部加交换机/路由器。当然,出于成本考虑,也可以将Switch芯片集成到ARM核心板或底板上,如KSZ9897、
    万象奥科 2024-12-03 10:24 68浏览
我要评论
0
点击右上角,分享到朋友圈 我知道啦
请使用浏览器分享功能 我知道啦