千家信息网

基于 RT-Thread 的“数码小精灵”设计与实现是怎样的

发表于:2026-11-03 作者:千家信息网编辑
千家信息网最后更新 2026年11月03日,基于 RT-Thread 的"数码小精灵"设计与实现是怎样的,针对这个问题,这篇文章详细介绍了相对应的分析和解答,希望可以帮助更多想解决这个问题的小伙伴找到更简单易行的方法。一、概述随着近年来智能化设
千家信息网最后更新 2026年11月03日基于 RT-Thread 的“数码小精灵”设计与实现是怎样的

基于 RT-Thread 的"数码小精灵"设计与实现是怎样的,针对这个问题,这篇文章详细介绍了相对应的分析和解答,希望可以帮助更多想解决这个问题的小伙伴找到更简单易行的方法。

一、概述

随着近年来智能化设备的不断增长,平板电脑、智能数字音视频播放器、移动数码相机等各类数码产品,正越来越受到城乡居民欢迎。特别是"云生活"让人们对数码产品有了更多需求,加上互联网技术、5G 技术、智能化新产品、新型分期消费模式等的出现,让数码产品消费热潮涌动。

本设计为基于 RT-Thread 的"数码小精灵"设计,硬件采用了以 BK7252 为主控芯片的麻雀一号开发板开发。BK7252 , 是一款高性能 WiFi 模块,采用高集成的无线射频芯片,内部集成 2.4GHz Wi-Fi 1T1R 先进技术,支持摄像头图像输出,拥有最佳的功耗性能、射频性能、稳定性、通用性和可靠性,适用于各种应用和不同产品需求。模块内部拥有 512KB 内嵌 RAM 和 4Mbyte Flash 空间,CPU 主频高达 180Mhz。



本设计在此基础上主要实现了以下功能,包括天气和疫情数据更新显示、MP3 音乐播放器以及数码拍照相机的功能。其中 MP3 播放器具有音量调节,播放/停止控制和歌曲切换的功能;数码相机将拍照图片进行 LCD 屏显示,同 时具有 SD 卡存储和 OneNet 云平台存储功能。该产品可以充当家庭数码助理的角色,因此取名"数码小精灵"。同时本作品完成的过程中参考了部分网络资料和网友的思路,在此一并表示感谢。

二、RT-Thread 使用情况概述

本设计基于麻雀一号开发板 SDK 进行开发,其 RT-Thread 为 3.1.0 版本。

图 1 RT-Thread 版本


在 RT-Thread 系统上的设备注册列表,其中主要使用了 rtc,sd0,w0,sound,uart1 等设备。使用到的 RT-Thread 组件包括了 FinSH 控制台,虚拟文件系统,POSIX 接口。在软件包上面涉及到网络工具及 NetUtils,WebClient,cJSON,EasyFlash,rt_ota,TJpgDec,Player 等。


图2设备注册列表

三、硬件框架



麻雀一号开发板外设资源丰富,但资源相当丰富,集成 WiFi、BLE、摄像头、音频扬声器、MIC 录音、TF 卡座、五向按键、还有一个 1.44 寸的 LCD 屏,使用常见的 TypeC 接口作为供电和调试串口,预留支持锂电池供电接口。


本设计的人机交互部分主要利用了开发板的五向按键和 LCD 显示屏,其中按键用于功能选择,数据刷新以及音乐播放控制功能。


普通模式下:" ←": 音乐播放 、"⭕":天气和疫情数据刷新 、 "→":相机拍照

音乐播放模式下:"↑":音量加 、"↓":音量减 、"←":下一曲 、"⭕":停止播放


设备联网采用 WIFI 连接,上电自动连接网络。数据显示 LCD 进行显示,同时设备接有 SD 进行相机拍照的存储。此外照片同时可以通过 WIFI 上传至OneNet 云平台,进行远端网页或者手机等智能终端进行查看。

四、软件框架说明


系统软件流程框图如下图所示,设备上电后启动 RT-Thread 操作系统,同 时进行相关硬件设备的初始化操作,如 LCD 显示屏,音频扬声器,以及挂在SD 卡到文件系统等操作,之后进行设备的网络连接。网络连接后输入应用程序启动命令进行程序启动,LCD 显示欢迎界面,接下来用户可以通过五向按键进 行功能选择,主要是天气疫情数据更新显示、MP3 播放器功能以及数码相机的功能。相机拍照后会进行本地 SD 卡数据存储以及 OneNet 云端存储。



五、软件模块说明


1. 设备联网

设备联网主要使用到了 RT-Thread 组件中的 wlan 驱动程序实现,上电初始化完成后在主程序中查询 wlan 无线设备,并根据用户配置的 SSID 和PASSWORD 进行 WIFI 网络的连接。该部分的具体代码实现如下所示:

 1static int iot_station_connect(char *ssid, char *passwd) {
2rt_err_t result = RT_EOK;
3struct rt_wlan_info info;
4struct rt_wlan_device *wlan;
5rt_tick_t tick = 0;
6wlan = (struct rt_wlan_device *)rt_device_find(WIFI_DEVICE_STA
7_NAME);
8if (!wlan)
9{
10rt_kprintf("no wlan:%s device\n", WIFI_DEVICE_STA_NAME);
11return -1; }
12result = rt_wlan_init(wlan, WIFI_STATION);
13rt_wlan_register_event_handler(wlan, WIFI_EVT_STA_CONNECTED, i
14ot_wlan_sta_connected_event);
15rt_wlan_register_event_handler(wlan, WIFI_EVT_STA_DISCONNECTED
16, iot_wlan_sta_disconnected_event);
17rt_wlan_info_init(&info, WIFI_STATION, SECURITY_WPA2_AES_PSK,
18ssid);
19result = rt_wlan_connect(wlan, &info, passwd);
20rt_wlan_info_deinit(&info);
21return result;
22}


2. NTP 网络时间同步

网络时间同步主要思路就是通过调用网络工具包中的 ntp 同步函数来实现,通过创建独立时间同步线程,达到定时同步网络时间的目的。该部分使用时需要启用 RT-Thread 中的 RTC 功能。相关代码如下:
 1{
2time_t cur_time = ntp_sync_to_rtc();
3if (cur_time)
4{
5rt_kprintf("Get local time from NTP server: %s", ctime((const t
6ime_t*) &cur_time));
7rt_kprintf("The system time is updated. Timezone is %d.\n", NTP
8_TIMEZONE);
9} }
10static rt_thread_t tid1 = RT_NULL;
11static void ntcthread1_entry(void * parameter) {
12while ((1))
13{
14time_t cur_time = ntp_sync_to_rtc();
15if (cur_time)
16{
17rt_kprintf("Get local time from NTP server: %s", ctime((const tim
18e_t *) &cur_time));
19rt_kprintf("The system time is updated. Timezone is %d.\n", NTP_T
20IMEZONE);
21break; }
22else
23{
24rt_thread_mdelay(1000);
25} } }
26void NTCThreadInit(void) {
27if (tid1 != RT_NULL)
28{
29rt_kprintf("ntc thread still run\n");
30return; }
31rt_kprintf("NTC thread init\n");
32tid1 = rt_thread_create("NTC",
33ntcthread1_entry, RT_NULL,
34THREAD_STACK_SIZE,
35THREAD_PRIORITY, THREAD_TIMESLICE);
36if (tid1 != RT_NULL)
37rt_thread_startup(tid1);
38}

3. 天气疫情数据更新

该部分主要是利用了 webclient 工具包的功能,通过调用天气和疫情数据API 接口获取相关 Json 数据,并利用 CJson 工具包进行返回 Json 数据的解析。最后通过 LCD 进行数据显示。相关代码如下:

  1#define GET_URI "http://www.weather.com.cn/data/sk/%s.html" //
2获取天气的 API
3#define GET_FY2020_URI "http://www.dzyong.top:3005/yiqing/total" //疫情
4数据 API
5void get_weather(int argc, char **argv) {
6rt_uint8_t *buffer = RT_NULL;
7int resp_status;
8struct webclient_session *session = RT_NULL;
9char *weather_url = RT_NULL;
10int content_length = -1, bytes_read = 0;
11int content_pos = 0;
12char *city_name = rt_calloc(1,255);
13/* 为 weather_url 分配空间 */
14weather_url = rt_calloc(1, GET_URL_LEN_MAX);
15if (weather_url == RT_NULL)
16{
17rt_kprintf("No memory for weather_url!\n");
18goto __exit;
19}
20if(argc == 1) {
21strcpy(city_name, AREA_ID);
22}
23else if (argc == 2) {
24strcpy(city_name, argv[1]);
25}
26/* 拼接 GET 网址 */
27rt_snprintf(weather_url, GET_URL_LEN_MAX, GET_URI, city_name);
28/* 创建会话并且设置响应的大小 */
29session = webclient_session_create(GET_HEADER_BUFSZ);
30if (session == RT_NULL)
31{
32rt_kprintf("No memory for get header!\n");
33goto __exit;
34}
35/* 发送 GET 请求使用默认的头部 */
36if ((resp_status = webclient_get(session, weather_url)) != 200) {
37rt_kprintf("webclient GET request failed, response(%d) error.\n", resp_
38status);
39goto __exit;
40}
41/* 分配用于存放接收数据的缓冲 */
42buffer = rt_calloc(1, GET_RESP_BUFSZ);
43if (buffer == RT_NULL)
44{
45rt_kprintf("No memory for data receive buffer!\n");
46goto __exit;
47}
48content_length = webclient_content_length_get(session);
49if (content_length < 0) {
50/* 返回的数据是分块传输的. */
51do
52{
53bytes_read = webclient_read(session, buffer, GET_RESP_BUFSZ);
54if (bytes_read <= 0) {
55break; } }while (1); }
56else
57{
58do
59{
60bytes_read = webclient_read(session, buffer,
61content_length - content_pos > GET_RESP
62_BUFSZ ?
63GET_RESP_BUFSZ : content_length - conte
64nt_pos);
65if (bytes_read <= 0) {
66break; }
67content_pos += bytes_read;
68}while (content_pos < content_length);
69}
70/* 天气数据解析 */
71weather_data_parse(buffer);
72__exit:
73/* 释放网址空间 */
74if (weather_url != RT_NULL)
75rt_free(weather_url);
76/* 关闭会话 */
77if (session != RT_NULL)
78webclient_close(session);
79/* 释放缓冲区空间 */
80if (buffer != RT_NULL)
81rt_free(buffer);
82if(city_name != RT_NULL)
83rt_free(city_name);
84}
85/* 天气数据解析 */
86void weather_data_parse(rt_uint8_t *data) {
87uint8_t temp[100];
88cJSON *root = RT_NULL, *object = RT_NULL, *item = RT_NULL;
89root = cJSON_Parse((const char *)data);
90if (!root)
91{
92rt_kprintf("No memory for cJSON root!\n");
93return; }
94object = cJSON_GetObjectItem(root, "weatherinfo");
95item = cJSON_GetObjectItem(object, "city");
96rt_kprintf("\ncity :%s ", item->valuestring);
97lcd_clear(BLACK);
98item = cJSON_GetObjectItem(object, "temp");
99rt_kprintf("\ntemp :%s ", item->valuestring);
100rt_sprintf(temp,"温度: %s",item->valuestring);
101lcd_disp_str_en_ch(0,20,temp,BLACK,WHITE);
102item = cJSON_GetObjectItem(object, "WD");
103rt_kprintf("\nwd :%s ", item->valuestring);
104item = cJSON_GetObjectItem(object, "WS");
105rt_kprintf("\nws :%s ", item->valuestring);
106item = cJSON_GetObjectItem(object, "SD");
107rt_kprintf("\nsd :%s ", item->valuestring);
108rt_sprintf(temp,"湿度: %s",item->valuestring);
109lcd_disp_str_en_ch(0,40,temp,BLACK,WHITE);
110item = cJSON_GetObjectItem(object, "time");
111rt_kprintf("\ntime :%s \n", item->valuestring);
112item = cJSON_GetObjectItem(object, "AP");
113rt_kprintf("\nap :%s ", item->valuestring);
114rt_sprintf(temp,"气压: %s",item->valuestring);
115lcd_disp_str_en_ch(0,60,temp,BLACK,WHITE);
116item = cJSON_GetObjectItem(object, "WSE");
117rt_kprintf("\nwse :%s ", item->valuestring);
118rt_sprintf(temp,"风力: %s",item->valuestring);
119lcd_disp_str_en_ch(0,80,temp,BLACK,WHITE);
120if (root != RT_NULL)
121cJSON_Delete(root);
122}
123/* 疫情数据解析 */
124void fy2020_data_parse(rt_uint8_t *data) {
125uint8_t temp[100];
126cJSON *root = RT_NULL, *object = RT_NULL, *item = RT_NULL;
127root = cJSON_Parse((const char *)data);
128if (!root)
129{
130rt_kprintf("No memory for cJSON root!\n");
131return; }
1324. 音乐播放模块
133该部分的功能主要通过使用 player 软件包的接口函数实现,包括音乐播
134放,停止,歌曲切换以及音量控制等功能。该部分的部分代码如下图所示:
135cJSON *dataArray = cJSON_GetObjectItem(root,"data"); //取数组
136int arraySize = cJSON_GetArraySize(dataArray); //取数组大小
137cJSON *dataList = dataArray->child;
138while(dataList != RT_NULL)
139{
140rt_kprintf("\ndiagnosed :%d \n", cJSON_GetObjectItem(dataList,"diagn
141osed")->valueint);
142rt_kprintf("\ndeath :%d \n", cJSON_GetObjectItem(dataList,"death")->
143valueint);
144rt_kprintf("\ncured :%d \n", cJSON_GetObjectItem(dataList,"cured")->
145valueint);
146rt_kprintf("\ndate :%s \n", cJSON_GetObjectItem(dataList,"date")->va
147luestring);
148//LCD 屏打印信息
149rt_sprintf(temp,"累计确
150诊: %d",cJSON_GetObjectItem(dataList,"diagnosed")->valueint);
151lcd_disp_str_en_ch(0,120,temp,BLACK,WHITE);
152rt_sprintf(temp,"累计死
153亡: %d",cJSON_GetObjectItem(dataList,"death")->valueint);
154lcd_disp_str_en_ch(0,140,temp,BLACK,WHITE);
155rt_sprintf(temp,"累计治
156愈: %d",cJSON_GetObjectItem(dataList,"cured")->valueint);
157lcd_disp_str_en_ch(0,160,temp,BLACK,WHITE);
158rt_sprintf(temp,"更新时
159间: %s",cJSON_GetObjectItem(dataList,"date")->valuestring);
160lcd_disp_str_en_ch(0,180,temp,BLACK,WHITE);
161dataList = dataList->next;
162}


4. 音乐播放模块

该部分的功能主要通过使用 player 软件包的接口函数实现,包括音乐播放,停止,歌曲切换以及音量控制等功能。该部分的部分代码如下图所示:
 1LCDShowMusic();
2rt_sprintf(music,"/sd/music/%d.mp3",count);
3rt_kprintf(" key left is press ...\r\n");
4rt_kprintf("//////////////////////////// player_play \n");
5player_stop();
6player_set_uri(music);
7player_play();
8player_status = 1;
9count++;
10if(count >= 8)
11count = 0;
12rt_kprintf("//////////////////////////// player_play end \n");

5. 相机功能实现

该部分主要通过 IPC 事件获取相机采集图像数据,并将采集到的图像数据经过 TJpgDec 软件包进行解码后在 LCD 进行显示,同时会将相机数据通过写文件的形式存储到 SD 卡,通过 HTTP 协议推送到 OneNet 云平台。

 1void take_photo(void) //手动拍照
2{
3//创建摄像头接收一帧图片的事件
4session.event = rt_event_create("vt_event", RT_IPC_FLAG_FIFO);
5camera_start(); //开启摄像头传输照片
6tvideo_capture(1);
7rt_event_recv(session.event, SEND_FRAME_EVENT, RT_EVENT_FLAG_OR | RT_EVE
8NT_FLAG_CLEAR, RT_WAITING_FOREVER, RT_NULL);
9int fd, res;
10time_t cur_time;
11struct tm *cur_tm;
12char time_now[50]; //保存文件到 sd 卡指定路径
13/* output current time */
14cur_time = time(RT_NULL);
15cur_tm = localtime(&cur_time);
16rt_sprintf(time_now, "d-d-d-d-d-d",cur_tm->tm_year + 19
1700, cur_tm->tm_mon + 1, cur_tm->tm_mday, cur_tm->tm_hour, cur_tm->tm_min, cur
18_tm->tm_sec);
19rt_sprintf(file_name, "/sd/images/%s.jpg", time_now);
20rt_kprintf("name = %s \n", file_name);
21fd = open(file_name, O_WRONLY | O_CREAT);
22if (fd >= 0) {
23write(fd, session.buf, session.total_len);
24close(fd);
25rt_kprintf("save %s ok!!!\n", file_name);
26res = Decode_Jpg(file_name);
27rt_kprintf("res = %d\n", res);
28}
29else
30{
31rt_kprintf("save pic failed!!!\n");
32}
33//拍照数据上传
34webclient_post_pic(session.buf, session.total_len);
35tvideo_capture(0);
36}
37MSH_CMD_EXPORT(take_photo,take_photo);

关于基于 RT-Thread 的"数码小精灵"设计与实现是怎样的问题的解答就分享到这里了,希望以上内容可以对大家有一定的帮助,如果你还有很多疑惑没有解开,可以关注行业资讯频道了解更多相关知识。

数据 功能 数码 设备 部分 相机 网络 天气 音乐 设计 疫情 软件 接口 存储 开发 产品 代码 模块 系统 音量 数据库的安全要保护哪些东西 数据库安全各自的含义是什么 生产安全数据库录入 数据库的安全性及管理 数据库安全策略包含哪些 海淀数据库安全审计系统 建立农村房屋安全信息数据库 易用的数据库客户端支持安全管理 连接数据库失败ssl安全错误 数据库的锁怎样保障安全 瑰夏咖啡 伟宏互联网科技 与互联网科技公司 小马过河互联网科技 互联网金融科技平台 左右互联网络科技 互联网科技公司的市场部门 江苏南京365互联网科技 新华互联网科技2019 银川新华互联网科技职业技术培训学校图片 互联网时代科技改变生活 福建科技产业互联网发展 青海科技产业互联网发展 民营互联网公司国防科技 山东子淼互联网科技有限公司 新氧科技和美国互联网有关系吗 宁波跨境商互联网科技有限公司 互联网金融运营模式中的金融科技 科技互联网经济论坛 互联网科技创业有什么好项目 中资互联网科技 西安互联网科技 致骋互联网科技 撒么互联网科技公司 温州喔噻互联网科技有限公司 互联网科技创新服务 受益于互联网科技的高速发展 链环科技传统企业怎么转型互联网 易企秀互联网科技是做什么的 保山浩联互联网科技有限公司
0