- 博客(37)
- 收藏
- 关注
原创 STM32电机控制基础知识
电机控制是嵌入式领域中一个前景广阔的专业方向。然而,面对繁杂的理论与实践,许多初学者常常感到无从下手。因此本篇文章将以STM32的标准库驱动直流有刷电机为例,分享一些电机控制的基础知识,希望可以给大家做一个参考。
2025-10-03 15:03:19
913
原创 STM32基础篇--GPIO
GPIO的全称是Genral purpose input output,简称IO口,一般用于控制连接在GPIO口上的外设。大家可能只看了STM32的固件库怎么配置,但是可能会遗漏为什么要这样配置。本讲将从GPIO的工作原理出发进行讲解。
2025-09-11 22:49:48
946
原创 MQTT协议基础讲解
MQTT协议的全称是Message Queuing Telemetry Transport(消息队列遥测传输),是一种基于服务/客户端架构的发布/订阅模式的轻量级消息传输协议。其工作在TCP/IP四层模型中的应用层,是基于TCP连接进行数据推送的。MQTT作为一种低开销、低带宽占用的即时通讯协议,使其在物联网、小型设备、移动应用等方面有较广泛的应用。本文将从MQTT的服务端/客户端架构、通信原理、报文格式、Qos及心跳机制几个方面来进行介绍。
2025-08-16 18:08:13
557
原创 MCU+RTOS调试
在做项目时,百分之三十的时间写代码,还有百分之70的时间用于调试。本期将以Keil为例进行调试章节的讲解,目的在于做出一个标准化的调试步骤,方便大家学习如何调试代码。内容分为基础调试、中级调试及进阶调试三部分,本次主要讲解基础调试。
2025-07-28 20:54:31
1048
原创 FreeRTOS移植中时钟管理文件的修改
当RTOS运行的时候,delay_ms函数将先判断延时时长是否大于等于1个RTOS时钟节拍(fac_ms),当大于这个值的时候,就通过调用OS的延时函数来实现(此时任务可以调度),不足1个时钟节拍的时候,直接调用delay_us函数实现(此时任务无法调度)。ps:需要stm32+rtos项目源码,或者FreeRTOS开发手册,请联系1840813505@qq.com,备注csdn。
2025-07-04 18:19:26
587
原创 MAP文件分析
掌握Map文件的解读能力,是程序员尤其是嵌入式开发、性能优化领域的一项重要基本功,也是面试中可能遇到的关键考察点。本文系统性地拆解了Map文件的核心组成部分,并提供了清晰的解读思路和示例。希望通过本文的分析,能帮助大家真正看懂Map文件,提升对程序底层布局的理解,为程序分析、优化和调试打下坚实基础。
2025-06-20 16:16:27
1013
原创 用C语言实现面向对象思想编写驱动层--以驱动LED为例
在做项目过程中,使用面向对象思想去编写驱动层是经常用到的软件设计方法。本文探讨了如何运用C语言实现面向对象编程思想构建LED驱动层,通过结构体封装技术将LED设备的硬件参数(如GPIO端口、引脚号)与操作函数(初始化、点亮、熄灭)整合为独立对象,实现了面向对象的封装特性,有效隔离硬件细节,使上层应用只需调用接口即可控制不同LED设备。显著提升了代码的可移植性可维护性和可扩展性。
2025-06-16 12:32:19
401
原创 FreeRTOS的低功耗Tickless模式
FreeRTOS Tickless模式通过动态暂停系统心跳(Tick)中断,允许处理器在空闲时段进入更深层次、功耗极低的睡眠状态,并精确预测下一个任务唤醒时间点来设置单次长定时唤醒,从而最大限度地减少了因周期性Tick中断导致的无谓唤醒和功耗浪费,显著降低了系统在空闲时的平均功耗。最后,更多FreeRTOS干货欢迎加入嵌入式学习交流场地,里边分享项目/资料/面经等。
2025-06-14 18:58:53
1324
原创 STM32底层机制--代码是如何在CM3芯片中运行的?
众所周知,代码会经过预处理、编译、汇编及链接四个阶段,最终被编译成可执行文件(二进制机器码)。根据启动方式的不同,决定了代码从哪块内存进行读取。一般而言,代码下载后都存储在Flash闪存中,即最终编译后的可执行文件是存储在Flash中,但flash中的代码是怎么被CPU读取并执行的呢?本文将从int a=0;a+=1;这两行代码如何在基于CM3内核的STM32F103处理器中运行来进行分析。
2025-06-11 17:25:40
939
原创 FreeRTOS队列原理讲解
接下来则挂起调度器和给队列上锁,然后判断阻塞时间到没到,如果时间未到,就再次判断队列是否真的为空,如果队列真的为空,将调用出队函数的任务加入延时表和等待接收消息表。与send函数一样,出队函数先去判断队列是否有数据,如果队列不为空,则调用prvCopydataFromQueue函数从队列中取出消息,接下来将队列中消息数减1。如果再次判断的队列不为空,就给队列解锁,恢复调度器,函数返回,再重新试一次,等待下一个while循环重新执行出队函数。如果队列还有空余,就先解锁,恢复调度器,再重新试一次,函数返回。
2025-05-14 19:12:42
630
原创 基于FreeRTOS和STM32的微波炉
使用STM32F103C8T6、舵机、继电器、加热片、蜂鸣器、两个按键、LCD及DHT11传感器等硬件。进一步,结合FreeRTOS和状态机等软件实现了一个微波炉系统;实现的功能包含:人机交互、时间及功率设置、异常情况处理及固件升级等。
2025-04-17 18:49:06
1235
3
原创 使用循环队列来接收串口信息--以stm32f103为例
在stm32中,一般采用的是通过数组来接收串口信息,但是由于受到数组大小的限制,易出现数据覆盖或者数据溢出问题。针对上述问题,采用循环队列的方式来接收串口信息,循环队列可以动态管理缓冲区并且当队列满时,能灵活选择覆盖旧数据或者丢弃新数据,从而避免了数据混乱问题。
2025-02-17 21:28:42
694
原创 Linux驱动--裸机编程--imx.6ull外部中断
接下来看一下初始化中断表函数system_irqtable_init:上述函数就是为每个中断号注册中断函数,此处进行的初始化操作,将中断函数全部初始化为空函数。最后看一下汇编中需要调用的中断处理函数system_irqhandler:该函数主要是根据传递进来的中断号,在中断函数数组中调用对应的中断函数。接下来就是初始化外部IO中断,初始化函数如下:
2025-01-03 15:46:48
1026
原创 为什么栈的访问速度比堆快及栈开销问题
因为栈的内存分配是编译阶段分配的,自动管理,不知道它用了多少栈的容量,都是分配的固定内存,因此不会产生内存碎片,因此访问速度快。堆则是动态分配的,需要去考虑分配多大的内存,这需要花时间处理,因此容易产生内存碎片(外部碎片和内部碎片),这些碎片会导致内存利用效率下降,增加分配和访问时间,访问速度相对较慢。
2024-10-12 16:34:23
717
1
原创 Linux与RTOS的区别
Linux关注性能和多任务处理,RTOS追求实时响应和确定性。Linux对普通任务使用公平调度;对实时任务使用优先级调度或时间片轮转调度。而RTOS只采用优先级调度。Linux使用,可能有延迟;RTOS使用,确保可预测性。4.Linux用于服务器、桌面等,RTOS用于工业控制等对实时性要求高的应用。
2024-10-11 18:03:57
2696
原创 判断数据在内存中的存储方式算法
这里先定义一个4个字节的数为1,那么它的16进制表示就是00 00 00 01,然后将其地址转换为char类型,此时用*byte,这个表示读取内存中的第一个字节,即内存中低地址处的字节,如果读出来的值是00,代表是大端模式,读出来的是01,就是小端模式。大端是高字节存于低地址,低字节存于高地址。小端是低字节存于低地址。
2024-10-10 18:39:16
459
原创 STM32_startup文件详解
;;</h>ALLGIN代表的是该内存的起始地址对其了2的3次方的边界space代表的是分配内存,这个heap_size是EQU定义的常量上述汇编代码主要是对堆和栈的内存进行分配。
2024-09-12 17:09:44
1487
原创 C++特性--动态内存和智能指针
new和delete与c语言的内存管理函数malloc和free是类似的,都是用于内存的分配与释放。不同的是,new用于分配内存时,会进行对象的创建和销毁,也就是调用构造函数和析构函数。用法:如int* ptr=new int;待变分配了一个int类型的内存给一个指向int类型的指针。释放内存:delete ptr;
2024-09-11 13:29:01
497
原创 C++特性--重载运算符和重载函数
如下示例所示:private:int feet;// 0 到无穷int inches;// 0 到 12public:// 所需的构造函数feet = 0;inches = 0;feet = f;inches = i;// 显示距离的方法。
2024-09-09 17:11:34
974
原创 C++特性---类和对象
构造函数是类的一种特殊的成员函数,这个函数的名字与类名字是完全相同的,而且构造函数不返回任何类型,包括void。析构函数的名称与类的名称是完全相同的,只是在前面加了个波浪号(~)作为前缀,它不会返回任何值,定义其他成员函数,注意这里函数名前添加类名Line::代表这个函数属于这个类,防止函数重名。注意构造函数是这样定义的,定义后只要创建了一个对象,这个函数自动调用。//带参数的构造函数;// 成员函数定义,包括构造函数。//还可以有带参数的构造函数。
2024-09-02 16:39:38
570
原创 Linux调度策略
CFS的全称是completely fair scheduler,意思是完全公平调度。它的目标是让每个任务尽可能公平地获得CPU运行时间。首先定义了一个核心概念--虚拟运行时间(vruntime)用于管理每个任务在CPU上的运行时间。每一个任务都有一个vruntime,这个vruntime是根据任务的优先级和该任务所占权重计算得出的。当该任务运行时,其vruntime会逐渐增加。但是对于不不同优先级的任务来说,vruntime增加的速度是不同的;高优先级的增加慢,低优先级任务增加快。
2024-08-17 16:55:23
955
原创 C语言的内存布局
栈区用于存放函数内的局部变量、参数以及返回地址等,栈是一种后进先出的结构,它由编译器自动分配内存和释放,栈上的数据是临时的,在函数调用结束以后销毁,且栈区的大小是固定的,在程序运行之前就已经确定,访问速度快。堆区是一个动态内存储存区域,用于储存程序运行时的动态内存,它在程序运行时确定堆区大小,由程序员手动管理内存分配和内存释放,如通过调用malloc、calloc以及free函数来进行内存分配以及内存释放。此时a存储在RO段。}此时a是一个指针常量,指向字符串的第一个字符,此时这种情况a是存储在RO段的。
2024-07-09 14:37:09
710
原创 基于ucosii的车载电控单元
通过利用STM32F103C8、直流电机、按键、us015超声波测距模块、MPU6050、蜂鸣器、TFLCD、霍尔传感器等硬件设计一个车载电控单元,实现了手动加档、实时显示车速、超声波避障预警、车身倾斜预警以及更新固件功能,以保证行车安全。
2024-06-30 21:51:19
1670
2
原创 IAP和Bootloader
在main函数中,发生了中断,此时PC指针会跳转到中断向量表去寻找对应的中断服务地址执行对应的中断服务函数,如图3、4所示。最后,我们要利用一个转换工具将keil生成的.hex文件转化为.bin文件,这是因为,hex文件指定了地址,bin文件没有指定地址,很明显,在IAP中,我们不需要系统自行指定,而是需要自己定制,因此需要转换为bin文件,这是keil安装目录下的fromelf.exe应用程序来做的,具体操作为:先点开魔术棒,在user选项卡输入以下内容,请按照自己的安装目录去填充,此处仅供参考。
2024-06-12 17:49:22
3760
1
原创 PendSV和SVC
PendSV异常也叫做可悬挂的系统调用,在操作系统中用于缓期执行一个异常,直到其他重要任务完成以后才执行异常动作,使用PendSV的方法是手工往NVIC的PendSV悬起寄存器里边写入1,即可开启PendSV异常。
2024-06-07 12:03:57
908
原创 关于ucosii操作系统原理------(三)内存管理
当用完这个内存控制块释放时,又将这个内存控制块归还内存控制块链表,用于新的内存分配。同样的,这一步链接成链表的操作也是在系统调用OSInit()函数时候完成的,也是定义了一个数组OSMemTb1[]数组来存放链表的各个节点,因为在OSInit()函数内部会调用OSMemInit()函数,该函数用于将OSMemTb1[]数组的各个元素链接成链表,并且各个节点进行初始化;接下来看看这个函数的源码:
2024-06-03 15:52:27
2596
原创 关于ucosii操作系统原理------(二)任务间通信
在ucosii操作系统中,为了在各个任务之间可以发生数据交换以及通信,因此创造出了信号量,互斥量、邮箱、事件标志组以及消息队列等方法来完成任务间的数据交换以及通信,任务之间传递的这些不同种类的信号被统称为事件,与TCB类似,这里也定义了一个事件控制块(ECB)来管理各个事件。本章节主要是讲解各个任务间通信函数的源码是如何实现的。
2024-06-01 17:29:41
1397
原创 C语言常见错误题
上述代码输出的结果是2,5。原因是在于因此,在(int*)(&a+1)代表的是将整个数组地址右移,此时假设a整个数组的地址是0x1000,那么(&a+1)代表的就是整个数组的地址再右移动一个同样的&a类型的字节大小,也就是a数组有5各元素,一个元素占用4各字节,所以a共占用20个字节,那么(&a+1)的地址就是0x0000+20=0x1014;
2024-05-26 16:29:53
407
原创 bootloader基础概念
Bootloader也叫做引导加载程序。在嵌入式系统上电复位后首先运行引导加载程序,它的功能主要是负责系统的上电自检、必要的硬件初始化、建立储存空间映射,并加载和启动操作系统。Bootloader一般储存在bootROM中,当前使用最多的类型是NOR flash rom,在大多数的嵌入式系统中,flash里边不仅储存了bootloader,还储存了用户程序代码。
2024-05-21 12:15:39
663
原创 c语言程序如何控制硬件?
接下来CPU开始按照PC计数器上的地址顺序读取flash上的指令,这个过程叫做取指,这在CM3上是通过Icode总线去读取的。以后,先进行预处理展开宏定义、去掉注释等生成.i文件,接下来这个i文件会被编译器转换为汇编代码生成S文件,然后把汇编代码转换成目标文件也就是o文件,最后是链接,也就是将多个o文件和库文件链接起来,第二点就是至于跳转到操作系统的入口地址还是用户程序的入口地址,就要看你是跑操作系统还是裸机开发,如果你是裸机开发,就是跳转到用户程序的入口地址。加载操作系统的方式是方式一,也即是直接在。
2024-05-20 22:20:54
1249
原创 关于ucosii操作系统原理---(一)任务调度
因此,ucosii也是借助这一思想,模仿刚被中断时,断点数据入栈,然后在中断程序执行完返回恢复断点数据时,此时把另一个任务的堆栈指针来替换掉当前需要返回的断点任务堆栈指针,不返回断点处继续执行,这样就发生了任务切换。在这个表中,给每一个任务安排了一个二进制位,1代表就绪,否则不就绪。这实际上是用一个U8类型的数组OSRdyTb1[]来充当这个任务就绪表,如下图所示,这是一个可以记录32个任务就绪状态的任务就绪表,这个数组一个元素可以代表8个任务的就绪状态,4个元素就可以代表32个任务的就绪状态。
2024-05-13 16:54:59
2748
2
原创 基于ucosii的厨房预警监测系统
uC/OS-II是一种实时多任务操作系统,由美国嵌入式软件工程师Jean Labrosse开发。它是通过源代码方式提供的,并且具有高度可移植性。uC/OS-II被广泛用于嵌入式系统、物联网设备和其他实时应用中。它提供了任务管理、内存管理、时间管理、中断管理和通信机制等功能,通过这些功能可以实现多个任务的并发执行,并确保任务之间的实时性和可靠性。uC/OS-II还具有较小的内存占用和运行效率高的特点,适用于资源受限的嵌入式系统。uC/OS-II中的每个任务都是一个循环。
2024-04-21 20:45:40
1084
2
空空如也
空空如也
TA创建的收藏夹 TA关注的收藏夹
TA关注的人