自定义博客皮肤VIP专享

*博客头图:

格式为PNG、JPG,宽度*高度大于1920*100像素,不超过2MB,主视觉建议放在右侧,请参照线上博客头图

请上传大于1920*100像素的图片!

博客底图:

图片格式为PNG、JPG,不超过1MB,可上下左右平铺至整个背景

栏目图:

图片格式为PNG、JPG,图片宽度*高度为300*38像素,不超过0.5MB

主标题颜色:

RGB颜色,例如:#AFAFAF

Hover:

RGB颜色,例如:#AFAFAF

副标题颜色:

RGB颜色,例如:#AFAFAF

自定义博客皮肤

-+
  • 博客(36)
  • 收藏
  • 关注

原创 AT24C02实战指南:一文搞懂EEPROM选型与应用

本文围绕 AT24C02 开展嵌入式实践,先介绍 EEPROM 的基础概念、AT24C02 芯片特性,讲解它的读写特点、写保护机制与设备地址规则;接着说明 AT24C02 和灵犀板的硬件连接、PCB 走线要点,明确本次实战目标与功能需求。软件部分以 STM32CubeMX 为工具,依次完成仿真接口、晶振系统时钟、I2C2、串口、LED 的配置,重点解释 I2C 快速模式(400KHz)及时钟占空比的原理,最后生成工程,实现对 AT24C02 的 I2C 读写调试。

2026-11-06 00:45:15 189 11

原创 Linux 常用工具(下):Git + GDB 入门实操

本文介绍了Git版本控制器的基本概念与使用流程,涵盖其诞生背景、安装配置、三板斧操作(add、commit、push)及Gitee远程仓库的协同开发实践。同时,结合调试器GDB与cgdb,演示了代码调试技巧,如断点设置、变量监视、条件断点和函数调用栈分析,帮助开发者高效管理代码版本与定位问题。

2026-11-04 17:23:27 635 16

原创 一文搞懂 C++ 反向迭代器:封装原理与代码实现

反向迭代器是STL中的一种适配器,用于实现容器的逆向遍历。其核心思想是封装正向迭代器,通过重载运算符(如--、*等)实现反向访问。在SGI-STL中,reverse_iterator基于iterator_traits提取迭代器类型信息,并通过base()返回原迭代器。例如,rbegin()返回reverse_iterator(end()),rend()返回reverse_iterator(begin())。该设计统一了不同容器的反向遍历接口,提升代码复用性与可维护性。

2026-11-01 21:09:33 155 9

原创 Linux 基础开发工具全解:换源、Vim、GCC、Makefile、GDB、Git(附进度条实战)

本文系统介绍了Linux开发基础技能:通过yum/apt管理软件包,掌握vim编辑器的三模式操作与配置,学习gcc/g++编译原理及静态/动态链接机制,编写Makefile实现自动化构建,最终完成首个进度条程序。结合实际案例,涵盖文件缓冲、回车换行、fflush刷新等关键概念,并为后续git版本控制与gdb调试奠定基础。

2026-11-01 14:14:19 524 14

原创 STM32 I2C 入门|硬件原理与协议详解(阻塞通信前置)

本文系统讲解I2C通信协议的核心原理与STM32F103ZET6的实现机制。重点涵盖I2C的两线制、开漏输出、线与特性及“线与”逻辑的硬件实现;深入剖析主从通信流程,包括起始/停止信号、地址寻址、读写控制、应答(ACK/NACK)机制及数据帧格式;明确STM32中ARM-CPU、MCU、I2C外设与GPIO的协同关系,理解I2C寄存器映射与访问方式。通过理论结合实践,为后续掌握I2C实战开发奠定坚实基础。

2026-10-29 19:34:47 483 9

原创 C++ 草原三剑客之一:多态

多态是面向对象编程中“同一接口,多种实现”的核心特性,主要分为编译时多态(如函数重载)和运行时多态。运行时多态依赖虚函数与继承关系,通过基类指针或引用调用虚函数,实际执行由对象类型决定。其实现关键在于:基类虚函数被派生类重写,且调用时使用动态绑定。底层通过虚函数表(vtable)机制实现,每个含虚函数的类拥有一个虚表,存放虚函数地址,对象包含虚表指针(vfptr),运行时根据指向对象类型查表调用对应函数。此外,析构函数应声明为虚函数以避免资源泄漏,纯虚函数定义抽象类,强制派生类重写。C++11引入overr

2026-10-26 19:52:18 192 11

原创 7-2 重定向C IO函数,多⽂件引⼊

本文通过实现STM32串口重定向,将printf/scanf/fgets函数定向至UART,使MCU可像PC端一样进行串口调试。基于MicroLIB库启用与HAL库配合,完成fputc和fgetc底层重写,并采用模块化设计(BSP)封装USART与LED驱动。结合上位机工具实现数据收发与LED控制,掌握嵌入式C语言调试核心技能,为后续I2C等通信协议学习奠定基础。

2026-10-24 22:06:32 225 6

原创 Linux 的基础指令 (续篇):tar、Shell 原理与权限详解

mv命令用于移动文件或重命名,若目标不存在则重命名,若为目标目录则移动文件。默认覆盖同名文件,可用-i交互确认。支持直接移动目录,无需-r。重命名不改变inode,仅修改目录项,ctime更新。cat、more、less用于查看文件,less支持前后翻页与搜索。head/tail显示文件首尾内容,可配合管道实现范围查询。date显示时间并支持格式化与时间戳转换。find、which、whereis用于查找命令与文件。grep搜索文本,支持忽略大小写与行号。tar打包解包,zip/unzip压缩解压。权限管理

2026-10-24 15:25:42 220 6

原创 STM32串口轮询收发实战教程

本示例基于STM32CubeMX与HAL库,实现USART1的阻塞式轮询收发。配置波特率115200、8位数据、奇校验、1停止位,通过HAL_UART_Receive与HAL_UART_Transmit函数完成数据收发,绿灯闪烁指示传输状态。代码采用轮询方式等待RXNE与TC标志,确保数据完整。结合CH340K USB转串口模块,配合上位机工具实现双向通信,掌握串口初始化、阻塞模式使用及调试技巧,为后续通讯模块学习奠定基础。

2026-10-22 00:37:29 426 7

原创 C++ 面向对象 —— 继承与派生

继承是面向对象编程中实现代码复用的核心机制,允许派生类在继承基类特性基础上扩展新成员。通过继承可避免重复定义共性成员(如姓名、年龄),提升代码维护性。继承支持public、protected、private三种访问控制方式,其中public继承最常用。派生类默认成员函数需调用基类对应函数,析构函数自动按逆序调用。继承存在作用域隐藏、菱形继承等问题,建议优先使用组合(has-a)而非继承(is-a),以降低耦合度。虚继承可解决菱形继承的数据冗余与二义性问题,但增加复杂性。现代C++提倡合理使用继承与组合,结合

2026-10-16 21:17:56 123 3

原创 理解第一个通信模块串口

本文系统讲解STM32 USART串口通信基础,涵盖UART/USART概念、串行异步通信特点、1对1全双工模式及硬件连接。重点解析波特率与比特率关系,深入理解帧格式(起始位、数据位、校验位、停止位),掌握TDR/RDR寄存器工作原理及TXE、RXNE等关键状态标志位。通过阻塞式发送与接收流程,实现理论到实践的过渡,为后续嵌入式串口开发奠定坚实基础。

2026-10-15 11:37:37 264 2

原创 七大基础排序详解:冒泡、选择、插入、堆排、快排、归并、计数排序

本文系统讲解了C/C++中的基础排序算法,涵盖冒泡、选择、插入、希尔、堆、快速、归并及计数排序。重点分析各算法思想、实现代码、时间复杂度(如O(N²)、O(N log N))、空间复杂度与稳定性。通过对比性能与适用场景,强调插入排序适合有序数据,快速排序综合效率高,归并排序稳定且适用于外排序,计数排序在范围集中时高效。结合面试题巩固理解,全面掌握排序核心原理与应用。

2026-10-11 20:29:53 114

原创 Linux的诞生和基本指令(前10个)

本文系统介绍了Linux基础指令与核心概念,涵盖其发展史、开源特性及广泛应用领域。重点讲解了40+常用命令,如ls、cd、pwd、touch、mkdir、rm等,掌握文件与目录操作、权限管理、路径理解及重定向、管道等高级功能。通过XShell远程登录实践,强化命令行操作能力,并深入解析man手册章节体系,明确系统调用(第2章)、库函数(第3章)与用户命令(第1章)的区分。内容兼顾理论与实操,为后续系统编程学习奠定坚实基础。

2026-10-07 22:20:49 93

原创 RCC与时钟树案例与源码解析

本文通过STM32CubeMX配置时钟树,利用外部8MHz晶振经PLL倍频至72MHz系统时钟,实现对LED闪烁速度的控制。采用CPU_Delay()软件延时函数,其执行时间受主频影响,从而直观展示时钟配置对系统行为的影响。结合GPIO初始化与寄存器操作,详细解析了时钟使能、分频配置及硬件寄存器映射机制,强调外设需开启时钟方可工作,并指出软件延时的局限性。最终实现PF8引脚输出方波,验证时钟树配置效果。

2026-10-06 22:33:43 200

原创 RCC与时钟树初始(stm32的指挥官)

本文围绕 STM32F1 芯片的 RCC 复位与时钟控制模块及整体时钟树展开学习分析。首先介绍芯片四个原始时钟源 HSE、HSI、LSE、LSI 各自特性与适用场景;梳理系统时钟 SYSCLK 的可选通路,以及 AHB、APB 总线的分频机制,解释内核与通用外设的时钟供给原理。重点分析 RTC、IWDG 这类拥有独立时钟源的外设,说明二者时钟通路不依赖主系统时钟的特点

2026-09-30 21:18:48 233 1

原创 unorder_set和unorder_map的使用及底层原理

unordered_set 基于哈希表实现,底层使用哈希桶存储数据,支持快速增删查改(平均时间复杂度 O(1)),与 set(红黑树实现,O(log N))相比,性能更优但不保证有序。其要求键类型支持转为整数及相等比较,迭代器为单向。通过 reserve() 预分配空间可避免频繁 rehash,提升效率。对比 set,unordered_set 在大多数场景下更快,但哈希冲突严重时性能可能退化。二者均去重,若需重复元素应使用 multiset/unordered_multiset。

2026-09-28 22:21:19 194

原创 第一个片上外设模块GPIO

本课程旨在帮助学习者建立对单片机GPIO模块的宏观认知,掌握其八种输入输出模式,深入理解推挽、开漏、复用及上下拉等核心原理。通过剖析MOS管工作机理、钳位保护电路与施密特触发器,强化对信号电平控制与抗干扰设计的理解。结合代码层面对时钟配置与寄存器操作的分析,为后续外设开发奠定坚实基础。

2026-09-25 20:22:42 206 2

原创 map和set基于红黑树的实现

set与map通过复用红黑树实现,利用模板参数区分存储类型:set以key为Value,map以pair<const key, T>为Value,实现同一棵红黑树支持两种容器。通过仿函数KeyOfT萃取key进行比较,解决pair默认全字段比较的问题。迭代器基于中序遍历,++/--操作通过局部逻辑与祖先路径查找实现,end()用nullptr表示。通过不同模板参数控制数据类型(const key或pair<key, value>),实现对元素的只读或可修改控制,达到代码复用与功能解耦

2026-09-24 16:34:46 55

原创 初识STM32ZET6

本文系统梳理STM32F103ZET6核心知识,涵盖型号命名解析(如144引脚、512KB Flash、LQFP封装、-40℃~+85℃工作温度)、引脚功能分类(特殊功能与可编程GPIO)、仿真器原理(以DAPLink为例,讲解SWD接口)及裸机开发基础。通过复盘STM32背景与应用,明确其在嵌入式领域的主流地位,并掌握首次烧录流程与文档查阅方法,为后续开发奠定坚实基础。

2026-09-23 10:46:52 161

原创 map和set基本用法(初识)

本文系统讲解C++ STL中set与map的使用,二者基于红黑树实现,支持有序存储,查找、插入、删除时间复杂度为O(log n)。set用于去重和存在性判断(如环形链表找入口),map用于键值映射(如单词计数、学生信息查询)。对比无序版本unordered_set/map(哈希表,平均O(1)),前者适用于需有序输出场景,后者追求高效查找。注意:map的key为const,不可修改;[]操作会自动插入不存在的键。选型口诀:要有序用set/map,求速度用unordered,需映射用map,仅判存在用set。

2026-09-21 20:25:27 177

原创 嵌入式发展的历史

本文围绕【这里填主题,如 STM32 和嵌入式的历史成因】展开讲解,介绍核心概念、实现思路与实操要点,梳理常见误区与调试经验,帮助读者快速理解相关技术逻辑,掌握基础开发方法。

2026-09-20 20:13:33 38

原创 红黑树的原理及其底层实现

第二单旋转加变色:叔叔是空或者是黑,父亲变成黑色并爷爷旋转父亲成为新的root继续向上循环,第三种是双旋转加变色先对parent进行旋转,再对爷爷进行旋转,爷爷红色,父亲黑色成为新的root。这是两张典型的情况,第一种是叔叔节点是空节点,第二种像是父亲和叔叔变成黑色爷爷变成红色3作为新的变成红色的节点继续向上遍历直到父亲的节点变成红色或者父亲变成空。叔叔在且是红色的情况下才能进行简单的变色,把父亲和叔叔的节点变成黑色,爷爷节点变成红色,爷爷变成新的子节点进行判断。这个图给的是上面的图一个简化版本的例子。

2026-09-18 22:40:46 206

原创 list的应用和底层实现

显式调用构造函数。:隐式转换(编译器自动把右边的初始化列表转成左边的 list 类型)。注意:在现代 C++ 中,由于编译器的优化(拷贝消除 Copy Elision),这里的“隐式转换”通常不会产生额外的性能开销,但语意上它确实代表了从初始化列表到list对象的隐式转换过程。

2026-09-17 01:03:34 30

原创 AVL树

avl树的基本结构节点的bf变成0后就停止向上寻找。

2026-09-15 23:43:17 147

原创 堆的解析及普通二叉树的算法(不同建堆的复杂度)

解决了空间容易不够的问题,其实很多的整数,你想找到前几个,就可以用建小堆的方法,让这个先存到里面,然后再让外部数据和这个堆顶的比较,如果比它大就可以进来。这种方式没法记录下一个递归的值不止二倍复杂度,每次函数比较完加的时候还得重新算。定义成静态的无法正确解决问题会在调用一次后保存原有的值。找叶子节点的个数,左右都是空的是叶子节点。代码实现,但左和右都为空时就不向后遍历。向下建堆的实际时间复杂度是O(N)寻找节点等于x的值的节点并返回。三种序列用于实现不同的功能。递归的过

2026-09-11 00:41:24 35

原创 二叉树讲解及其底层剖析(堆的排序)

重要:parent = (child‑1)/2 = ((n‑1) − 1)/2 = (n‑2)/2。建队的时候,所有根都是坏的。嗯,在修整的时候,只有最前面的根被swap替换了,是坏的。他上面都是默认有序,只要1次走到elsezhelide。多了跳出和判断加一之后是否越界,两种跳出循环的情况。parent判断会出现死循环,不要出现0的判断。直接当成二叉树,不开空间,从1直接开始,向上建堆。这里的函数参数传数组,为后续堆排序创造条件。满二叉树和完全二叉树量级是一样的。两次不同作用的向下调整。

2026-09-08 00:51:37 43

原创 栈和队列2

获得第一个元素,它如果pop是空了,先把push倒过来。

2026-09-04 00:30:14 26

原创 栈和队列及习题讲解1

从内存先拿到寄存器,运算完再放回内存。

2026-08-31 13:51:39 209

原创 单链表的实现和各种接口

函数内部修改外部链表头指针变量本身(头插、删除头节点)两种选择:返回新头 或者 传二级指针。工程刷题优先选返回新头,可读性更高。不需要 dummy 虚拟头完成删除操作(上面 203 例题)链表的就地逆置、构建链表,不想用返回值接收头。

2026-08-27 23:04:45 309

原创 spi通信及硬件实现

SPI1 在 APB2 (72M),SPI2 在 APB1 (36M),最大 SCK 时钟不一样。波特率分频只对主机生效,从机不受 BR 分频位影响。W25Q64 配置:8bit,MSB 高位先行,SPI 模式 0(CPOL=0,CPHA=0)。硬件 SPI 对比软件 SPI:软件 SPI 全部 GPIO 手动翻转;硬件 SPI 外设接管 SCK/MOSI/MISO。同一个外设可切换 SPI/I2S,二者互斥。软件 NSS 模式下,

2026-08-27 01:23:19 429

原创 spi通信及其软件实现

spi通信是单端信号,电压差都是相当于对地的设备需要额外接地,当ss是1时miso变成高阻态,防止多个从机同时输出。掉电后仍不丢失数据,如果只擦除不写入,它的read数组里只有0 XFF。擦除和页编程里边儿都得有写使能,擦除因为要把他们全部置为1每一位。上升沿把数据放到时钟线上,下降沿把数据移位到寄存器中。SPI 模式 0(CPOL=0,CPHA=0)总结。写的时候不可以跨页,读的时候可以。ss未被选中时miso是高阻态。

2026-08-21 17:27:33 241 1

原创 顺序表的讲解及通讯录的实现

seqlist.hcontact.h顺序表包括动态数组和容量和有效数据个数。用realloc增加容量,按照2倍增能增加效率。尾插顺序表,要先判断容量是否够用没错,realloc 一定会自动保留并复制原内存里的有效内容,不需要你手动写 memcpy 去搬运数据,这是它的核心特性。

2026-08-06 20:21:14 252

原创 vector的实现,底层代码分析

vector 的 insert仅迭代器定位,不支持数字下标;string 为了字符串操作方便,额外增加了整数下标定位的全套重载,这是二者最直观的区别。下面走隐式类型转换编译器会生成两个类vector<int>和int。

2026-06-22 22:01:56 206

原创 string的原理和模拟实现

是拷贝构造的浅拷贝出作用域后销毁,会报错,没写构造函数一般都是浅拷贝两份会指向同一段空间。npos是string里的一个成员对象,因为是无符号的一在默认下的取值是正数的最大。const 数组必须用const迭代器来写,因为迭代器一般是可读可写的。这样不行,初始化列表出事的顺序是声明的顺序,这样size是一个随机值。正向迭代器反向的用法,但容易越界,反向迭代器更加安全。范围for适用于容器和数组的遍历,加*就必须是指针。npos有一个-1的缺省值,没有指定长度会全删。

2026-06-11 21:45:17 249

原创 模板跟底层运行

全局变量和静态变量(无论全局还是函数内),生命周期贯穿整个程序运行期,都存放在。限制了作用域,不影响内存分区。

2026-06-09 22:30:58 211

原创 类和对象下:初始化列表,static成员,

每个类都必须有一个拷贝初始化构造函数,如果类中没有说明拷贝构造函数,则编译器系统会自动生成一个缺省拷贝构造函数,作为该类的保护成员。匿名对象用作单独的函数调用非常方便,上面是有名对象,下面是匿名对象,匿名对象的生命周期只在当前这一行。引用成员变量,const成员变量,没有默认构造的类型变量必须用初始化列表初始化。A(const A& aa) // ② 拷贝构造返回值临时对象。省去了ret的构造,直接把aa的内存放到了ret上。省区了临时对象没aa,直接构造临时对象。~A() // ⑤ 析构临时对象。

2026-05-26 20:59:20 58

空空如也

空空如也

TA创建的收藏夹 TA关注的收藏夹

TA关注的人

提示
确定要删除当前文章?
取消 删除