- 博客(141)
- 收藏
- 关注
原创 stm32学习笔记---SPI通信协议(理论部分)
SPI(Serial Peripheral Interface)是由Motorola公司开发的一种通用数据总线。四根通信线:SCK(Serial Clock串行时钟线)、MOSI(Master Output Slave Input主机输出从机输入,有些叫DI即data input)、MISO(Master Input Slave Output主机输入从机输出,有些叫DO即data output)、SS(Slave Select从机选择,有些叫NSS即not slave select或者CS即chip
2025-01-03 17:07:02
1261
2
原创 嵌入式全栈开发学习笔记---C++(STL)
STL概述STL(Standard Template Library,标准模板库)是惠普实验室开发的一系列软件的统称。现然主要出现在C++中,但在被引入C++之前该技术就已经存在了很长的一段时间。STL的从广义上讲分为三类:algorithm(算法)、container(容器)和iterator(迭代器),容器和算法通过迭代器可以进行无缝地连接。几乎所有的代码都采用了模板类和模板函数的方式,这相比于传统的由函数和类组成的库来说提供了更好的代码重用机会。在C++标准中,STL被组织为下面的13个头文 件
2024-09-06 09:42:31
2031
原创 嵌入式全栈开发学习笔记---C++(强制类型转换/异常和文件)
栈解旋异常被抛出后,从进入try块起,到异常被抛掷前,这期间在栈上的构造的所有对象,都会被自动析构。析构的顺序与构造的顺序相反。这一过程称为栈的解旋(unwinding)。比如我们在try块里面创建了一个对象,那么一旦有异常,这两块地方之间写的所有东西都会被释放。
2024-09-06 08:27:59
2004
原创 嵌入式全栈开发学习笔记---C++(函数/类模板)
函数模板C++提供了函数模板(function template)。所谓函数模板,实际上是建立一个通用函数,其函数类型和形参类型不具体指定,用一个虚拟的类型来代表。这个通用函数就称为函数模板。凡是函数体相同的函数都可以用这个模板来代替,不必定义多个函数,只需在模板中定义一次即可。在调用函数时系统会根据实参的类型来取代模板中的虚拟类型,从而实现了不同函数的功能。
2024-09-05 08:55:25
1561
原创 嵌入式全栈开发学习笔记---C++(运算符重载)
c1和c2都是复数Complex这个类的对象,为什么不支持相加?首先“+”两边只支持整型,如果写成double或者float,编译器会自己转换类型,但是这里结构体加结构体就不行了,因为它缺少相加的规则,不知道是用c1里面的m_b和c2里面的m_b相加还是用c1里面的m_a和c2里面的m_b相加,编译器不会乱来。因此我们必须指定规则(即运算符重载),重载加号运算符,让它支持两个结构体,也就是Complex类相加。运算符重载的本质就是函数重载,我们可以将这个加号重载成成员函数,也可以重载成全局函数。
2024-09-05 08:34:55
1865
原创 嵌入式全栈开发学习笔记---C++(多态)
多态成立的三个条件这就涉及到多态成立的三个条件:1、要有继承2、要有虚函数重写3、用父类指针(父类引用)指向子类对象
2024-09-04 09:31:56
1435
1
原创 嵌入式全栈开发学习笔记---C++(继承和派生)
继承的使用场景以下是两种典型的使用继承的场景:1、当你创建的新类与现有的类相似,只是多出若干成员变量或成员函数时,可以使用继承,这样不但会减少代码量,而且新类会拥有基类的所有功能。2、当你需要创建多个类,它们拥有很多相似的成员变量或成员函数时,也可以使用继承。可以将这些类的共同成员提取出来,定义为基类,然后从基类继承,既可以节省代码,也方便后续修改成员。
2024-09-04 08:54:41
1308
原创 嵌入式全栈开发学习笔记---C++(类和对象)
什么是面向对象?object-oriented面向将系统看成通过交互作用来完成特定功能的对象的集合,每个对象用自己的方法(这里的方法指的就是函数)来管理数据(这里的数据指的是结构体里面的成员)。也就是说只有对象内部的代码能够操作对象内部的数据(之前在C语言中我们是可以在结构体外操作成员的,但是在C++中是不可以的)。所谓对象,我们可以把它理解为变量,比如int a;这个a就是一个对象,对象就是实实在在的一个东西,如果更具体一点,它其实指的是结构体变量,而这个s1在内存中是要占内存的,所以它就是一个实实在
2024-09-03 10:02:14
2525
原创 嵌入式全栈开发学习笔记---C++开发概述
入门级问题为什么学习C++语言?大型应用软件开发中,程序员往往关注的是业务逻辑的实现,很少把精力放在一些细节的实现上(比如链表);求职中,C和C++难以分割,比如C/C++工程师,C的笔试题中也会有C++;C++在哪方面经常被应用?主要应用于嵌入式的图像界面(QT)、游戏和后台服务器,另外也能做一些桌面应用。
2024-09-03 09:21:19
2074
原创 嵌入式全栈开发学习笔记---shell脚本
shell脚本有什么用?Shell其实也是一门语言,在嵌入式开发里面经常会用到。在Linux中有很多操作命令,如果为了节约时间,可以写一个shell脚本,里面包含了很多命令,执行shell脚本就相当于执行这些命令。所以shell脚本里面其实就是这些命令的集合和shell的一些语法。基本上自动化的领域离不开shell脚本。如果你想要作系统启动之后自动启动一些服务(类似windows开机之后会有一些自启动软件),我们就可以用shell来完成。
2024-09-02 13:00:50
1739
原创 嵌入式全栈开发学习笔记---Linux常用库(libevent)
之前我们学习服务器端和客户端的网络编程时,我们需要自己写创建socket,绑定信息,监听等等代码,而这个Libevent里面已经有封装好的这些代码,我们直接使用,提高我们编程的效率。Libevent里面有两个非常重要的结构体:struct event; struct event base;之前我们学习epoll的时候知道被监听的事件是放在一个集合中的,而这个集合其实就是一个存放了很多事件的结构体,而每一个事件也是用结构体封装的。
2024-09-02 12:37:51
1953
原创 嵌入式全栈开发学习笔记---C语言(数据类型/控制结构)
这篇博文的目的是复习C语言,以30多个编程题作为复习要点,这30多个编程题基本涵盖了C语言所有的内容了,只要你掌握了这30多个编程题,那么你的C语言基本就没什么问题了。注意:由于本专栏是嵌入式全栈开发专栏,为了我们能熟悉以后实际工作中的开发环境,我们写C语言全部在Linux中的vim编辑器中写,这么做事为了我们能够熟练掌握Linux系统的常用命令以及Linux上的vim编辑器的常用工作命令,以达到对口训练的目的!vim编辑器的一些工作命令在上一篇博文中已经详细介绍过了,如果不了解可以先去看看。
2024-09-01 11:16:31
994
原创 嵌入式全栈开发学习笔记---Linux常用库(json)
为什么使用json?以QQ注册的场景为例。当我们注册QQ的时候,我们需要输入很多信息,比如账号,密码还有一些以防之后忘记密码需要找回密码时所需的邮箱账号,或者密保问题等等,这些信息有将放在一个结构体里面,注册成功后,我们登录的时候,就只需要用到账号和密码,那么之前注册的结构体里的其他成员就用不上了,为了节约内存空间只好又重新创建一个登录时用的结构体,这个结构体只放账号和密码,但是这样如果每次一个任务都要重开一个结构体,就太麻烦了。如果不开新的结构体,之后什么信息都往注册时用的结构体里面添加,这个结构体
2024-09-01 10:38:29
2296
原创 嵌入式全栈开发学习笔记---Linux网络编程(面试/开发重点)
服务器建立步骤1、创建一个socket--socket();2、绑定信息bind();上面创建的socket还是个空的文件,现在要往里面填一些东西;填什么?我们用电脑模拟服务器,一般是两个网卡,一个是有线网卡,一个是无线网卡,并且这两个IP地址不一样。我们到底接下来要监听哪个网卡呢?我们就得把IP地址填进去,以及服务器要监听这个网卡上的哪个端口号,因为一个网卡有6万多个端口。因此“绑定信息”就是绑定端口号和IP地址。服务器在监听,客户端向这个IP地址的端口发起连接,被服务器监听到了,监听到后就可以建
2024-09-01 09:50:48
2487
原创 嵌入式全栈开发学习笔记---Linux系统编程(多线程编程)
什么叫线程?通俗来讲,线程就是“进程里面的进程”,叫执行流就像这样,下图一个箭头代表一个进程,一个进程分为两个线程,一个线程可以单独处理一件事情,那一个进程里面有两个线程,也就是两个分支,这样一个进程就可以处理两件事情,而这两个线程是共享这一个进程的虚拟空间的。线程的优势(面试重点)和进程相比,它是一种非常“节俭”的多任务操作方式.,启动一个线程不需要分配内存资源。线程间彼此切换所需的时间也远远小于进程间切换所需要的时间。线程有方便的通信机制(比如定义了一个全局变量,每个线程都可以使用,因为它们
2024-08-31 14:57:20
2133
原创 嵌入式全栈开发学习笔记---Linux系统编程(进程间通信)
现在Linux使用的进程间通信方式包括:1、管道(pipe)和有名管道(FIFO)2、信号(signal)3、消息队列(message queue)4、共享内存(share memory)5、信号量(semphore)6、套接字(socket)(这个是网络编程里面的东西,两台电脑之间的通信,之后再讲)
2024-08-31 14:05:32
2202
原创 嵌入式全栈开发学习笔记---Linux系统编程(进程控制)
为什么有了操作系统,就能同时处理多个任务?比如单片机一次只能下载一个main函数进去,因为一个处理器同一时刻只能处理一个事情(一个main函数)。而我们的电脑可以上QQ,同时也能使用浏览器,但是为什么我们的电脑可以同时处理多件事情,单片机就不行呢?是因为我们的单片机是裸机,没有操作系统,而我们的电脑是有操作系统的。比如我们的电脑现在正在运行QQ,音乐,浏览器三个进程操作系统让QQ在CPU里面进行5ms,然后让它出来,又让音乐进去5ms,然后让它出来,再让浏览器经常去5ms,让它出来,再它QQ进去5m
2024-08-31 09:10:54
1396
原创 嵌入式全栈开发学习笔记---Linux系统编程(文件编程)
Linux一点哲学:一切皆为文件file在Linux中对目录和设备的操作都等同于对文件的操作,都是使用文件描述符来进行的。(一切都可以抽象概括为文件,包括硬件,比如在电脑上插上U盘,操作U盘其实就是在操作这个文件)Linux文件可分为:普通文件,目录文件(文件夹),链接文件(软链接,可以指向特定的文件,类似windows上的快捷方式),设备文件(硬件设备,比如U盘);1、当打开一个现存文件或创建一个新文件时,内核就向进程返回一个文件描述符;当需要读写文件时,也需要把文件描述符作为参数传递给相应的函数
2024-08-30 21:00:20
1358
原创 嵌入式全栈开发学习笔记---Linux系统编程(概述)
为什么要学习Linux系统?因为在嵌入式设备中用的大多都是Linux系统,而且在现实生活中Linux系统应用的概率可能比windows系统要大,比如安卓系统底层用的就是Linux系统,很多智能家居用的也都是Linux系统,一些路由器也是Linux系统,电视机底层用的也是Linux系统等等,凡是能被手机远程控制的产品,它们的底层一般都是Linux系统。为什么Linux系统被嵌入式设备广泛应用?因为Linux系统开源免费,而且功能强大。
2024-08-30 20:20:24
995
原创 嵌入式全栈开发学习笔记---项目1:停车管理系统
目前为止我们已经学习了linux系统的终端上的一些操作命令、vim编辑器上的一些操作命令、C语言和数据结构,接下来我们就用我们学过的这些知识做一个“停车管理系统”的项目。开发环境:基于VMware Workstation虚拟机上的Linux系统的终端上的vim编辑器。涉及重要知识点:C语言(二维数组);数据结构(链表、队列、广度优先算法(BFS));
2024-08-12 00:58:13
1206
原创 嵌入式全栈开发学习笔记---数据结构(排序算法)
常见的排序算法按照排序过程中所依据的原则的不同可以分类为:插入排序:直接插入排序 希尔排序交换排序:冒泡排序 快速排序选择排序:简单选择排序 堆排序归并排序基数排序
2024-08-10 10:42:32
1117
原创 嵌入式全栈开发学习笔记---数据结构(二叉树)
二叉树的特点1、每个结点最多有两棵子树,所以二叉树中不存在度大于2的结点(即一个结点最多只能有两个分支)。2、左子树和右子树是有顺序的,次序不能任意颠倒(如上图中B是A的左子树,C是A的右子树,B和C的顺序不能调换)。3、即使树中某结点只有一棵子树,也要区分它是左子树还是右子树。
2024-08-10 10:19:25
914
原创 嵌入式全栈开发学习笔记---数据结构(广度优先算法)
分析到这里我们已经知道这其实是多条路径同时进行的,谁先到达终点,说明谁走过的路径就是多短路径。这个过程什么时候结束呢?当最后出队的点(即要分析的点)是终点的时候这个过程就结束了。当我们知道谁走过的那条路是最短路径的时候,怎么打印出来呢?比如我们知道走过(2,0)这个点对应的是最短路径,我们就可以顺着记录下来的下标找到它前面点,依次倒推,就能得到一条完整的路径
2024-08-09 18:49:45
485
原创 嵌入式全栈开发学习笔记---数据结构(队列)
所以求长度的正确做法是:(rear-front+SIZE)%SIZE用上面的队列验证一下,(0-2+8)%8=6,最终长度就是6队满的条件队满的条件是:rear和front相邻,用公式表达:(rear+1)%SIZE=front比如下面这种情况:(7+1)%8 =0,所以这种情况也属于rear和front相邻的情况
2024-08-09 18:44:29
764
原创 嵌入式全栈开发学习笔记---数据结构(深度优先算法)
我们接下来用这个二维数组模拟一个迷宫,写0的地方表示一个正常的通道,1表示一堵墙,也就是写1的地方不能走,走过的点也不能再走。我们从起点出发,首先从这个方向走,走到终点之后退回去在走得通的一个点处找另外一条可走的路径。很显然我们需要一个东西来记录走过的点,这个东西就是栈,让一个点进栈和出栈。
2024-08-09 18:32:09
792
原创 嵌入式全栈开发学习笔记---数据结构(栈结构解决四则运算)
运算数:直接进栈;运算符进栈的情况:空栈;表达式中的符号优先级比栈顶高;栈顶是左括号同时此时表达式中的符号不是右括号;运算符出栈不计算的情况:栈顶是左括号且表达式中的符号是右括号;运算符出栈计算的情况:表达式中的符号优先级不高于栈顶;表达式中的符号是右括号且栈顶不为左括号;表达式中没有要操作的符号和数字了(为空)且运算符的栈不为空;
2024-08-09 18:25:31
1168
原创 嵌入式全栈开发学习笔记---数据结构(链栈)
所谓链栈就是以链表的形式来实现栈的这种结构。在链表里面我们有个“头指针”的概念,而在栈里面我们有“栈顶指针”的概念。Top既可以是头指针,也可以是栈顶指针。每进栈一个元素,top就往上移动一次,每出栈一个元素,top就往下移动一次。所以我们将指针的方向定义为从上往下指,这样可以省去“头指针”和“栈顶指针”这些概念。
2024-08-09 18:13:39
332
原创 嵌入式全栈开发学习笔记---数据结构(顺序栈)
当我们初始化一个空栈的时候,栈顶指针(下标)应该设置为-1,如果设置为0的话就还不能表示空栈。我们在程序上如果来表示一个栈呢?我们还是用结构体来表示:只要知道栈顶在哪了,就知道这个栈的容量有多大了。
2024-08-09 18:01:58
796
原创 嵌入式全栈开发学习笔记---数据结构(双向循环链表)
双向循环链表同时具有双向链表和循环链表的特性,是效率最高的一种链表。我们也是在单链表的代码基础上修改。双向循环链表的初始化在双向循环链表中,从头到尾我们都不能出现NULL这个字眼。初始化的时候,头结点的Prior和next指针域都初始化为它自己的地址。
2024-08-07 06:33:20
538
原创 嵌入式全栈开发学习笔记---数据结构(双向链表)
双向链表的删除操作比如我们要删除第二个节点,在删除之前我们得先把第三个结点的位置存放在第一个结点的next指针域中,然后将第一个结点的位置存放在第三个结点的prior指针域中,最后再释放掉第二个节点的空间。
2024-08-07 06:22:57
394
原创 嵌入式全栈开发学习笔记---数据结构(链表的分类)
常见的链表有:静态链表(用的很少,有点类似于顺序表)、单链表、双向链表、循环链表、双向循环链表(效率最高)
2024-08-06 10:25:51
210
原创 嵌入式全栈开发学习笔记---数据结构(单链表)
链式存储俗称链表,将零散的结点连起来,比如当我们找到第一个结点的时候,我们可以通过某种方式找到第二个结点,以此类推。虽然它们不是连续的,但是我们能通过某种方式把它们连起来,我们也把这种结构称为线性结构。编辑链表的每个结点都有一个地址,并且地址是随机的,即使我们知道链表中第一个结点的地址,也无法找到第二个结点,而顺序表的地址是连续的,所以当我们知道顺序表中第一个结点的位置我们就能顺着首地址找到后面的位置。编辑因此我们需要把链表的每一个结点连起来,形成一条线。如何连起来?首先我们把这个结点
2024-08-06 10:16:00
924
原创 嵌入式全栈开发学习笔记---数据结构(顺序表)
顺序表应该支持以下操作:初始化操作,建立一个空的顺序表InitList(*L); 判断顺序表是否为空 ListEmpty(L); 清空顺序表ClearList(*L);获取第i个位置的元素,存放在e中GetElem(L, i, *e); 查找于e相等的元素,返回元素的位置LocateElem(L, e); 在第i个位置插入元素eListInsert(*L, i, e); 删除第i个位置的元素,保存在e中ListDel(*L, i, *e); 获
2024-08-04 17:41:49
1119
原创 嵌入式全栈开发学习笔记---数据结构概述
入门级概念什么是数据结构?我们以往都是把数据存放在数组中,数组占用的是连续的内存。这种形式大部分都是没有问题的,90%的情况下数组都是能解决需求的,但是数据量特别大时,比如4亿个整型数据,你如何进行排序呢?我们不可能把这么多个数据放在内存中,也不会有这么多的内存。因此,我们就要想办法如何来排布这些数据才能放入内存中,以及如何排布才能让操作的效率最高。所以,数据的结构形式就是我们所说的数据结构。什么是算法?算法和数据结构有什么联系?我们提到数据结构时一般都会涉及到算法。之前我们学过冒泡排序就算是一种常
2024-08-04 17:25:42
935
原创 stm32学习笔记---MPU6050(代码部分)软件I2C读写MPU6050
通过AD0引脚改名的功能我们可以把一根飞线连接AD0引脚和VCC, 这时MPU6050的从机地址就是1101 001了。编辑这个时候运行就发现从机没有给我们应答了,因为它刚刚改名成1101 001了。这个时候把飞线拔掉,再次运行发现它又可以应答了。编辑这就是改名的实验现象。目前我们这个芯片只有AD0一个引脚,它就只能拥有两个名字。如果有AD0和AD1两个引脚,就可以拥有总共四个名字。如果有更多的可配置引脚,就有更多的改名机会。当我们需要一条总件挂载多个相同型号的设备时,就可以利用这个改名
2024-07-22 11:30:40
2459
5
原创 stm32学习笔记---MPU6050(理论部分)
什么是6轴姿态传感器?在现实的三维空间里,只有xyz三个轴。但是这个MPU6050芯片里面有加速度计和陀螺仪两种传感器,可以分别测量xyz三个轴的加速度和角速度,加起来总共就是六个轴,所以这个芯片是六轴姿态传感器。当然,如果芯片里再集成一个三轴的磁场传感器,测量xyz轴的磁场强度,就叫做九轴姿态传感器。如果再集成一个气压传感器,测量气压大小,就叫做十轴姿态传感器。一般气压值反映的是高度信息,海拔越高,气压越低,所以气压计是单独测量垂直地面的高度信息的。这也就是姿态传感器的一些术语,之后别人再说这个传感器是
2024-07-11 18:33:49
3745
3
原创 stm32学习笔记---I2C通信协议(理论部分)
同步和异步的区别异步时序的好处就是省一根时钟线,节省资源,缺点就是对时间要求严格,对硬件电路的依赖比较严重。同步时序的好处就是反过来,对时间要求不严格,对硬件电路不怎么依赖。在一些低端单片积没有硬件资源的情况下,也很容易使用软件来模拟时序。缺点就是多一根时钟线。本节我们最基本的任务是通过通信线实现单片机读写外挂模块寄存器的功能。其中至少要实现在指定的位置写寄存器和在指定的位置读寄存器这两个功能。实现了读写寄存器就实现了对这个外挂模块的完全控制。
2024-07-11 18:11:29
1427
原创 stm32学习笔记---FlyMcu串口下载&STLINK Utility(理论部分)
本节主要是教大家使用两个小软件,这两个软件也是比较常用的,里面有很多有意思的功能。这个功能能帮助我们干什么呢?比如你看到别人用STM32做了一个产品,你觉得不错,就可以抄一下它的PCB板,然后程序文件又可以通过这个软件读出来,这样就可以大批量山寨别人的产品了。不过STM32也可以配置读保护,这个等会儿再说。但是反过来,如果你开发产品不注意这个问题的话,是不是一不小心程序就泄露了!我们看一下读出来的这个文件,这个文件是.bin格式的,里面记录的就是STM32从0800开始存储的程序数据,bin格式是没
2024-07-04 12:30:00
3871
原创 stm32学习笔记---USART串口数据包(代码部分)串口收发HEX数据包/文本数据包
这个程序还隐藏有一个问题,就是这个Serial_RxPacket数组,它是一个同时被写入,又同时被读出的数组。在中断函数里,我们会依次写入它,在主函数里,我们又会依次读出它。这会造成数据包之间可能会混在一起。比如读出的过程太慢了,前面两个数据刚读出来,等了一会儿才继续往后读取。这时后面的数据就有可能会刷新为下一个数据包的数据,也就是读出的数据可能一部分属于上一个数据包,另一部分属于下一个数据包。解决方法可以在接收部分加入判断,就是在每个数据包读取处理完毕后,再接收下一个数据包。当然,很多情况下其实还可以不
2024-07-04 11:30:00
1645
原创 stm32学习笔记---USART串口数据包(理论部分)
我们之前学习了串口的代码,发送一个字节,接收一个字节都没问题。但在实际应用中,我们可能需要把多个字节打包为一个整体进行发送。比如说我们有个陀螺仪传感器,需要用串口发送数据STM32。陀螺仪的数据,比如x轴一个字节,y轴一个字节,z轴一个字节,总共三个数据需要连续不断的发送,当你像这样xyzxyzxyz连续发送的时候,就会出现一个问题,就是接收方不知道这数据哪个对应x,哪个对应y,哪个对应z,因为接收方可能会从任意位置开始接收,所以会出现数据错位的现象。这时候我们就需要研究一种方式,把这个数据进行分割,把x
2024-07-03 15:57:09
1986
空空如也
空空如也
TA创建的收藏夹 TA关注的收藏夹
TA关注的人