static const struct i2c_device_id ap3216c_id[] = {
{“alientek,ap3216c”, 0},
{}
};
/* 设备树匹配列表 /
static const struct of_device_id ap3216c_of_match[] = {
{ .compatible = “alientek,ap3216c” }, / 需要和设备树下的保持一致 /
{ / Sentinel */ }
};
/* i2c驱动结构体 /
static struct i2c_driver ap3216c_driver = {
.probe = ap3216c_probe,
.remove = ap3216c_remove,
.driver = { / 设备树的匹配方法 /
.owner = THIS_MODULE,
.name = “ap3216c”,
.of_match_table = ap3216c_of_match,
},
.id_table = ap3216c_id, / 传统驱动匹配方法 */
};
/*
-
@description : 驱动入口函数
-
@param : 无
-
@return : 无
*/
static int __init ap3216c_init(void)
{
int ret = 0;ret = i2c_add_driver(&ap3216c_driver);
return ret;
}
/*
- @description : 驱动出口函数
- @param : 无
- @return : 无
*/
static void __exit ap3216c_exit(void)
{
i2c_del_driver(&ap3216c_driver);
}
/* module_i2c_driver(ap3216c_driver) */
module_init(ap3216c_init);
module_exit(ap3216c_exit);
MODULE_LICENSE(“GPL”);
MODULE_AUTHOR(“sneak”);
>
> 驱动详解可查阅注释及配合上诉的I2C驱动框架的框图及数据手册理解
>
>
>
我们通过 在终端输入 **cat** 指令可以读取到传感器的数值变量,如下图:
![](https://img-blog.csdnimg.cn/498281554dce4b21a70d0ecd2d9245af.png)
## 三、AP3216C的QT程序设计
>
> IMX6ULL 的 QT-UI 的部署与实现需要依赖 QT 的很多依赖包,各位读者可以根据实际情况进行移植。或者直接使用正点原子提供的系统镜像!
>
>
>
### 3.1 Chart表制作
**Qt Charts** 很方便的绘制我们常见的**曲线图**、**折线图**、**柱状图**和**饼状图**等图表。不用自己花精力去了解第三方组件的使用了或者开发第三方组件。**Qt** 的帮助文档里已经有说明 **Qt Charts** 主要部件的使用方法。需要用到时我们可以查看 **Qt** 文档就可以了。
本项目中我们需要使用**曲线图**去展示 **AP3216C** 的 **ALS** 光强度属性。
>
> 使用一个 **QSplineSeries** 对象(曲线),一个 **QChart**(图表),一个 **QChartView**(图表视图)。首先我们创建坐 **chart** 图表,然后创建两条坐标轴 **axisX** 与 **axisY**。将两条坐标轴添加到 **chart** 图表上,再将 **splineSeries** 曲线与坐标轴连系起来。最后再将 **chart** 图表添加到 **chartView** 图表视图中。曲线上的数据由系统产生随机数,使用定时器更新数据。
>
>
>
**qtchart.pro:**
QT += core gui charts
greaterThan(QT_MAJOR_VERSION, 4): QT += widgets
CONFIG += c++11
The following define makes your compiler emit warnings if you use
any Qt feature that has been marked deprecated (the exact warnings
depend on your compiler). Please consult the documentation of the
deprecated API in order to know how to port your code away from it.
DEFINES += QT_DEPRECATED_WARNINGS
You can also make your code fail to compile if it uses deprecated APIs.
In order to do so, uncomment the following line.
You can also select to disable deprecated APIs only up to a certain version of Qt.
#DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000 # disables all the APIs deprecated before Qt 6.0.0
SOURCES +=
main.cpp
mainwindow.cpp
HEADERS +=
mainwindow.h
FORMS +=
mainwindow.ui
Default rules for deployment.
qnx: target.path = /tmp/
T
A
R
G
E
T
/
b
i
n
e
l
s
e
:
u
n
i
x
:
!
a
n
d
r
o
i
d
:
t
a
r
g
e
t
.
p
a
t
h
=
/
o
p
t
/
{TARGET}/bin else: unix:!android: target.path = /opt/
TARGET/binelse:unix:!android:target.path=/opt/{TARGET}/bin
!isEmpty(target.path): INSTALLS += target
**mainwindow.h:**
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include
#include
#include
#include
#include
#include
#include
/* 必需添加命名空间 */
QT_CHARTS_USE_NAMESPACE
class MainWindow : public QMainWindow
{
Q_OBJECT
public:
MainWindow(QWidget *parent = nullptr);
~MainWindow();
private:
/* 接收数据接口 */
void receivedData(int);
/* 数据最大个数 */
int maxSize;
/* x轴上的最大值 */
int maxX;
/* y轴上的最大值 */
int maxY;
/* y轴 */
QValueAxis *axisY;
/* x轴 */
QValueAxis *axisX;
/* QList int类型容器 */
QList<int> data;
/* QSplineSeries对象(曲线)*/
QSplineSeries *splineSeries;
/* QChart图表 */
QChart *chart;
/* 图表视图 */
QChartView *chartView;
/* 定时器 */
QTimer *timer;
private slots:
void timerTimeOut();
};
#endif // MAINWINDOW_H
**mainwindow.c:**
#include “mainwindow.h”
#include
MainWindow::MainWindow(QWidget parent)
: QMainWindow(parent)
{
/ 设置最显示位置与大小 /
this->setGeometry(0, 0, 800, 480);
/ 最大储存maxSize - 1个数据 /
maxSize = 51;
/ x轴上的最大值 /
maxX = 5000;
/ y轴最大值 */
maxY = 40;
/* splineSeries曲线实例化(折线用QLineSeries) */
splineSeries = new QSplineSeries();
/* 图表实例化 */
chart = new QChart();
/* 图表视图实例化 */
chartView = new QChartView();
/* 坐标轴 */
axisY = new QValueAxis();
axisX = new QValueAxis();
/* 定时器 */
timer = new QTimer(this);
/* legend译图例类型,以绘图的颜色区分,本例设置为隐藏 */
chart->legend()->hide();
/* chart设置标题 */
chart->setTitle("实时动态曲线示例");
/* 添加一条曲线splineSeries */
chart->addSeries(splineSeries);
/* 设置显示格式 */
axisY->setLabelFormat("%i");
/* y轴标题 */
axisY->setTitleText("温度/℃");
/* y轴标题位置(设置坐标轴的方向) */
chart->addAxis(axisY, Qt::AlignLeft);
/* 设置y轴范围 */
axisY->setRange(0, maxY);
/* 将splineSeries附加于y轴上 */
splineSeries->attachAxis(axisY);
/* 设置显示格式 */
axisX->setLabelFormat("%i");
/* x轴标题 */
axisX->setTitleText("时间/ms");
/* x轴标题位置(设置坐标轴的方向) */
chart->addAxis(axisX, Qt::AlignBottom);
/* 设置x轴范围 */
axisX->setRange(0, maxX);
/* 将splineSeries附加于x轴上 */
splineSeries->attachAxis(axisX);
/* 将图表的内容设置在图表视图上 */
chartView->setChart(chart);
/* 设置抗锯齿 */
chartView->setRenderHint(QPainter::Antialiasing);
/* 设置为图表视图为中心部件 */
setCentralWidget(chartView);
/* 定时200ms */
timer->start(200);
/* 信号槽连接 */
connect(timer, SIGNAL(timeout()), this, SLOT(timerTimeOut()));
/* 设置随机种子,随机数初始化 */
qsrand(time(NULL));
}
MainWindow::~MainWindow()
{
}
void MainWindow::timerTimeOut()
{
/* 产生随机0~maxY之间的数据 */
receivedData(qrand() % maxY );
}
void MainWindow::receivedData(int value)
{
/* 将数据添加到data中 */
data.append(value);
/* 当储存数据的个数大于最大值时,把第一个数据删除 */
while (data.size() > maxSize) {
/* 移除data中第一个数据 */
data.removeFirst();
}
/* 先清空 */
splineSeries->clear();
/* 计算x轴上的点与点之间显示的间距 */
int xSpace = maxX / (maxSize - 1);
/* 添加点,xSpace * i 表示第i个点的x轴的位置 */
for (int i = 0; i < data.size(); ++i) {
splineSeries->append(xSpace * i, data.at(i));
}
}
**QT Chart表效果:**
![](https://img-blog.csdnimg.cn/cb074415b3344b1194a4132bde00c998.png)
### 3.2 AP3216C的数据读取
我们编写 QT 下的 AP3216C 的应用代码:
**ap3216c.h:**
#ifndef AP3216C_H
#define AP3216C_H
#include
#include
class Ap3216c : public QObject
{
Q_OBJECT
public:
explicit Ap3216c(QObject *parent = 0); //构造函数声明,"explicit"是一个C++关键字,用于修饰构造函数或函数,以禁止隐式转换
~Ap3216c(); //析构函数
Q_INVOKABLE void setCapture(bool str); //Q_INVOKABLE是一个宏,setCapture函数接受一个bool类型的参数str,用于设置某个对象的捕获状态
QString alsData(); //光强传感器( ALS: Ambient Light Sensor)
QString psData(); //接近传感器( PS: Proximity Sensor)
QString irData(); //红外 LED( IR LED)
private:
QTimer *timer; //定时器timer
QString alsdata; //光强数据
QString psdata; //接近数据
QString irdata; //红外数据
QString readAlsData(); //读取Ais数据
QString readPsData(); //读取Ps数据
QString readIrData(); //读取IR数据
Q_PROPERTY(QString alsData READ alsData NOTIFY ap3216cDataChanged)
Q_PROPERTY(QString psData READ psData NOTIFY ap3216cDataChanged)
Q_PROPERTY(QString irData READ irData NOTIFY ap3216cDataChanged)
/*Q_PROPERTY:这是一个宏,用于在类中声明属性。
*QString:alsData是属性的类型,这里是一个QString类型的变量。
*READ alsData:这表示该属性可以通过"alsData"方法进行读取。
*NOTIFY ap3216cDataChanged:这表示当该属性发生变化时,会发出"ap3216cDataChanged"信号
*/
public slots:
void timer_timeout();
signals:
void ap3216cDataChanged();
};
#endif // AP3216C_H
**ap3216c.c:**
#include “ap3216c.h”
#include <stdio.h>
#include <string.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include
/* AP3216C的构造函数 */
Ap3216c::Ap3216c(QObject *parent) : QObject (parent)
{
timer = new QTimer(); //定义一个定时器容器
connect(timer, SIGNAL(timeout()),this,SLOT(timer_timeout())); //将超时信号,与timer_timeout链接起来
}
/* 析构函数 */
Ap3216c::~Ap3216c()
{
}
/* 超时函数 */
void Ap3216c::timer_timeout()
{
alsdata = readAlsData();
psdata = readPsData();
irdata = readIrData();
emit ap3216cDataChanged(); //发送ap3216c数值变化信息
}
QString Ap3216c::readIrData()
{
char const *filename = “/sys/class/misc/ap3216c/ir”;
int err = 0;
int fd;
char buf[10];
fd = open(filename,O_RDONLY); //只读模式打开文件
if(fd < 0){
close(fd);
return "open file error!";
}
err = read(fd,buf,sizeof(buf));
if(err < 0){
close(fd);
return "read data error!";
}
close(fd);
QString irValue = buf;
QStringList list = irValue.split("\n"); //将irValue按照换行符"\n"分割成一个字符串列表,并将结果存储在list对象中
return list[0];
}
QString Ap3216c::readPsData()
{
char const *filename = “/sys/class/misc/ap3216c/ps”;
int err = 0;
int fd;
char buf[10];
fd = open(filename,O_RDONLY); //只读模式打开文件
if(fd < 0){
close(fd);
return "open file error!";
}
err = read(fd,buf,sizeof(buf));
if(err < 0){
close(fd);
return "read data error!";
}
close(fd);
QString irValue = buf;
QStringList list = irValue.split("\n"); //将irValue按照换行符"\n"分割成一个字符串列表,并将结果存储在list对象中
return list[0];
}
QString Ap3216c::readAlsData()
{
char const *filename = “/sys/class/misc/ap3216c/als”;
int err = 0;
int fd;
char buf[10];
fd = open(filename,O_RDONLY); //只读模式打开文件
if(fd < 0){
close(fd);
return "open file error!";
}
err = read(fd,buf,sizeof(buf));
if(err < 0){
close(fd);
return "read data error!";
}
close(fd);
QString irValue = buf;
QStringList list = irValue.split("\n"); //将irValue按照换行符"\n"分割成一个字符串列表,并将结果存储在list对象中
return list[0];
}
QString Ap3216c::alsData()
{
return alsdata;
}
QString Ap3216c::irData()
{
return irdata;
}
QString Ap3216c::psData()
{
return psdata;
}
void Ap3216c::setCapture(bool str)
{
if(str)
timer->start(500);
else
timer->stop();
}
>
> **“Linux 系统之下一切皆文件”**,上述代码就是通过 C 语言库函数去读取系统下的属性数值信息来做到获取 AP3216C 的数据值!
>
>
>
![](https://img-blog.csdnimg.cn/6cea936ff2cc4f418518b67e61809145.png)
### 3.3 AP3216C与Chart联动
>
> 我们将 **AP3216C** 与 **Chart** 进行联动配合,通过 **Chart** 实时读取显示 **AP3216C** 的 **ALS** 属性。
>
>
>
**mainwindow.h:**
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include “ap3216c.h”
/* 必需添加命名空间 */
QT_CHARTS_USE_NAMESPACE
class MainWindow : public QMainWindow
{
Q_OBJECT
public:
MainWindow(QWidget *parent = nullptr);
~MainWindow();
private:
/* 主容器,Widget也可以当作一种容器 */
QWidget *mainWidget;
/* 界面水平区域布局 */
QHBoxLayout *hboxLayout[2];
/* 界面右侧区域布局 */
QVBoxLayout *vboxLayout[4];
/* 界面右侧区域容器 */
QWidget *rightWidget;
/* 用一个 QLabel 对象用于显示字符串 */
QLabel *labelString;
/* 容器作用,用于布局 */
QWidget *widget[5];
/* 标签文本 */
QLabel *label[3];
/* 数据标签 */
QLabel *my_label[3];
/* 数据最大个数 */
int maxSize;
/* x轴上的最大值 */
int maxX;
/* y轴上的最大值 */
int maxY;
/* y轴 */
QValueAxis *axisY;
/* x轴 */
QValueAxis *axisX;
/* QList int类型容器 */
QList<int> data;
/* QSplineSeries对象(曲线)*/
QSplineSeries *splineSeries;
/* QChart图表 */
QChart *chart;
/* 图表视图 */
QChartView *chartView;
/* ii2传感器类 */
Ap3216c *ap3216c;
/* 接收数据接口 */
void receivedData(int);
/* 布局初始化 */
void layoutInit();
private slots:
/* 获取ap3216传感器数据 */
void getAp3216cData();
};
#endif // MAINWINDOW_H
**mainwindow.c:**
#include “mainwindow.h”
#include “ui_mainwindow.h”
#include
#include
#include
-
MainWindow::MainWindow(QWidget *parent)
-
QMainWindow(parent)
{
/* 布局初始化 */
layoutInit();
}
MainWindow::~MainWindow()
{
}
/* 布局初始化 /
void MainWindow::layoutInit()
{
/ 获取屏幕的分辨率,Qt官方建议使用这
* 种方法获取屏幕分辨率,防上多屏设备导致对应不上
* 注意,这是获取整个桌面系统的分辨率
*/
QList <QScreen *> list_screen = QGuiApplication::screens();
/* 如果是ARM平台,直接设置大小为屏幕的大小 */
#if arm
/* 重设大小 /
this->resize(list_screen.at(0)->geometry().width(),
list_screen.at(0)->geometry().height());
#else
/ 否则则设置主窗体大小为800x480 */
this->resize(800,400);
#endif
/* 实例化与布局,常规操作 */
mainWidget = new QWidget();
rightWidget = new QWidget();
for(int i = 0; i < 2; i++) //水平布局
hboxLayout[i] = new QHBoxLayout();
for(int i = 0; i < 5; i++) //容器布局
widget[i] = new QWidget();
for(int i = 0; i < 4; i++) //垂直布局
vboxLayout[i] = new QVBoxLayout();
for(int i = 0; i < 3; i++) //数据变量
my_label[i] = new QLabel();
/********************** chart表格 ****************************/
/ 最大储存maxSize - 1个数据 /
maxSize = 51;
/ x轴上的最大值 /
maxX = 5000;
/ y轴最大值 */
maxY = 40;
/* splineSeries曲线实例化(折线用QLineSeries) */
splineSeries = new QSplineSeries();
/* 图表实例化 */
chart = new QChart();
/* 图表视图实例化 */
chartView = new QChartView();
/* 坐标轴 */
axisY = new QValueAxis();
axisX = new QValueAxis();
/* legend译图例类型,以绘图的颜色区分,本例设置为隐藏 */
chart->legend()->hide();
/* chart设置标题 */
chart->setTitle("环境光强度");
/* 添加一条曲线splineSeries */
chart->addSeries(splineSeries);
/* 设置显示格式 */
axisY->setLabelFormat("%i");
/* y轴标题 */
axisY->setTitleText("光通亮/Lux");
/* y轴标题位置(设置坐标轴的方向) */
chart->addAxis(axisY, Qt::AlignLeft);
/* 设置y轴范围 */
axisY->setRange(0, maxY);
/* 将splineSeries附加于y轴上 */
splineSeries->attachAxis(axisY);
/* 设置显示格式 */
axisX->setLabelFormat("%i");
/* x轴标题 */
axisX->setTitleText("时间/ms");
/* x轴标题位置(设置坐标轴的方向) */
chart->addAxis(axisX, Qt::AlignBottom);
/* 设置x轴范围 */
axisX->setRange(0, maxX);
/* 将splineSeries附加于x轴上 */
splineSeries->attachAxis(axisX);
/* 将图表的内容设置在图表视图上 */
chartView->setChart(chart);
/* 设置抗锯齿 */
chartView->setRenderHint(QPainter::Antialiasing);
/********************** chart表格 *****************************/
/* 设置传感器数据标签 */
QFont font;
font.setPixelSize(18);
QPalette pal;
pal.setColor(QPalette::WindowText, Qt::black);
QStringList list;
list<<"环境光强度:"<<"接近距离:"<<"红外强度:";
for (int i = 0; i < 3; i++) {
label[i] = new QLabel();
label[i]->setText(list[i]);
label[i]->setFont(font);
label[i]->setPalette(pal);
label[i]->adjustSize();
}
/* 垂直容器布局 */
vboxLayout[3]->addWidget(widget[0]);
vboxLayout[3]->addWidget(widget[1]);
vboxLayout[3]->addWidget(widget[2]);
hboxLayout[0]->addWidget(chartView); //将chart表格添加到水平布局中
widget[3]->setLayout(hboxLayout[0]);
widget[4]->setLayout(vboxLayout[3]);
hboxLayout[1]->addWidget(widget[3]);
hboxLayout[1]->addWidget(widget[4]);
mainWidget->setLayout(hboxLayout[1]);
this->setCentralWidget(mainWidget);
/* als布局 */
vboxLayout[0]->addWidget(label[0]);
vboxLayout[0]->addWidget(my_label[0]);
vboxLayout[0]->setAlignment(Qt::AlignTop | Qt::AlignVCenter);
widget[0]->setLayout(vboxLayout[0]);
/* ps布局 */
vboxLayout[1]->addWidget(label[1]);
vboxLayout[1]->addWidget(my_label[1]);
vboxLayout[1]->setAlignment(Qt::AlignTop | Qt::AlignVCenter);
widget[1]->setLayout(vboxLayout[1]);
/* ir布局 */
vboxLayout[2]->addWidget(label[2]);
vboxLayout[2]->addWidget(my_label[2]);
vboxLayout[2]->setAlignment(Qt::AlignTop | Qt::AlignVCenter);
widget[2]->setLayout(vboxLayout[2]);
ap3216c = new Ap3216c(this);
/* 只能在开发板上开启获取数据,Ubuntu上是没有ap3216c传感器的 */
#if arm
ap3216c->setCapture(true);
#endif
connect(ap3216c,SIGNAL(ap3216cDataChanged()),this,SLOT(getAp3216cData()));
}
void MainWindow::getAp3216cData()
{
static QString als = ap3216c->alsData();
// if (als != ap3216c->alsData()) {
// als = ap3216c->alsData();
// }
als = ap3216c->alsData();
static QString ps = ap3216c->psData();
// if (ps != ap3216c->psData()) {
// ps = ap3216c->psData();
// }
ps = ap3216c->psData();
static QString ir = ap3216c->irData();
// if (ir != ap3216c->irData()) {
// ir = ap3216c->irData();
// }
ir = ap3216c->irData();
my_label[0]->setText(als);
my_label[1]->setText(ps);
my_label[2]->setText(ir);
/**************** chart表数据 ******************/
int num = als.toInt(); //字符串转int类型数据
/* 将数据添加到data中 */
data.append(num);
/* 当储存数据的个数大于最大值时,把第一个数据删除 */
while (data.size() > maxSize) {
/* 移除data中第一个数据 */
data.removeFirst();
}
/* 先清空 */
splineSeries->clear();
/* 计算x轴上的点与点之间显示的间距 */
int xSpace = maxX / (maxSize - 1);
/* 添加点,xSpace * i 表示第i个点的x轴的位置 */
for (int i = 0; i < data.size(); ++i) {
splineSeries->append(xSpace * i, data.at(i));
}
}
>
> **AP3216C** 与 **Chart** 联动的程序主要是进行 **QT** 的容器布局,通过**layoutInit()** 函数进行布局初始化(**UI设计部分**),之后通过定时 **timer** 去定时读取 **ap3216c** 的传感器数据,在读取 **ap3216c** 的数据之后,通过 **Chart** 进行绘制出来!
>
## 最后
**自我介绍一下,小编13年上海交大毕业,曾经在小公司待过,也去过华为、OPPO等大厂,18年进入阿里一直到现在。**
**深知大多数Java工程师,想要提升技能,往往是自己摸索成长,自己不成体系的自学效果低效漫长且无助。**
**因此收集整理了一份《2024年嵌入式&物联网开发全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友,同时减轻大家的负担。**
![img](https://img-blog.csdnimg.cn/img_convert/5de43561aa02fc0431a47b0e63102478.png)
![img](https://img-blog.csdnimg.cn/img_convert/d91c2ecb061cea70b2072c6008e92524.jpeg)
![img](https://img-blog.csdnimg.cn/img_convert/9ea3cd275bec869f6f3d948b7bed17dc.png)
![img](https://img-blog.csdnimg.cn/img_convert/870d45bd344f4dd724f271a53912d4d8.png)
![img](https://img-blog.csdnimg.cn/img_convert/ce2c8d102cf603732d41e622665d0677.png)
![img](https://img-blog.csdnimg.cn/img_convert/7bad42eece39d7e9fd05c639f751a12d.png)
![](https://img-blog.csdnimg.cn/img_convert/980f5b639ef9b7980c11f1f409fc6c6a.png)
**既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,基本涵盖了95%以上嵌入式&物联网开发知识点,真正体系化!**
[**如果你觉得这些内容对你有帮助,需要这份全套学习资料的朋友可以戳我获取!!**](https://bbs.csdn.net/topics/618654289)
**由于文件比较大,这里只是将部分目录大纲截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且后续会持续更新**!!
* 的容器布局,通过**layoutInit()** 函数进行布局初始化(**UI设计部分**),之后通过定时 **timer** 去定时读取 **ap3216c** 的传感器数据,在读取 **ap3216c** 的数据之后,通过 **Chart** 进行绘制出来!
>
## 最后
**自我介绍一下,小编13年上海交大毕业,曾经在小公司待过,也去过华为、OPPO等大厂,18年进入阿里一直到现在。**
**深知大多数Java工程师,想要提升技能,往往是自己摸索成长,自己不成体系的自学效果低效漫长且无助。**
**因此收集整理了一份《2024年嵌入式&物联网开发全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友,同时减轻大家的负担。**
[外链图片转存中...(img-JNDG1HgJ-1715682675090)]
[外链图片转存中...(img-sAU97Ux7-1715682675091)]
[外链图片转存中...(img-TRnmINqW-1715682675092)]
[外链图片转存中...(img-NG1Lz0DC-1715682675092)]
[外链图片转存中...(img-W2znPQea-1715682675093)]
[外链图片转存中...(img-JhAgUynR-1715682675093)]
[外链图片转存中...(img-RCZ0h4e0-1715682675094)]
**既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,基本涵盖了95%以上嵌入式&物联网开发知识点,真正体系化!**
[**如果你觉得这些内容对你有帮助,需要这份全套学习资料的朋友可以戳我获取!!**](https://bbs.csdn.net/topics/618654289)
**由于文件比较大,这里只是将部分目录大纲截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且后续会持续更新**!!