【吃灰开发板复活】DIY全志V3s随身终端屏幕适配,LVGL以及各种外设驱动移植教程

在上周的文章中介绍了一款因作者想要学习Linux而动手DIY的终端设备V3S-PI,

《梦回2004!我用全志V3s做了个成本100元,功能媲美MP4的随身终端》:梦回2004!我用全志V3s做了个成本100元,功能媲美MP4的随身终端 | 全志在线开发者论坛

并详细解析了项目的硬件设计部分,本文将着重介绍项目的软件适配部分,并挑选其中几个普适性较强的外设功能来进行介绍。

微信图片_20240108132611.jpg

微信图片_20240108132629.jpg

V3S-PI是基于全志V3s设计的开发板,V3s芯片包含专用视频引擎以提供高级多媒体应用程序和服务,开发板设计之初就预留了屏幕、音频等接口,作者本人给这块开发板增加适配的外设以及功能有将近10个:获取天气、连耳机播放音乐、10M/100M以太网接口、连wifi、接入SD卡、调整屏幕亮度、按键控制、外接其他设备、1转4USB HUB......

而在适配了屏幕,移植了LVGL以及各种外设驱动后,开发板摇身一变成为功能可以媲美MP4的随身终端。

640.gif

640 (1).gif

640 (2).gif

640 (3).gif

2.4寸LCD彩屏适配

LCD彩屏使用SPI接口与主控连接,由于各家屏幕初始化代码不同,所以st7735r.c文件在原来的基础上,我们只需修改st7735r_pipe_enable这个函数中的代码即可。

  • 软件部分采用TinyDRM,与传统的fbtft相比,不再是固定帧率刷新。
  • 采用DRM架构,可以与新架构程序更快集成。

修改完成的代码参考下方文件,设备树配置参考:


&spi0 {
       status = "okay";
       pinctrl-names = "default";
       pinctrl-0 = <&spi0_pins>;


       display@0 {
        compatible = "jianda,jd-t18003-t01";
        reg = <0>;
           spi-max-frequency = <95000000>;


        backlight = <&panel_backlight>;
        dc-gpios = <&pio 4 9 0>; // PE9
        reset-gpios = <&pio 4 8 0>; // PE8
        rotation = <0>;
    };
};

除spi外,需要添加一个背光节点,这样就可以在用户层操作背光:


panel_backlight: panel-backlight {
              compatible = "gpio-backlight";
        gpios = <&pio 4 7 GPIO_ACTIVE_HIGH>; // PE7
              default-on;
              status = "okay";
       };

顺利适配好屏幕后移植上LVGL,可以在刷FB的图层刷出来700帧的高刷。
 

640.gif

 

640 (4).gif

libcurl获取天气信息方式

为了丰富功能,作者还通过libcurl库实现了获取天气信息的功能,通过回调函数处理获取到的JSON数据,并使用lvgl库显示天气信息。

这里需要用到一个回调函数,用于解析获取到的JSON格式的天气信息。它首先使用cJSON库对获取到的数据进行解析,并找到对应的天气信息字段。

// 解析json数据
    cJSON * json = cJSON_ParseWithLength(ptr, size * nmemb);
    if(!json) {
        goto end;
    }
    json = cJSON_GetObjectItem(json, "now");
    if(!json) {
        goto end;
    }
    cJSON * temp     = cJSON_GetObjectItem(json, "temp");
    cJSON * humidity = cJSON_GetObjectItem(json, "humidity");
    cJSON * text     = cJSON_GetObjectItem(json, "text");
    cJSON * pressure = cJSON_GetObjectItem(json, "pressure");

然后使用其它函数进行线程锁定,以防止多线程冲突,接着利用LVGL库的相关函数将天气信息设置到对应的标签上。

pthread_mutex_lock(&mutex);
    if(cJSON_IsString(text)) {
        lv_label_set_text_fmt(label1, "当前天气\n%s", text->valuestring);
    }
    if(cJSON_IsString(pressure)) {
        lv_label_set_text_fmt(label2, "气压\n%s hPa", pressure->valuestring);
    }
    if(cJSON_IsString(temp)) {
        lv_label_set_text_fmt(label3, "室外温度\n%s ℃", temp->valuestring);
    }
    if(cJSON_IsString(humidity)) {
        lv_label_set_text_fmt(label4, "湿度\n%s %%", humidity->valuestring);
    }
    pthread_mutex_unlock(&mutex);

    cJSON_Delete(json);

end:
    return size * nmemb;

微信图片_20240108132625.jpg

get_now_weather函数首先定义一个URL字符串,其中包含了获取天气信息所需的地址和参数。然后通过curl_easy_init创建一个CURL对象,并配置相应的选项,如设置URL、禁止进度信息、忽略SSL证书校验、设置回调函数等。接着使用curl_easy_perform执行请求,并检查返回的结果。最后使用curl_easy_cleanup清理CURL对象。

char * url =
        "https://devapi.qweather.com/v7/weather/now?location=" LOCATION "&key=xxx";
    CURL * curl = curl_easy_init();

    curl_easy_setopt(curl, CURLOPT_URL, url);
    curl_easy_setopt(curl, CURLOPT_NOPROGRESS, 1L);
    //    curl_easy_setopt(curl, CURLOPT_VERBOSE, 1L);
    curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, 0L);
    curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, now_weather_cb);
    curl_easy_setopt(curl, CURLOPT_ENCODING, "gzip");

需要根据实际情况修改URL字符串中的LOCATIONxxx,并根据天气API的要求进行必要的参数配置和授权等操作。

音频播放

Buildroot中集成了alsa,默认声卡会静音状态,打开终端,输入alsamixer,首先解除静音。

在当前界面,选中Headphone,然后按下M键 解除静音,然后使用键盘↑,调整音量到合适大小即可,界面可参考:

微信图片_20240108133147.png

调整完成后,输入mpv 文件名 --no-video,插入耳机,即可实现音乐播放:


[root@buildroot ~]# mpv 2.flac --no-video
     Video --vid=1 [P] (mjpeg 500x500 1.000fps)
 (+) Audio --aid=1 (flac 2ch 48000Hz)
File tags:
 Album: 西厢寻他
 Title: 西厢寻他
 Track: 1
AO: [alsa] 48000Hz stereo 2ch s32
A: 00:00:04 / 00:03:43 (2%)


Exiting... (Quit)

命令提示符显示当前目录,编辑/etc/profile文件,添加一行,然后export /etc/profile重新加载配置即可:

export PS1='[\u@\h \w]\$ '

640 (1).gif

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/345460.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

微信小程序如何获取当前日期时间

Hello大家好&#xff01;我是咕噜铁蛋&#xff0c;获取当前日期时间是小程序中经常会用到的一个功能。因此&#xff0c;在本文中&#xff0c;我通过科技手段给大家收集整理了下&#xff0c;今天我将向大家介绍如何在微信小程序中获取当前日期时间的方法&#xff0c;并分享一些实…

HubSpot在线客户互动:建立强大数字连接的关键一步

HubSpot在线客户互动为企业带来了多方面的具体业务优势&#xff0c;其中一些关键点包括&#xff1a; 提高销售转化率&#xff1a; 通过实时在线聊天、个性化推荐等互动方式&#xff0c;HubSpot使企业能够更主动地接触潜在客户&#xff0c;解答其疑问&#xff0c;提供定制化的…

RabbitMQ——高级篇

目录 一、MQ的常见问题 二、消息可靠性问题 生产者消息确认 消息持久化 消费者消息确认 失败重试机制 三、死信交换机 简介死信交换机 TTL超时机制 延迟队列 四、惰性队列 消息堆积问题 惰性队列 一、MQ的常见问题 消息可靠性问题&#xff1a;如何确保发送的…

解决 Git:ssh: connect to host github.com port 22: Connection timed out 问题的三种方案

1、问题描述&#xff1a; 其一、整体提示为&#xff1a; ssh: connect to host github.com port 22: Connection timed out fatal: Could not read from remote repository. 中文为&#xff1a; ssh&#xff1a;连接到主机 github.com 端口 22&#xff1a;连接超时 fatal&a…

【设计模式】腾讯面经:原型模式怎么理解?

什么是原型模式&#xff1f; 设计模式是编程世界的基石&#xff0c;其中原型模式无疑是一种常用而又高效的创建对象的手段。那么&#xff0c;什么是原型模式呢&#xff1f;又该如何去实现它&#xff1f; 在软件工程中&#xff0c;原型模式是一种创建型设计模式。我们可以这样…

「JavaSE」抽象类接口2

&#x1f387;个人主页&#xff1a;Ice_Sugar_7 &#x1f387;所属专栏&#xff1a;快来卷Java啦 &#x1f387;欢迎点赞收藏加关注哦&#xff01; 抽象类&接口2 &#x1f349;接口间的继承&#x1f349;接口的应用&#x1f349;总结 &#x1f349;接口间的继承 和类的继承…

Pyside6中QTableWidget使用

目录 一&#xff1a;介绍&#xff1a; 二&#xff1a;演示 一&#xff1a;介绍&#xff1a; 在 PySide6 中&#xff0c;QTableWidget 是一个用于展示和编辑表格数据的控件。它提供了在窗口中创建和显示表格的功能&#xff0c;并允许用户通过单元格来编辑数据。 要使用 QTabl…

黑马Java——面向对象进阶(static继承)

1.static静态变量 静态变量是随着类的加载而加载的&#xff0c;优先与对象出现的

Kotlin 开发环境配置指南

一、下载与安装 Kotlin 编译器 步骤 1&#xff1a;获取最新版 Kotlin 编译器 要配置 Kotlin 开发环境&#xff0c;首先需要从 JetBrains 官方 GitHub 仓库下载最新的 Kotlin 编译器。访问以下链接以获取最新版本的编译器&#xff1a; [https://github.com/JetBrains/kotlin/…

Severstal公司的汉语名字是什么,是一家什么样的公司?

问题描述&#xff1a;Severstal公司的汉语名字是什么&#xff0c;是一家什么样的公司&#xff1f; 问题解答&#xff1a; Severstal 公司的中文名字通常被翻译为 "谢韦尔钢铁公司"。这家公司是俄罗斯的一家大型钢铁和矿业企业&#xff0c;总部位于莫斯科。Seversta…

libtorch学习第六

构建卷积网络 #include<torch/torch.h> #include<torch/script.h> #include<iostream>using std::cout; using std::endl;class LinearBnReluImpl : public torch::nn::Module { private:torch::nn::Linear ln{ nullptr };torch::nn::BatchNorm1d bn{ nullp…

[Python] glob内置模块介绍和使用场景(案例)

Unix glob是一种用于匹配文件路径的模式&#xff0c;它可以帮助我们快速地找到符合特定规则的文件。在本文中&#xff0c;我们将介绍glob的基本概念、使用方法以及一些实际应用案例。 glob介绍 Glob(Global Match)是Unix和类Unix系统中的一种文件名扩展功能&#xff0c;它可以…

分布式锁的实现方式

分布式锁是指分布式环境下&#xff0c;系统部署在多个机器中&#xff0c;实现多进程分布式互斥的一种锁。实现分布式锁有三种主流方式&#xff0c;接下来一一盘点。 盘点之前要说说选择时的优缺点 数据库实现的锁表完全不推荐。 Redis分布式锁性能优于ZooKeeper&#xff0c;因…

01、领域驱动设计:微服务设计为什么要选择DDD总结

目录 1、前言 2、软件架构模式的演进 3、微服务设计和拆分的困境 4、为什么 DDD适合微服务 5、DDD与微服务的关系 6、总结 1、前言 我们知道&#xff0c;微服务设计过程中往往会面临边界如何划定的问题&#xff0c;不同的人会根据自己对微服务的理 解而拆分出不同的微服…

通过 GScan 工具自动排查后门

一、简介 GScan 是一款为安全应急响应提供便利的工具&#xff0c;自动化监测系统中常见位置。 工具运行环境&#xff1a;CentOS (6、7) python (2.x、3.x) 工具检查项目&#xff1a; 1、主机信息获取 2、系统初始化 alias 检查 3、文件类安全扫描 3.1、系统重要文件完整行…

JS进阶-深入对象(二)

拓展&#xff1a;深入对象主要介绍的是Js的构造函数&#xff0c;实例成员&#xff0c;静态成员&#xff0c;其中构造函数和Java种的构造函数用法相似&#xff0c;思想是一样的&#xff0c;但静态成员和实例成员和java种的有比较大的差别&#xff0c;需要认真理解 • 创建对象三…

Switch用法以及新特性-最全总结版

本篇文章参考了大佬文章&#xff0c;感谢大佬无私分享&#xff1a; http://t.csdnimg.cn/MjZnX http://t.csdnimg.cn/QFg0x 目录 一、Switch用法&#xff1a;JDK7及以前 1.1、举例一&#xff1a; 1.2、举例二&#xff1a; 二、Switch穿透&#xff1a; 2.1、举例&#xf…

三极管的奥秘:如何用小电流控制大电流

双极性晶体管&#xff08;英语&#xff1a;bipolar transistor&#xff09;&#xff0c;全称双极性结型晶体管&#xff08;bipolar junction transistor, BJT&#xff09;&#xff0c;俗称三极管&#xff0c;是一种具有三个引脚的电子元器件。 本文是讲述的是三极管的基础知识…

基于openssl v3搭建ssl安全加固的c++ tcpserver

1 概述 tcp server和tcp client同时使用openssl库&#xff0c;可对通信双方流通的字节序列进行加解密&#xff0c;保障通信的安全。本文以c编写的tcp server和tcp client为例子&#xff0c;openssl的版本为v3。 2 安装openssl v3 2.1 安装 perl-IPC-Cmd openssl项目中的co…

企业内部知识库搭建教程,赶紧收藏起来

在企业运营中&#xff0c;内部知识库搭建是一项重要的挑战&#xff0c;并需要合理的规划与管理。尤其对于中大型企业&#xff0c;内部知识库能够提高工作效率&#xff0c;减轻员工工作压力与突发事件的处理的困扰。下面给大家提供一份完整的内部知识库搭建教程&#xff0c;快看…