HonestQiao 发表于 2023-12-13 18:08

【nRF7002-DK Wi-Fi® 6开发套件评测】驱动ST7789 TFT屏幕使用LVGL显示仪表盘

<div class='showpostmsg'> 本帖最后由 HonestQiao 于 2023-12-13 18:44 编辑

<p>之前在&nbsp;NUCLEO-U5A5ZJ-Q 开发板上,应用过Arduino兼容接口,驱动过ST7789 TFT屏幕。</p>

<p>nRF7002-DK 开发板的官方介绍中,主要特点里面,就有Arduino连接器:</p>

<p>&nbsp; 这个Arduino兼容接口,采用的是&nbsp;Arduino Uno Rev3 规格。&nbsp;Arduino Uno Rev3 是Arduino 世界最负盛名的开发板型号,兼容该接口,意味着千千万万Arduino Uno Rev3可用的传感器或者外部设备,都可以在咱们板子上使用了。</p>

<p>&nbsp;</p>

<p>这篇分享,就是使用Arduino兼容接口,连接DFRobot的ST7789显示屏来实现显示功能,包括基本的显示,以及显示仪表盘。</p>

<p>&nbsp;</p>

<p><span style="font-size:18px;"><strong>一、硬件了解</strong></span></p>

<p><strong>1. nRF7002-DK 开发板的Arduino接口了解</strong></p>

<p>nRF7002-DK 开发板的Arduino兼容接口具体信息,通过查看手册可以了解:</p>

<p> &nbsp;</p>

<p>兼容的接口,包括模拟接口A0~A5,数字IO D0~D13,以及IIC接口的SDA、SCL。</p>

<p>在开发版的背面,也做了友好的标注:</p>

<p> &nbsp;</p>

<p>对应正面的接口如下:</p>

<p> &nbsp;</p>

<p>&nbsp;</p>

<p><strong>2. DFRobot ST7789显示屏了解</strong></p>

<p>我手头的这块ST7789如下:</p>

<p> &nbsp;</p>

<p>&nbsp;</p>

<p>DFRobot官方介绍为:这是一款1.47英寸,分辨率为172&times;320的彩色高清IPS显示屏 ,采用驱动芯片ST7789V3、SPI通讯接口。</p>

<p>屏幕的背后如下:</p>

<p> &nbsp;</p>

<p>&nbsp;</p>

<p><strong>3.&nbsp;显示屏与开发板连接</strong></p>

<p>显示屏与开发板Arduino兼容接口的连接关系如下:</p>

<p> &nbsp;</p>

<p>&nbsp;</p>

<p>&nbsp;</p>

<p><span style="font-size:18px;"><strong>二、通过样例学习基础使用</strong></span></p>

<p>在Zephyr中,提供了ST7789的驱动,以及一个LVGL的实例,可以用于驱动ST7789屏来显示,但是在nRF7002-DK上使用,需要做一些对应的处理,具体如下。</p>

<p>&nbsp;</p>

<p><strong>1.&nbsp;新建工程</strong></p>

<p>首先,在VSCode的nRF Connect插件界面,从样例新建一个lvgl工程:</p>

<p> &nbsp;</p>

<p> &nbsp;</p>

<p>建立完成后,工程如下:</p>

<p> &nbsp;</p>

<p>&nbsp;</p>

<p><strong>2. 添加nRF7002-DK专用配置</strong></p>

<p>这个目录里面,有一个boards目录,用于存放特定开发板的专属配置文件。</p>

<p>nRF7002-DK在一般编译的时候,对应的board名称为:nrf7002dk_nrf5340_cpuapp&nbsp;</p>

<p>如果是其他类型的,下面的配置要参考添加。</p>

<p>&nbsp;</p>

<p>首先,添加一个&nbsp;nrf7002dk_nrf5340_cpuapp.conf 文件,内容如下:</p>

<pre>
<code class="language-ini">CONFIG_LV_COLOR_DEPTH_32=y
CONFIG_GPIO=y
CONFIG_INPUT=y
</code></pre>

<p>用于定义LVGL的颜色深度,以及启用GPIO等。</p>

<p>&nbsp;</p>

<p>然后,再添加一个nrf7002dk_nrf5340_cpuapp.overlay文件,用于自定义dts</p>

<pre>
<code class="language-json">#include &lt;zephyr/dt-bindings/led/led.h&gt;

/ {
        chosen {
                zephyr,display = &amp;st7789v_st7789v_dfrobot_172x320;
        };
};

&amp;arduino_spi {
        status = "okay";
        cs-gpios = &lt;&amp;arduino_header 16 GPIO_ACTIVE_LOW&gt;;        /* D10 */

        st7789v_st7789v_dfrobot_172x320: st7789v@0 {
                compatible = "sitronix,st7789v";
                spi-max-frequency = &lt;20000000&gt;;
                reg = &lt;0&gt;;
                cmd-data-gpios = &lt;&amp;arduino_header 15 GPIO_ACTIVE_LOW&gt;;        /* D9 */
                reset-gpios = &lt;&amp;arduino_header 14 GPIO_ACTIVE_LOW&gt;;        /* D8 */
                width = &lt;172&gt;;
                height = &lt;320&gt;;
                x-offset = &lt;35&gt;;
                y-offset = &lt;0&gt;;
                vcom = &lt;0x19&gt;;
                gctrl = &lt;0x35&gt;;
                vrhs = &lt;0x12&gt;;
                vdvs = &lt;0x20&gt;;
                mdac = &lt;0x00&gt;;
                gamma = &lt;0x01&gt;;
                colmod = &lt;0x05&gt;;
                lcm = &lt;0x2c&gt;;
                porch-param = ;
                cmd2en-param = ;
                pwctrl1-param = ;
                pvgam-param = ;
                nvgam-param = ;
                ram-param = ;
                rgb-param = ;
        };
};</code></pre>

<p>上述配置,定义了我所使用到的st7789屏的具体连接盒初始化信息,在代码中,最终为zephyr_display设备。</p>

<p>&nbsp;</p>

<p><strong>3. 编译下载测试</strong></p>

<p>编译上述代码:</p>

<p> &nbsp;</p>

<p>然后点Flash下载:</p>

<p> &nbsp;</p>

<p>&nbsp;</p>

<p>下载后,实际运行的效果如下:</p>

<p></p>

<p>&nbsp;</p>

<p>默认的演示代码,会在屏幕上显示 Hello World,并在底部显示一个计数器计数的值。&nbsp;</p>

<p>&nbsp;</p>

<p><span style="font-size:18px;"><strong>三、显示仪表盘</strong></span></p>

<p>上面的演示代码,过于简单,LVGL的强大没有体现出来。</p>

<p>下面,我们根据LVGL官方的实例,来进行仪表盘的显示。</p>

<p><strong>1. 添加meter和inidc的定义</strong></p>

<pre>
<code class="language-cpp">static lv_obj_t * meter;
static lv_meter_indicator_t * indic;
</code></pre>

<p>&nbsp;</p>

<p><strong>2. 添加 仪表盘值更新的回调</strong></p>

<pre>
<code class="language-cpp">static void set_value(void * indic, int32_t v)
{
    lv_meter_set_indicator_value(meter, indic, v);
}</code></pre>

<p>&nbsp;</p>

<p><strong>3. 添加一个测试用的仪表盘</strong></p>

<pre>
<code class="language-cpp">void lv_example_meter_1(void)
{
    meter = lv_meter_create(lv_scr_act());
    lv_obj_center(meter);
    lv_obj_set_size(meter, 150, 150);

    /*Add a scale first*/
    lv_meter_scale_t * scale = lv_meter_add_scale(meter);
    lv_meter_set_scale_ticks(meter, scale, 41, 2, 10, lv_palette_main(LV_PALETTE_GREY));
    lv_meter_set_scale_major_ticks(meter, scale, 8, 4, 15, lv_color_black(), 10);

    // lv_meter_indicator_t * indic;

    /*Add a blue arc to the start*/
    indic = lv_meter_add_arc(meter, scale, 3, lv_palette_main(LV_PALETTE_BLUE), 0);
    lv_meter_set_indicator_start_value(meter, indic, 0);
    lv_meter_set_indicator_end_value(meter, indic, 20);

    /*Make the tick lines blue at the start of the scale*/
    indic = lv_meter_add_scale_lines(meter, scale, lv_palette_main(LV_PALETTE_BLUE), lv_palette_main(LV_PALETTE_BLUE),
                                     false, 0);
    lv_meter_set_indicator_start_value(meter, indic, 0);
    lv_meter_set_indicator_end_value(meter, indic, 20);

    /*Add a red arc to the end*/
    indic = lv_meter_add_arc(meter, scale, 3, lv_palette_main(LV_PALETTE_RED), 0);
    lv_meter_set_indicator_start_value(meter, indic, 80);
    lv_meter_set_indicator_end_value(meter, indic, 100);

    /*Make the tick lines red at the end of the scale*/
    indic = lv_meter_add_scale_lines(meter, scale, lv_palette_main(LV_PALETTE_RED), lv_palette_main(LV_PALETTE_RED), false,
                                     0);
    lv_meter_set_indicator_start_value(meter, indic, 80);
    lv_meter_set_indicator_end_value(meter, indic, 100);

    /*Add a needle line indicator*/
    indic = lv_meter_add_needle_line(meter, scale, 4, lv_palette_main(LV_PALETTE_GREY), -10);

    /*Create an animation to set the value*/
    lv_anim_t a;
    lv_anim_init(&amp;a);
    lv_anim_set_exec_cb(&amp;a, set_value);
    lv_anim_set_var(&amp;a, indic);
    lv_anim_set_values(&amp;a, 0, 100);
    lv_anim_set_time(&amp;a, 2000);
    lv_anim_set_repeat_delay(&amp;a, 100);
    lv_anim_set_playback_time(&amp;a, 500);
    lv_anim_set_playback_delay(&amp;a, 100);
    lv_anim_set_repeat_count(&amp;a, LV_ANIM_REPEAT_INFINITE);
    lv_anim_start(&amp;a);
}</code></pre>

<p>&nbsp;</p>

<p>上述代码,添加了一个150x150的仪表盘,取值范围为0~100,并根据取值范围设置了对应的区间颜色:</p>

<ul>
        <li>0~20:蓝色</li>
        <li>80~100:红色</li>
        <li>其他为默认颜色</li>
</ul>

<p>在这个演示的最后,用了一个&nbsp;animation动画&nbsp;&nbsp;来更新仪表盘的值。实际上,也可以在循环部分,直接调用&nbsp;lv_meter_set_indicator_value(meter, indic, v) 来更新仪表盘的值。</p>

<p>关于LVGL的知识,这里就不详细介绍了,大家可以看LVGL官方的文档,非常的详细,包括各种实例代码。</p>

<p>&nbsp;</p>

<p>然后,在源代码的main()部分的while前面,添加下面的代码:</p>

<pre>
<code class="language-cpp">#if 1
        // 清屏
        lv_obj_clean(lv_scr_act());

        lv_example_meter_1();

        while(1) {
                lv_task_handler();
                k_sleep(K_MSEC(10));
        }
#endif</code></pre>

<p>上述代码的逻辑也不复杂,就是调用&nbsp;lv_example_meter_1() 绘制仪表盘,然后循环更新界面。</p>

<p>&nbsp;</p>

<p><strong>4. 编译下载测试</strong></p>

<p>配置和代码处理好了以后,编译下载测试,运行的效果如下:</p>

<p>81e39e0c66fddb6ca7316ccf5319970c<br />
&nbsp;</p>

<p>从上面的效果可以看出,运行起来丝滑流畅,效果非常不错。</p>

<p>&nbsp;</p>

<p>5. 问题处理</p>

<p>细心的同学,可能会发现,怎么显示的颜色,和前面代码中说明的,不一样啊?</p>

<p>前面还差2个配置需要修改,具体修改如下:</p>

<p>文件:/opt/nordic/ncs/v2.5.0/zephyr/boards/shields/st7789v_generic/Kconfig.defconfig</p>

<pre>
<code class="language-bash"># Copyright (c) 2019 Jan Van Winkel &lt;jan.van_winkel@dxplore.eu&gt;
# SPDX-License-Identifier: Apache-2.0

if SHIELD_ST7789V_TL019FQV01 || SHIELD_ST7789V_WAVESHARE_240X240 || SHIELD_ST7789V_DFROBOT_172x320

if DISPLAY

choice ST7789V_PIXEL_FORMAT
        default ST7789V_RGB888 if SHIELD_ST7789V_TL019FQV01
        default ST7789V_RGB565 if SHIELD_ST7789V_WAVESHARE_240X240
        default ST7789V_RGB565 if SHIELD_ST7789V_DFROBOT_172x320
endchoice

if LVGL

config LV_Z_BITS_PER_PIXEL
        default 24 if SHIELD_ST7789V_TL019FQV01
        default 16 if SHIELD_ST7789V_WAVESHARE_240X240
        default 16 if SHIELD_ST7789V_DFROBOT_172x320

choice LV_COLOR_DEPTH
        default LV_COLOR_DEPTH_16 if SHIELD_ST7789V_WAVESHARE_240X240
        default LV_COLOR_DEPTH_16 if SHIELD_ST7789V_DFROBOT_172x320
endchoice

config LV_COLOR_16_SWAP
        default y if SHIELD_ST7789V_WAVESHARE_240X240
        default y if SHIELD_ST7789V_DFROBOT_172x320

endif # LVGL

endif # DISPLAY

endif # SHIELD_ST7789V_TL019FQV01 || SHIELD_ST7789V_WAVESHARE_240X240 || SHIELD_ST7789V_DFROBOT_172x320
</code></pre>

<p>文件:/opt/nordic/ncs/v2.5.0/zephyr/boards/shields/st7789v_generic/st7789v_dfrobot_172x320.overlay</p>

<pre>
<code class="language-bash">/*
* Copyright (c) 2019 Jan Van Winkel &lt;jan.van_winkel@dxplore.eu&gt;
* Copyright (c) 2019 PHYTEC Messtechnik GmbH
* Copyright (c) 2023 HonestQiao &lt;honestqiao@gmail.com&gt;
*
* SPDX-License-Identifier: Apache-2.0
*/

/ {
        chosen {
                zephyr,display = &amp;st7789v_st7789v_dfrobot_172x320;
        };
};

&amp;arduino_spi {
        status = "okay";
        cs-gpios = &lt;&amp;arduino_header 16 GPIO_ACTIVE_LOW&gt;;        /* D10 */

        st7789v_st7789v_dfrobot_172x320: st7789v@0 {
                compatible = "sitronix,st7789v";
                spi-max-frequency = &lt;20000000&gt;;
                reg = &lt;0&gt;;
                cmd-data-gpios = &lt;&amp;arduino_header 15 GPIO_ACTIVE_LOW&gt;;        /* D9 */
                reset-gpios = &lt;&amp;arduino_header 14 GPIO_ACTIVE_LOW&gt;;        /* D8 */
                width = &lt;172&gt;;
                height = &lt;320&gt;;
                x-offset = &lt;35&gt;;
                y-offset = &lt;0&gt;;
                vcom = &lt;0x19&gt;;
                gctrl = &lt;0x35&gt;;
                vrhs = &lt;0x12&gt;;
                vdvs = &lt;0x20&gt;;
                mdac = &lt;0x00&gt;;
                gamma = &lt;0x01&gt;;
                colmod = &lt;0x05&gt;;
                lcm = &lt;0x2c&gt;;
                porch-param = ;
                cmd2en-param = ;
                pwctrl1-param = ;
                pvgam-param = ;
                nvgam-param = ;
                ram-param = ;
                rgb-param = ;
        };
};
</code></pre>

<p>上述两个文件的路径,请根据你的实际情况修改。</p>

<p>&nbsp;</p>

<p>修改完成后,编译参数添加一个:-DSHIELD=st7789v_dfrobot_172x320</p>

<p> &nbsp;</p>

<p>然后重新进行编译下载,最终的效果如下:</p>

<p>2d4e747d7043084236601b10ab88e42d</p>

<p>&nbsp;</p>

<p>这次,颜色就完全正常了。</p>

<p>&nbsp;</p>

<p>&nbsp;</p>

<p><span style="font-size:18px;"><strong>四、总结</strong></span></p>

<p>nRF7002-DK 开发板的Arduino兼容接口非常的方便,能够快速应用上手头的Arduino外部设备,对开发者非常的友好。</p>

<p>上面演示了驱动ST7789,以及LVGL的简单应用。但LVGL的功能非常的强大,小到简单的仪表盘,再次播放器,或者其他更复杂的界面,都完全能够胜任。</p>

<p>掌握好了LVGL,以及相关的开发工具,就相当于给嵌入式设备开了光了,赶紧用起来吧。</p>
</div><script>                                        var loginstr = '<div class="locked">查看本帖全部内容,请<a href="javascript:;"   style="color:#e60000" class="loginf">登录</a>或者<a href="https://bbs.eeworld.com.cn/member.php?mod=register_eeworld.php&action=wechat" style="color:#e60000" target="_blank">注册</a></div>';
                                       
                                        if(parseInt(discuz_uid)==0){
                                                                                                (function($){
                                                        var postHeight = getTextHeight(400);
                                                        $(".showpostmsg").html($(".showpostmsg").html());
                                                        $(".showpostmsg").after(loginstr);
                                                        $(".showpostmsg").css({height:postHeight,overflow:"hidden"});
                                                })(jQuery);
                                        }                </script><script type="text/javascript">(function(d,c){var a=d.createElement("script"),m=d.getElementsByTagName("script"),eewurl="//counter.eeworld.com.cn/pv/count/";a.src=eewurl+c;m.parentNode.insertBefore(a,m)})(document,523)</script>
页: [1]
查看完整版本: 【nRF7002-DK Wi-Fi® 6开发套件评测】驱动ST7789 TFT屏幕使用LVGL显示仪表盘