- 博客(110)
- 收藏
- 关注
原创 stm32单片机学习(40)——关于CAN的收发实验
当然了这只是演示它的功能,正常我们还是需要配置中断来接收消息的这样会更合理,另外就是我们现在是环回模式只是用来自测,那么如果实现真正的通信需要修改什么呢?//只需要修改这个参数就好了 CAN_InitStruct . CAN_Mode = CAN_Mode_LoopBack;
2026-06-21 20:10:20
46
原创 stm32单片机学习(39)——STM32中的CAN外设
bxCAN是基本扩展CAN(Basic Extended CAN)的缩写,它支持CAN协议2.0A和2.0B。它的设计目标是,以最小的CPU负荷来高效处理大量收到的报文。它也支持报文发送的优先级要求(优先级特性可软件配置)。对于安全紧要的应用,bxCAN提供所有支持时间触发通信模式所需的硬件功能。
2026-06-20 18:22:00
327
原创 stm32单片机学习(38)——CAN通信协议
CAN 是 Controller Area Network 的缩写(以下称为 CAN),是 ISO*1 国际标准化的串行通信协议。在当前的汽车产业中,出于对安全性、舒适性、方便性、低公害、低成本的要求,各种各样的电子控制系统被开发了出来。由于这些系统之间通信所用的数据类型及对可靠性的要求不尽相同,由多条总线构成的情况很多,线束的数量也随之增加。为适应“减少线束的数量”、“通过多个 LAN,进行大量数据的高速通信”的需要,1986 年德国电气商博世公司开发出面向汽车的 CAN 通信协议。
2026-06-19 20:27:55
440
原创 stm32项目(4)——lp_node
坦白讲我没想到这个项目输出成博客,这四篇文章只有这寥寥几个字,深恶之都没有我学习外设的文章文字多,但其实也确实就是这样了,当我们具备做很多事情的基础之后,那么我们阐述的就是思路了就是一个更宏观的框架,只能是说把一些决定不错的细节讲一下不可能面面俱到,比如我怎么接收CAN的数据,怎么用联合体很巧妙的转换数据结构,如果这种问题放在专门讲CAN的章节还是可以,写在这里倒是有些违和了。依旧是CAN的数据收发,这部分不再赘述,唯一的区别就是各个节点发送的数据帧和接收的数据帧不一致,在处理上有些许不同。
2026-06-18 14:24:26
158
原创 stm32项目(3)——log_node
关于log_node节点的代码,因为一些原因变的很简单了我们先说一下当前的代码,等之后在扩展一下,最开始想要实现的效果。
2026-06-18 11:10:23
221
原创 STM32项目(2)——host_node
这里的功能不固定,我也是随用随加的。因为我的项目比较简单,帧的类型不多,我就在我所有的节点实现的代码中的这部分初始化了四种帧格式,这样就发送起来简单,另外就是不需要来回的看和翻找确认了,尽管这对于程序来讲是一个无意义且浪费资源的行为,但是可以极大的便利我们,当然注释放在这里一样可以提醒,但是这样还有另外一个好处就是,我们做环回测试的时候,可以更方便的在一个MCU配置过滤器。其实和USART的思路大差不差,同样需要两个任务,不同的是,CAN的数据收发比较固定,不需要太多的逻辑,因为他就是负责与节点的通信。
2026-06-18 10:04:15
186
原创 STM32项目(1)——项目介绍
该项目主要是博主用来练习CAN总线和低功耗设计的一个项目,如果是刚刚学习完基础外设的同学是不合适这个项目的,因为这里用CAN总线实现分布式多机通信,需要多个MCU。业务场景是智慧大棚,主要实现大棚的通风系统,通过来舵机模拟开关。host_node 主机节点作为中控系统,与用户进行数据交互,同时传达用户指令到各个节点log_node 日志节点进行日志记录,并且负责整个系统的时间同步工作。但是由于种种原因,日志非常粗糙,如果有兴趣扩展的同学可以考虑将数据存入W25Q64。
2026-06-18 10:03:56
214
原创 STM32单片机学习(37) —— PWR和BKP
这一篇内容包括两个内容,一个是PWR电源控制以及BKP备份寄存器。因为BKP的内容不多所以就合并到一起了。另外就是我与大家分享一个关于我的小插曲。在这最后我们同样还是会有个关于低功耗的小实验。原本我是不打算写在这里的。等我们学完之后就会知道stm32f103c8t6的芯片唤醒低功耗模式会有一些局限性。所以我上网查了有专门应对低功耗场景的芯片L0系列。这个芯片有一个LPUART,就是说他可以通过USART通信唤醒STOP模式(这些下面都会讲到)。
2026-06-10 19:24:07
194
原创 STM32单片机学习(36) —— RTC
实时时钟是一个独立的定时器。RTC模块拥有一组连续计数的计数器,在相应软件配置下,可提供时钟日历的功能。修改计数器的值可以重新设置系统当前的时间和日期。RTC模块和时钟配置系统(RCC_BDCR寄存器)处于后备区域,即在系统复位或从待机模式唤醒后,RTC的设置和时间维持不变。系统复位后,对后备寄存器和RTC的访问被禁止,这是为了防止对后备区域(BKP)的意外写操作。设置寄存器RCC_APB1ENR的PWREN和BKPEN位,使能电源和后备接口时钟。
2026-06-10 19:23:32
225
原创 STM32单片机学习(35) —— DMA
直接存储器存取(DMA)用来提供在外设和存储器之间或者存储器和存储器之间的高速数据传输。无须CPU干预,数据可以通过DMA快速地移动,这就节省了CPU的资源来做其他操作。两个DMA控制器有12个通道(DMA1有7个通道,DMA2有5个通道),每个通道专门用来管理来自于一个或多个外设对存储器访问的请求。还有一个仲裁器来协调各个DMA请求的优先权。上面来自官方文档对DMA的解释,从最后一句话,仲裁器协调各个DMA请求。可以推测出DMA各个通道在搬运数据时,并不是并行运行的,而是并发的。
2026-06-08 21:10:15
311
原创 FreeRTOS学习(12)——任务通知
消息队列(Queue)信号量(Semaphore)消息队列主要用于任务与任务、任务与中断之间传递数据信号量主要用于任务同步以及资源管理消息队列的作用几乎是不可替代的。如果需要在任务与任务,或者任务与中断之间传递数据,那么消息队列通常都是首选机制。但在实际应用中,很多时候并不需要传递数据。中断通知任务一个任务唤醒另一个任务某个事件发生后通知任务继续执行这种情况,本质上只是 发送通知和接收通知。二值信号量就可以完成这种任务同步工作。
2026-06-03 14:22:51
263
原创 FreeRTOS学习(11)——信号量
到这里为止,三种常见的信号量机制:二值信号量、计数信号量、互斥信号量,我们已经全部学完了。我们可以对 信号量相关的操作 API 做一个简单的总结。三种信号量的创建函数各不相同,但本质上都是创建消息队列,返回消息队列句柄。释放信号量都使用xSemaphoreGive()函数:对于二值信号量而言,释放信号量表示信号状态从无到有,从0到1。对于计数信号量和互斥信号量而言,释放信号量表示资源被释放,可用资源增加。本质上,都是uxMessagesWaiting++
2026-06-03 14:22:15
274
原创 FreeRTOS学习(10)——消息队列
经过上面文档的阅读与学习,相信大家已经对FreeRTOS的消息队列有了一定的理解。消息队列既可以用于任务之间通信,也可以用于中断与任务之间通信。具体来说:任务发 → 任务收(常见)中断发 → 任务收(很常见)任务发 → 中断收(几乎没有)在嵌入式系统中,最常见的一种模式是:外设中断 → 发送消息到队列 → 任务读取消息并处理。在这种模式下,中断只负责收集数据,任务负责处理业务逻辑。要重点学习这种消息队列的使用模式,这是实际工程中,最常见的消息队列使用方式。
2026-06-03 14:21:32
493
原创 FreeRTOS学习(9)——临界区
通过源码可以看出,vTaskSuspendAll() 并不是“停止系统运行”,而只是“暂停任务调度”。系统 Tick 仍然正常产生,全局时间持续推进。但所有与任务调度相关的行为被暂时冻结。调度器暂停后,所有“与调度相关的行为”都会被延迟处理,而不会丢失。延时阻塞任务到期 → 不立即转入就绪态,而是通过记录事件触发 → 不直接进入就绪列表,而是进入挂起就绪列表任务切换 → 不立即发生本质上:不是“不处理”,而是“暂不处理,后续统一处理”
2026-06-02 09:12:05
476
原创 FreeRTOS学习(8)——获取任务信息API
在前面的内容中,我们已经学习了任务的创建、删除、阻塞以及挂起恢复等操作。这些 API 主要用于“控制任务行为”。当前正在运行的是哪个任务;某个任务的优先级是多少;系统当前有多少个任务;调度器是否已经启动。也就是说,我们不仅要“控制任务”,还要“获取任务信息”。为此,FreeRTOS 提供了一组任务获取 API。这类 API 不会改变任务状态,而是用于查询系统当前运行情况,常用于调试与状态监测。接下来,我们将逐一介绍这些任务获取接口,并结合源码分析其实现机制。
2026-06-02 09:11:02
180
原创 FreeRTOS学习(7)——任务列表
Ready ↔ Running —— 解决的是 CPU 在多个任务之间如何切换;Running → Blocked → Ready —— 解决的是任务为何主动离开 CPU;Ready ↔ Suspended —— 解决的是任务如何被人为移出调度体系。调度器如何管理“就绪态任务”?因为无论是阻塞完成,还是恢复挂起,最终都会回到 Ready 状态,重新参与 CPU 竞争。也就是说:所有任务状态流转的“汇聚点”,都是——就绪态。那么问题来了:FreeRTOS 内核究竟是如何组织这些就绪任务的?
2026-05-30 19:34:36
291
原创 FreeRTOS学习(6)——任务创建
由于任务句柄非常重要,但确实比较抽象。任务句柄本质上是任务 TCB 结构体的指针。FreeRTOS 通过任务句柄,为每个任务提供一个唯一的、被内核认可的标识。程序员只能通过“任务句柄 + 内核 API”的方式,间接操作和控制任务,而不能直接修改任务的 TCB 内存区域。如果系统结构较为简单明了,各任务之间相互独立,那么任务句柄并不需要被保存。如果需要保存任务句柄以供使用,建议使用全局变量或静态全局变量来保存,用局部变量来保存句柄也没什么意义。
2026-05-30 19:33:07
255
原创 FreeRTOS学习(5)——内存映射
CPU 在进行上下文切换时,需要将寄存器中的执行状态保存到 SRAM 中。而在 FreeRTOS 系统中,系统往往同时存在多个任务。为了保证每个任务在被切换回来时,都能够继续从原来的位置正确执行,这些上下文信息显然不能混在一起保存。因此,FreeRTOS 为每一个任务,在 SRAM 中划分出一块独立且专属的内存区域,用于保存该任务的运行状态以及相关的工作数据。那么,这块属于“任务”的内存区域具体包含哪些内容?又是如何组织和管理的?这正是本文将要重点讲解的内容。
2026-05-30 19:31:42
281
原创 FreeRTOS学习(4)——内存映射
任务是 FreeRTOS 进行资源分配的基本单元,每一个任务都拥有一套相对独立的内存空间;任务是 FreeRTOS 进行 CPU 调度的基本单元,调度器通过在不同任务之间切换,实现 CPU 的合理使用。任务所拥有的“独立内存空间”究竟包含哪些内容?任务之间切换时,上下文又是如何被保存与恢复的?要想搞清楚这些问题,我们就要从STM32的内存映射机制入手,来看一看STM32的内存使用究竟是一个什么情况。STM32 单片机是一台微型计算机,麻雀虽小、五脏俱全,CPU、存储器、外设等核心组成部分一应俱全。
2026-05-29 17:15:27
196
1
原创 FreeRTOS学习(3)——FreeRTOS的移植与剪裁
了解完FreeRTOS的任务调度机制,关于FreeRTOS的前置理论,我们就大体上搞定了。虽然还有很多理论需要学习,但我们暂缓一下脚步,在这一章节中,我们先把FreeRTOS集成到我们的项目中。先跑起来再说。基于SPL标准外设库模板工程,集成FreeRTOS,形成一个新的带FreeRTOS的标准库开发工程模板。再顺便,我们来讲一讲HAL库的开发方式,也讲一讲在HAL库开发工程中集成FreeRTOS,当然这些内容了解即可。我们后续还是以标准库开发方式为主要手段。
2026-05-27 14:26:53
463
原创 FreeRTOS学习(2)——FreeRTOS的任务调度
本文的内容标题叫做《FreeRTOS的任务调度》,是纯粹的理论课程,但是重点中的重点。FreeRTOS 的任务调度,是整个 RTOS 学习中最核心、最需要理解的一部分。如果这部分内容不求甚解,那么到后续学习FreeRTOS的使用,就会彻底变成“API Caller”,而且将完全无法调试FreeRTOS。调度任务这两个中文名词非常简单,大家都知道它们啥意思。但是在FreeRTOS中,它们是核心的专业术语,下面我们将逐一解释它们。在 FreeRTOS 中,任务是调度机制的核心。
2026-05-27 14:25:46
1810
原创 FreeRTOS学习(1)——裸机开发与操作系统
在 没有操作系统(OS)作为中间层 的情况下,应用程序 直接运行在 MCU 硬件之上。开发者需要 直接操作寄存器,或者使用 外设库(如 SPL / HAL) 来完成外设初始化、控制和业务逻辑实现。也就是说:程序没有操作系统调度,一切代码都由开发者自己控制。一个典型的裸机操作是:初始化(时钟/引脚/外设)→ 主循环前执行的操作 → while(1) 主循环 → 中断服务程序(ISR)响应外部事件。所有事情都要程序员自己安排。开 RCC 时钟配 GPIO 模式。
2026-05-27 14:25:11
282
原创 STM32单片机学习(34) —— ADC实验: ADC规则组配合DMA实现自动化转运
业务更关心“发生过什么”(需要完整性),还是“现在是什么”(需要实时性)?想清楚这一点,就能在这三种策略中做出最合适的选择。
2026-05-26 09:10:42
451
原创 STM32单片机学习(33) —— ADC实验: ADC注入组的使用
最开始我是使用连续转换模式的,但是每次转换之前仍然需要触发,只在初始化中触发一次的话,也就只会转换一次。看了手册,没有找到问题,只是看到了可以支持注入组。无奈本人能力有限,尚未能分析出问题所在。在PA0,PA1,PA2,PA3接入不同的传感器/电位器,通过ADC的注入组进行进行模数转换,最后输出到OLED屏幕上。
2026-05-26 09:10:07
259
原创 STM32单片机学习(32) —— ADC
在我们的配件盒当中,有几个比较常见的传感器模块,如下图所示。光敏电阻传感器用于检测环境光照强度,其核心器件为光敏电阻(LDR)。光照越强 → 光敏电阻的电阻越小光照越弱 → 光敏电阻的电阻越大模块内部采用分压电路设计,将光敏电阻随光照而改变的阻值变化转换为电压变化输出。模拟输出(AO):直接输出连续变化的电压信号(模拟信号),用于 ADC 采集数字输出(DO):通过LM393电压比较器,配合电位器设定阈值,最终输出高低电平信号(0或1)。温度电阻传感器通常采用热敏电阻(NTC)作为核心元件。
2026-05-26 09:09:34
363
原创 STM32单片机学习(31) —— Flash编程
所谓 Flash 编程,就是通过编程的方式对 STM32 单片机的内置 Flash 存储器进行读写操作,从而实现数据的。
2026-05-26 09:08:40
370
原创 STM32单片机学习(30) —— W25Q64的使用
W25Qxx 系列是台湾Winbond(华邦电子)设计生产的,一种低成本、小型化、使用简单的非易失性存储器。通常来说,这种基于 SPI 接口进行通信的非易失性存储器,被统称为SPI Flash。它们常应用于 数据存储、字库存储、图片资源存储、固件程序存储 等场景。STM32F103C8T6 单片机内部仅集成了 32 KB 的 Flash 闪存,如果觉得还不够用,此时可以通过 外挂 W25Qxx 系列 SPI Flash 来实现存储扩容。
2026-05-25 17:24:55
341
原创 STM32单片机学习(29) —— SPI引脚和外设初始化
到此为止,关于SPI通信的时序,STM32的SPI外设,这些内容,我们都基本搞清楚了。单片机SPI通信的引脚和工作模式选择单片机与W25Q64通信实验接线SPI通信引脚和外设的初始化除此之外,我们还需要来实现一个“与从机无关的、通用的”SPI通信数据交换函数。
2026-05-25 17:24:25
364
原创 STM32单片机学习(28) —— STM32的SPI外设
在上一章节 《SPI 相关概念》 中,我们已经从通信协议本身出发,系统讲解了 SPI 通信在时序结构上的灵活可配置性。比特序的选择。时钟极性(CPOL),也就是通信空闲状态的选择。时钟相位(CPHA),也就是采用时机的选择。四种时钟模式选择。至此,我们已经大体了解了SPI通信的基本规则。结合我们学习I2C通信的经验,距离我们实现SPI通信,还有一个很重要的问题需要解决:我们实现软件SPI,还是实现硬件SPI呢?软件 SPI。
2026-05-25 17:23:49
408
原创 STM32单片机学习(27) —— SPI相关概念
我们已经学习过两种STM32通信接口了,它们就是I2C总线通信以及USART串口通信。接下来我们再来学习一种全新的通信方式——SPI通信。首先,我们要先建立一种正确的认知——SPI 并不是比 串口 / I2C 更高级的通信方式,只是设计的思路不同,解决的问题不同罢了。在《SPI相关概念》这一文中,我们所讲的内容,既和单片机的SPI外设没有关系,也和与单片机进行SPI通信的从机设备没有关系。本文仅仅涉及与SPI通信本身、通信协议本身相关的一些设定和概念。到此为止,关于SPI 通信本身、以及。
2026-05-25 17:23:16
404
原创 STM32单片机学习(26) —— 硬件I2C的实现
至此,我们已经掌握了 I2C 通信的原理与基本用法。最后,我们来系统地总结一下 I2C 的优势与局限。只需两根信号线(SCL、SDA),节省引脚、简化布线,适合板载多设备芯片之间的通信;支持多主机与多从机架构,具有高度灵活性;软件和硬件实现皆可,可以根据不同的需求,选择不同的实现;功能完善强大,支持寻址,应答,主机切换,主从数据发送等功能;成本低廉,无需专用通信器件,仅依赖通用 IO 与上拉电阻即可构建完整通信系统,性价比极高。通信距离有限。
2026-05-25 17:22:33
425
原创 STM32单片机学习(25) —— 软件I2C的实现
但是我们已经明确软件I2C的优势就在于它可以灵活的使用引脚,但是如果我们这样去初始化的话,每次更换引脚就会不方便,所以我们应该把SDA和SCL引脚换成宏,并且在初始化之后,应该将SDA和SCL电平拉高,表示空闲状态,所以我们应该先定义一些基本的操作。大家可以尝试一下,在我们现有代码的基础上更改I2C初始化的SDA和SCL的顺序,如果先初始化SDA后初始化SCL,会发现程序OLED屏幕不能正常启动。先拉高SCL总线,再拉高SDA总线,无意之间,产生了一个停止位信号,和前面的起始信号抵消了。
2026-05-24 14:37:16
311
原创 STM32单片机学习(24) —— 硬件I2C和软件I2C
硬件I2C:基于单片机的I2C外设,让I2C外设帮助程序员完成I2C通信的时序控制,实现I2C通信,这种方式称之为硬件I2C。软件I2C:直接基于某两个普通引脚,用GPIO外设来模拟I2C通信的时许,实现I2C通信过程,这种方式称之为软件I2C。
2026-05-24 14:36:43
187
原创 STM32单片机学习(23) —— OLED的使用
在讲完I2C相关所有概念、I2C通信协议、时序要求等问题后,我们再了解一下支持I2C通信的硬件从机设备——OLED。这可以为后续我们做实验打下基础。
2026-05-24 14:36:10
650
原创 STM32单片机学习(22) —— I2C通信协议
本文将系统讲解I2C 通信协议。I2C通信协议的基础约定。引脚工作模式约定I2C总线设计原理。主从设备,在通信中的引脚设置。SDA总线和SCL总线,在通信过程中的作用。I2C通信的时序结构,数据帧格式,也就是通信从开始到结束的流程。到此为止,有关I2C通信硬件电路设计、以及一些相关的约定限制,我们就全部讲完结束了。I2C 总线由 SDA(数据线)与 SCL(时钟线)组成,所有主从设备共享这两条线,形成“多设备挂载”的总线结构。
2026-05-24 14:35:27
416
原创 STM32单片机学习(20) —— 利用中断实现串口通信(填前面的坑)
在之前的串口通信的实验(输入字符,打印到OLED屏幕,以及控制LED)中,我们总是会因为函数阻塞,导致不能正常的运行程序,只能通过一些其他的办法来缓解,但终归没有真正的解决。而在我们学习中断之后就可以解决了。所以本文将继续从头开始分析如何完成该项目。
2026-05-23 20:03:29
68
原创 STM32单片机学习(18) —— 外部中断
在之前所有的串口通信中,我们都直接使用了PA9和PA10的引脚复用功能,直接把它们当成USART1_TX和USART1_RX引脚使用。现在假如PA9和PA10引脚不可用了,于是我们只能考虑重定义引脚功能。比如参考下图:将USB-TTL设备的RXD针脚接入单片机的PB6(USART1_Tx)引脚。将USB-TTL设备的TXD针脚接入单片机的PB7(USART1_Rx)引脚。如下图所示:现在我们使用AFIO模块,来将PB6和PB7重定义为串口通信的引脚。此时我们需要使用的函数就是函数。
2026-05-22 16:37:54
429
原创 STM32单片机学习(17) —— 串口外设中断
初始化NVIC外设就是配置某个中断请求其中的成员NVIC_IRQChannel,就是配置终端的唯一性编号这个标号不要手写和记忆,要去stmf10x.h的头文件找到枚举类型IRQn_Type进行复制粘贴计算机系统为什么要使用中断?使用中断有什么好处呢?中断在计算机系统中有何意义?这三个问题的答案都可以通过上面的,一个简单的串口中断的案例得出。CPU的运行速度是最快的,其次是存储器,外设运行速度最慢。
2026-05-22 16:37:12
436
空空如也
CSDN的Markdown怎么更新了
2026-05-13
TA创建的收藏夹 TA关注的收藏夹
TA关注的人
RSS订阅