自定义博客皮肤VIP专享

*博客头图:

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

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

博客底图:

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

栏目图:

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

主标题颜色:

RGB颜色,例如:#AFAFAF

Hover:

RGB颜色,例如:#AFAFAF

副标题颜色:

RGB颜色,例如:#AFAFAF

自定义博客皮肤

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

原创 RT-Thread线程间同步互斥量

互斥量 (Mutual Exclusion)是一种特殊的、具有所有权属性的二值信号量。形象比喻:独占式停车场。进场(上锁):车进入,门锁住,外面的车必须等待。出场(开锁):里面的车出来,门打开,下一辆车才能进。本质用途:保护临界资源(Critical Section),保证在任意时刻,只有一个线程能访问该资源,防止数据竞争。上一节的第二个历程里面使用二值信号量作为锁,但是这种锁会导致优先级反转,导致实时性崩塌,相对于二值信号量,互斥量主要用于:(1)线程多次持有互斥量的情况下。

2025-11-27 16:28:21 641

原创 RT-Thread线程间同步

上面的历程1展示的信号量的主要功能是:信号量的值初始化成 0,表示具备 0 个信号量资源实例,而尝试获得该信号量的线程,将直接在这个信号量上进行等待当持有信号量的线程完成它处理的工作时,释放这个信号量,可以把等待在这个信号量上的线程唤醒。

2025-11-26 18:38:32 886

原创 RT-Thread时钟管理

操作系统也一样,需要通过时间来规范其任务的执行,操作系统中最小的时间单位是时钟节拍 (OS Tick)

2025-11-25 20:02:40 736

原创 RT-Thread线程管理

RT-Thread 线程管理的主要功能是对线程进行管理和调度系统中总共存在两类线程,分别是系统线程和用户线程,系统线程是由 RT-Thread 内核创建的线程,用户线程是由应用程序创建的线程,这两类线程都会从内核对象容器中分配线程对象,当线程被删除时,也会被从对象容器中删除每个线程都有重要的属性,如线程控制块、线程栈、入口函数等。

2025-11-24 21:41:30 624

原创 RT-Thread内核基础

内核是一个操作系统的核心,是操作系统最基础也是最重要的部分。它负责管理系统的线程、线程间通信、系统时钟、中断及内存等可以看到,最底层是硬件层(Hardware)包括:CPUUARTEMAC各种外设…硬件层之上是BSP 与 CPU 移植层:也叫 CPU 移植层,位于 libcpu/ 目录。作用:提供 CPU 初始化代码提供上下文切换(栈切换)实现提供中断管理机制提供 tick 定时器初始化。

2025-11-22 13:39:04 1015

原创 STM32CubeMX安装教程

前面我们已经成功的配置了Keil的MDK版本,可以实现各种芯片的开发了,但是当我们开发stm32时,我们可以使用CubeMX一键生成脚手架,使用HAL库简便开发。

2025-09-27 13:33:26 1587

原创 配置AC5(ARM Compiler 5)编译器

前面我们按照了Keil MDK 版本,但是上面只有AC6(全称是ARM Compiler 6)编译器,老版本的AC5编译器没有集成上去,如下图:可以看到Compiler Version 5处于Missing的状态,而Compiler Version 6是可以使用的状态,而且可以选择版本为V6.22版本:需要我们自己手动添加,那么为什么我们还要使用老版本的AC5编译器呢?许多传统嵌入式项目(如基于Keil MDK或IAR的工程)依赖AC5的特定语法或编译指令。

2025-09-27 11:24:16 607

原创 STM32编译环境配置/Keil MDK配置

前面一节,我们通过配置STC-ISP和Keil C51实现了51的烧录和在线仿真功能,本节我们将配置Keil的MDK版本,为后面的烧录提公支持,同时讲一下如何添加芯片型号,是我们能够开发各种芯片。

2025-09-27 10:42:01 597

原创 51的烧录与调试

上一篇我们下载了Keil的C51和MDK版本,可以书写代码了,但是如何将我们写的代码烧录/下载到51单片机中呢?这需要使用一个程序:STC-ISP,它是STC公司发明的一种在线调试技术???不是说我们要使用STC-ISP进行代码的下载/烧录吗?这个在线调试是什么东西?实际上,STC-ISP主要有两大功能:1,下载程序 2,在线调试/在线仿真两者的区别很明显:直接下载程序,我们的单片机就会按照程序运行,不会停下;

2025-09-25 18:42:18 459

原创 EEPROM(FM24C256E)移植

下面是EEPROM的结构体 需要我们自己定义一个EEPROM的实例:包括使用的iic,从机地址,锁,写保护引脚(如果WP连接GPIO而不是地)为防止多个操作同时控制EEPROM 导致数据丢失 我们在进行读/写时 先查看锁的状态 等待锁锁住 待操作完成后 再解锁。I2C Speed Mode: Standard Mode (100KHz) 或 Fast Mode (400KHz)就是使用了HAL库的读和写函数 同时定义了一个状态标志位 只有完成读/写 标志位才显示正确。

2025-07-10 14:14:25 451

原创 WouoUI-Page移植

WouoUI 定义了一组标准输入消息,如 msg_up (上), msg_down (下), msg_left (左), msg_right (右), msg_click (确认/点击), msg_return (返回)。WouoUI-Page 只负责生成菜单的像素数据,而如何将这些数据显示到屏幕上,则由用户提供的这个"刷新函数"决定。回调函数处理: 你需要在页面的回调函数中捕获关键的交互消息,主要是 msg_click (确认) 和 msg_return (返回),并根据当前选中的选项执行相应逻辑。

2025-07-08 22:47:56 830 1

原创 u8g2移植

2,u8g2_d_memory文件的其他芯片型号也删除 这里面是内存管理函数 会被下面的启动函数调用 只保留u8g2_m_16_4_f。_alt0:备用方案,会微调几条时序/重映射寄存器(如预充电、扫描方向),用在有特殊要求的版子上。3,u8g2_d_setup文件的其他芯片型号也删除 “f” 代表 full buffer 模式。不同的缓冲模式(全缓冲、页缓冲)需要不同大小的 RAM 缓冲区。1,将我们不需要的型号的底层驱动删掉,减少flash占用。csrc文件是OLED的底层驱动,这里我们需要三处修改。

2025-07-08 15:59:59 565

原创 编码器电机

想想看,如果编码器的分辨率是360PPR,使用四倍频后实际分辨率是多少?如果你的项目需要0.1°的角度精度,应该选择多少PPR的编码器?H桥就是这样的"电子开关组",通过控制四个开关的通断, 让电流从不同方向流过电机,实现正转、反转和停止。• 慢衰减(DIR=0):电流通过续流二极管缓慢衰减,转矩波动小,运行平稳,适合正转和停止。• 四倍频:A/B相90°相位差,可以检测4个边沿(A上升、A下降、B上升、B下降)• 快衰减(DIR=1):电流快速衰减,响应速度快,制动效果好,适合反转和快速停止。

2025-06-26 17:27:13 1031

原创 电机驱动基础

如果用手动开关,由于人手速度有限(最快几Hz),电机会出现明显的启停,无法形成连续转动,就像老式电风扇档位切换时的顿挫感。3D打印机:X、Y、Z轴使用步进电机实现精确定位,挤出机使用直流电机控制材料供给,每一层的精度都依赖电机的准确控制。无人机:四个无刷电机分别控制,通过调节不同电机的转速实现前后左右和旋转运动,电机响应速度直接影响飞行稳定性。核心作用:电机控制技术是这些设备的"肌肉系统",将数字指令转化为精确的物理运动,是实现智能化的关键技术基础。将MCU的弱电信号放大为强电信号,为电机提供足够的电流。

2025-06-24 16:13:59 938

原创 deepseek本地部署

DeepSeek 本地部署是指将 DeepSeek 公司开发的大语言模型(如 DeepSeek-V2、DeepSeek-Coder、DeepSeek-R1 等)部署在你自己的本地计算机、服务器、或者私有云环境中运行,而不是通过官方提供的 API 或网页接口使用。换句话说,本地部署就是数据在自己的设备上运行,而不是交给deepseek官方服务器,数据不出本地的好处就是响应速度快,但是同时需要较强显卡或大内存。

2025-06-22 20:34:18 1269

原创 回归-嵌入式与c概念

因为printf实际上就是调用fputc实现功能的,在标准C库实现中,printf()→vfprintf()→fputc()形成一个调用链。而标准c库其实就是C语言的扩展:是一组预定义的函数、常量和头文件的集合,它提供了基本的输入/输出、内存管理、字符串处理、数学计算等功能。2,C++有自己的标准库:除了C标准库外,C++还有自己的标准库(STL),提供了更高级的功能(如容器、算法、流等)C/C++编译器:专门用于编译C和C++语言的编译器,如GCC中的gcc©和g++(C++)。

2025-06-12 12:12:25 865

原创 SD卡及FATFS文件系统

SD卡以其容量大、成本适中、接口相对简单等优点,成为了扩展存储的常用选择直接操作SD卡的物理扇区非常复杂且低效。为了方便管理SD卡上的数据,我们需要文件系统本节我们将通过SDIO接口(或SPI模式,但本教程重点关注SDIO)使用FATFS文件系统来读写SD卡这里的SDIO模式怎么和SPI模式平起平坐了?

2025-06-11 18:31:54 1585

原创 SPI Flash开发全解(基于GD25Qxx)

上一节我们学习了以ssd1306为例开发iic的流程,本节我们以GD25Q为例学习spi的开发流程。

2025-06-09 19:39:09 1417

原创 OLED(SSD306)移植全解-基于IIC

一种屏幕类型,每个像素都能自己发光,不需要背光大小多为 128×32 或 128×64 像素(像素就是屏幕上最小的发光点),还有一种衡量大小的方式,就是使用对角线长度表示,例如128×32 和 128×64像素数分别对应对角线长0.91英寸 或 0.93 英寸oled如何发光呢?首先其内部会有一个驱动芯片ssd1306,OLED 屏幕多为 128×32 或 128×64 像素(像素就是屏幕上最小的发光点)。那0.91和0.93是什么意思?

2025-06-06 21:12:38 1485

原创 STM32CubeDAC及DMA配置

STM32 的原生 DAC 外设是一个 12 位的数模转换器。它内部有一个“数据保持寄存器”(Data Holding Register)这个寄存器是 16 位宽度的寄存器(2 Byte),但是 DAC 硬件只会读取其中的低 12 位来做真正的数模转换,寄存器高 4 位可以不用,DAC 只关心低 12 位。ST官方在HAL库中提供了三种对齐方式,就是我们的查找表buffer写入到DAC的数据寄存器时,怎么和数据寄存器对齐:就是把一个 12 位数据(0~4095)写入到数据寄存器的低12位。

2025-06-02 14:14:57 1672

原创 STM32CubeMX串口配置

在左边配置选项中选择Connectivity(通信),以串口1为例。

2025-05-31 17:38:49 1954

原创 STM32CubeMX定时器配置

因为只有当 CH2 处于 输入模式 时,硬件才能把这根脚送进滤波器(TI2FP2通道之前要滤波),再生成 TI2FP2 这条支路供 Slave-Mode 控制器使用,也就是说TI2FP2 并不是“独立存在”的,但在CubeMX配置时:如下图,我们只设置Slave Mode和TI1FP1,之后,CH1就自动配置为 Input Capture 了,下图发现,Channel1只能 Input Capture 或者Disable。哪来的主定时器和从定时器呢?把待测 PWM 的高电平当“门”,连接到ETR。

2025-05-31 14:46:07 2537 1

原创 可变参数函数

栈存储了大量数据,当调用函数时会分出一部分空间,这部分空间就是栈帧,储存函数的信息(参数、局部变量、返回地址等)指针类型,在原代码中。va_start会访问最后一个固定变量的位置,再直接规定下一个位置为第一个可变变量。在串口功能中,我们需要访问可变变量,完成传输,arg就是用来储存这些可变变量的。2,va_start 初始化第一个可变参数的位置,并且规定最后一个固定变量。储存可变变量的容器**(arg)有了,我们该如何访问栈帧里的可变变量呢?1,va_list 指针类型,用于指向可变参数列表中的当前位置。

2025-05-28 23:46:07 364

原创 AD/DA HAL库API

前面我们通过实例了解了 AD/DA 转换的几种常用方法。这些方法的实现都离不开 STMicroelectronics 提供的 HAL (Hardware Abstraction Layer) 库。HAL 库封装了底层的寄存器操作,提供了统一、易用的 API 接口。理解这些核心 API 对于灵活运用 AD/DA 功能至关重要。本节将深入探讨我们在之前章节中使用到的关键 HAL 函数和宏。

2025-05-28 17:30:22 953

原创 UART通信HAL库API

uwTick是超时判断的基石: 在我们的超时解析逻辑 if (uwTick - uart_rx_ticks > UART_TIMEOUT_MS) 中,uwTick 提供了当前的精确时间,uart_rx_ticks 保存了上次收到字节的时间戳,两者相减就得到了时间间隔,从而判断是否超时。Size: 至关重要!每次调用它,就好比你跟前台说:“嘿,请帮我留意一下,下一个(而且仅仅一个,因为我们Size=1)送来的包裹,到了之后立刻(中断方式)通知我(触发中断),并把它放到这个指定的位置(pData指向的内存)。

2025-05-28 16:40:33 1097

原创 STM32环境搭建

然后会跳出添加到哪里的彩单,如下图,我们将它添加到keil_v5中,不要点进C51或UV4,点击确定,会提示单片机型号添加成功。在stc右边的菜单栏,找到keil仿真设置,选择单片机型号IAP15F2K61S2,然后点击添加,如下图。在51中,我们使用stc-isp添加芯片型号,而在32中,我们可以直接安装芯片包,就是下图中的packs。然后会跳出安装packs的提示,我们不用在这里安装:这里先按下图操作,取消勾选,点击ok,点击×。选择安装路径,路径名字不能有中文,尤其是“-”,只能有英文和下划线"_"

2025-05-25 01:46:20 1259

原创 蓝桥杯框架-按键数码管

上一节已经一步步移植了led模板,本节移植按键和数码管的模板,但我不会再教移植,我直接给出main.c,key.c,key.h,seg.c,seg.h,init.c,init.h的代码,你们自己移植。Key_Down的值等于板子上按键的丝印号,如S7按下的一瞬间Key_Down等于7。Key_Old的值也等于板子上按键的丝印号,如S7一直按下,则Key_Old一直为7。所有的.h代码:引用单片机的头文件+.c中函数的声明。表示第一个数码管显示0。

2025-05-20 13:57:14 719

原创 蓝桥杯框架-LED蜂鸣器继电器

框架移植完毕,我们可以随意操作led了:在框架中,Led_Proc函数是空的,加入以下三句话就可以点亮第一,三,四个led。在.c文件中右键,导入头文件:keil自动帮我们加入了单片机的头文件,我们将他Ctrl X下来,粘贴到led.h中。左上角的Text1是我们Ctrl N是生成的文件,我们将他保存在User下面,并且命名为main.c,如下图操作。可以看到keil的文件管理:led.c已经添加进来了,那led.h怎么添加呢?在扳手中添加,如下图:将led.h文件的上一级文件Driver添加进来即可。

2025-05-19 13:39:57 574

原创 STM32SPI实战-Flash模板

上一节介绍了通用的SPI模块的开发流程,本节以GD25QXX系列FLASH芯片为例,移植Flash模板我们提供的GD25QXX驱动库 (gd25qxx.c 和 gd25qxx.h) 封装了与SPI FLASH通信的底层细节,提供了一系列简单易用的API函数供上层应用调用。这些函数依赖于STM32 HAL库的SPI和GPIO功能。

2025-05-18 23:12:14 1030

原创 STM32SPI通信基础及CubeMX配置

CPOL 和 CPHA 的组合定义了四种 SPI 工作模式:模式 CPOL CPHA 描述 (空闲电平, 采样边沿)0 Low (0) 1 Edge (0) 空闲低,SCK 第一个边沿采样1 Low (0) 2 Edge (1) 空闲低,SCK 第二个边沿采样2 High (1) 1 Edge (0) 空闲高,SCK 第一个边沿采样3 High (1) 2 Edge (1) 空闲高,SCK 第二个边沿采样重要: 必须查阅从设备的数据手册,选择其支持的 SPI 模式。

2025-05-18 11:07:53 2448

原创 STM32IIC实战-OLED模板

在掌握了基础的单片机控制和通信之后,是时候为你的项目添加一块小巧而酷炫的显示屏了。OLED (Organic Light-Emitting Diode) 屏幕因其自发光、高对比度、低功耗和宽视角等优点,在嵌入式项目中越来越受欢迎。本教程将重点介绍如何驱动基于 SSD1306 控制芯片的单色 OLED 显示屏,这种屏幕通常分辨率为 128x64 或 128x32,常用于显示文本、简单图形和状态信息。

2025-05-17 18:57:43 1437

原创 STM32IIC协议基础及Cube配置

I²C(Inter-Integrated Circuit,读作"I-squared-C")是一种由飞利浦公司(现恩智浦半导体)开发的串行(一根数据线)通信总线,广泛应用于连接微控制器和低速外围设备。

2025-05-17 17:06:19 1716

原创 STM32外设DA实战-DAC + DMA 输出正弦波

因为 DAC 数据寄存器通常只需要写入有效数据位(如 12 位),并且我们的查找表是 uint16_t 类型,所以 DMA 的外设和内存宽度都设置为 Half Word (16位) 是最自然、最高效的配置。4,DMA 自动"喂数据": 配置 DMA 通道,在每次接收到定时器触发信号后,自动从内存中的正弦波查找表里取出下一个样本点,写入 DAC 的数据保持寄存器 (DHR)。: 启动作为触发源的定时器。(中心值,大约是 2047.5),将波形整体向上平移,使其中心对准 DAC 输出范围的中点。

2025-05-17 12:54:00 2623

原创 STM32外设AD-定时器触发 + DMA读取模板

说明: 此处输入的应为定时器的实际输入时钟频率,通常是经过 APB 总线分频后的频率(例如,若 APB1 时钟为 72MHz 且定时器时钟未被进一步分频,则输入 72),而不是 CPU 的主频(如 180MHz)。通常选择内部时钟 (Internal Clock),其频率与 APB 总线时钟相关(例如,如果 APB1 时钟是 72MHz,那么 TIM3 的时钟基频通常也是 72MHz 或其倍频)。上面的方法需要定时器精确控制每次数据块采集的启动频率,你需要根据期望的数据块采集间隔来设置定时器的触发频率。

2025-05-16 21:29:28 2678

原创 STM32外设AD-DMA+定时读取模板

您可能注意到,即使我们的 ADC 缓冲区 adc_dma_buffer 定义为 uint16_t 类型(因为 12 位或 16 位 ADC 的结果适合用 16 位整数存储),在调用 HAL_ADC_Start_DMA 时(形参adc_dma_buffer 是32位,我们却将其强制转换为了 uint32_t*。但是,因为 ADC 的有效数据通常在低 16 位,所以我们访问 adc_dma_buffer[i] 时,通常能正确获取到需要的转换结果(存储在内存的低 16 位部分)。CPU 会定期读取这里的数据。

2025-05-16 19:59:33 1230

原创 STM32外设AD-轮询法读取模板

想象一下你要去楼下信箱取信:你走到信箱旁 (HAL_ADC_Start(&hadc1);- 启动一次转换)。你站在那里一直等,直到邮递员把信投进去 (HAL_ADC_PollForConversion(&hadc1, timeout);- 循环检查转换完成标志位,直到超时)。邮递员投完信后,你打开信箱,取出信件 (adc_val = HAL_ADC_GetValue(&hadc1);- 读取转换结果)。

2025-05-16 15:43:18 1265

原创 STM32外设AD/DA-基础及CubeMX配置

我们已经掌握了如何让单片机通过 UART 与外界"交流"。但是,现实世界充满了连续变化的模拟信号,比如温度、光线强度、声音大小等等。单片机内部处理的是离散的数字信号,如何让它们互相理解呢?这时,ADC (Analog-to-Digital Converter, 模数转换器) 和 DAC (Digital-to-Analog Converter, 数模转换器) 就派上用场了!ADC: 就像一位"翻译官",把现实世界的模拟语言(连续变化的电压)翻译成单片机能懂的数字语言(离散的数值)。

2025-05-16 14:16:09 2106

原创 STM32串口UART实战-DMA + 空闲中断解析法

HAL_UARTEx_ReceiveToIdle_DMA可以开启数据接收知道空闲,函数HAL_UART_IRQHandler留意串口总线上的空闲状态,一旦检测到空闲1即再次开启HAL_UARTEx_ReceiveToIdle_DMA接收数据,关闭__HAL_DMA_DISABLE_IT半满中断“空闲"的定义:在 UART 通信中,当没有数据传输时,通信线路(RX 线)会保持在高电平状态(逻辑 ‘1’),这被称为"空闲状态"或"标记状态 (Mark State)”。

2025-05-15 14:42:47 2363

原创 8051模板移植

编译一下,发现5个报错:2个EEPROM函数和3个LED函数没有调用。接下来将桌面上的文件(main.c和底层.c)添加到Keil。出现下图情况,选择是,然后会多出一个启动文件,以后有用。在工程文件下建立Driver和User。建立main.c文件,保存到User。打开Keil,点击扳手选择芯片型号。将桌面上的头文件路径添加到Keil。将下面的代码粘贴到main.c。按照下图,勾选生成hex文件。将模板粘贴到Driver下。

2025-05-10 11:29:46 316

原创 STM32串口UART实战-串口接收超时解析法模板

上一节单片机发送了数据,本节将讲解超时解析法让单片机完成数据接收。

2025-05-10 08:14:04 1365

空空如也

空空如也

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

TA关注的人

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