- 博客(86)
- 收藏
- 关注
原创 nRF52840 BLE 多服务开发中 NRF_ERROR_NO_MEM(0x00000004)的排查与解决
代码层面增大 GATT 属性表(最重要):Cble_cfg.gatts_cfg.attr_tab_size.attr_tab_size = 0x1400;每个 GATT 服务和特征都需要在属性表中占用空间,LBS 服务初始化时申请内存失败,导致 ble_lbs_init() 返回 NRF_ERROR_NO_MEM。建议在 ble_stack_init() 中主动配置 attr_tab_size、conn_cfg 等关键参数。0x00000004 对应 NRF_ERROR_NO_MEM(内存不足)。
2026-04-12 22:27:39
184
原创 解释Nordic nRF52的低功耗
当应用调用 sd_app_evt_wait() 时,SoftDevice 会将系统置于 System ON 低功耗模式。在这种状态下,CPU 可以运行,外设可用,功耗相对较高。:芯片的深度休眠模式,核心功能(CPU、大部分时钟和外设)的电源被切断,功耗极低(约0.3μA)。:芯片的深度休眠模式,核心功能(CPU、大部分时钟和外设)的电源被切断,功耗极低(约0.3μA)。,调用 sd_power_system_off(),使芯片进入 System OFF 深度休眠模式,唤醒后会复位重启。
2026-04-10 21:47:18
449
原创 从四个 ble_evt_handler 看 Nordic BLE 架构:模块化解耦与优先级控制
在 Nordic SDK 的 BLE 应用中,多个文件(如main.c)都定义了一个名为的函数。这并不是代码错误或重复,而是的典型应用。
2026-04-07 20:02:11
160
原创 UUID----私有服务与公有服务
公有 = 官方身份证,大家都认识,直接用短号码。私有 = 自己印的身份证,先把模板交给协议栈备案(sd_ble_uuid_vs_add),然后用短号码 + 类型。
2026-04-06 22:09:38
38
原创 Nordic SDK BLE 服务指针机制完整总结 —— 以 Battery Service 为例
注册时把 &m_bas 交给系统 → 事件发生时系统把 &m_bas 塞到 p_context 里 → 函数里 p_bas = (ble_bas_t *)p_context;→ 从此 p_bas 就代表了 m_bas。
2026-04-06 15:59:29
198
原创 通过观察nRF52服务的回调,解释两种回调函数的区别,以及为什么看不到他们回调函数的调用
只要是 BLE 服务相关的回调:led_write_handler、on_bas_evt、ble_evt_handler全部 ← 主循环上下文全部 ←SoftDevice产生事件,事件(在事件观察者中)触发回调只有外设驱动(ADC、定时器、UART、GPIO)才 ←硬件产生中断,中断产生事件,事件(在事件观察者中)触发回调SoftDevice 会产生很多具体可见的事件,你在代码里完全能看到,不是“看不到的”。
2026-04-04 14:30:39
225
原创 蓝牙5.0协议、初始化及服务创建的关系
你不需要管 L2CAP/ATT/SMP 怎么初始化,SoftDevice 已经做好了。你只需要配置 GAP(设备名、广播、连接参数)和GATT(添加你需要的服务)。增加一个服务,就是用 GATT 的 API(比如)去注册一个服务结构体,里面包含特征和回调。
2026-04-03 12:49:03
155
原创 nrf52840蓝牙----私有服务的建立
把你的开发板(nRF52)想象成一台(或者手机里的存储空间)。的目的就是: 你在 U 盘里,并告诉手机“我的文件夹和文件长什么样、叫什么名字、能不能读写”。如果不建立这些,手机连上你的 U 盘后会发现里面是空的,什么文件夹和文件都没有,就没法控制你的 LED 了。
2026-04-02 17:34:24
743
原创 nRF5 SDK 添加自定义服务(LBS)后,nRF Connect 中无法自动显示服务,需要手动 Refresh services才能看到
代码中 ble_lbs_init() 函数返回成功,串口日志也明确打印 “LBS service initialized successfully!”,表明服务已在设备端正确注册到 GATT Server。在使用 Nordic nRF5 SDK(基于 nRF528xx 等芯片)开发 BLE 外设时,我在模板工程中成功添加了。只有手动点击右上角菜单,选择。后,该服务才会突然显示出来。
2026-04-02 16:06:21
43
原创 BLE服务和Freertos的任务(Task)、函数有什么区别
Nordic nRF5 SDK 中的 BLE 服务采用的是 观察者模式(Observer Pattern) + 事件驱动(Event-Driven) 机制。服务是由观察者(Observer)的形态,不需要自己调用。,至于什么是观察者,我在前面的。二、新建一个服务需要的内容。
2026-04-01 23:11:00
40
原创 Keil更改RAM地址
当你修改了配置(例如增加连接数、启用更多功能),SoftDevice 需要更多 RAM,但链接脚本中的偏移量(RAM 起始地址)没有同步增大,就会导致 SoftDevice 初始化时发现预留空间不足,从而报错并提示你增大偏移量。,而 SoftDevice 的占用大小取决于你的配置(例如最大连接数、ATT MTU、安全参数等)。当你添加新的 BLE 服务时,例如增加了一个自定义服务(LBS),GATT 属性表的条目数增加了。协议栈运行时需要占用的 RAM(包括连接上下文、属性表、GATT 缓存等)。
2026-04-01 22:49:36
303
原创 事件观察者NRF_SDH_BLE_OBSERVER,变量的“文件锁”与指针的“后门”——BLE 服务实例初始化剖析
BLE 事件观察者NRF_SDH_BLE_OBSERVER是 Nordic SDK 中用于注册 BLE 事件观察者的宏。它让不同模块能够独立处理自己关心的 BLE 事件,而无需把所有处理逻辑都塞进一个函数中。概念说明宏定义 LBS 模块实例,并自动注册一个 BLE 事件观察者,将模块的事件处理函数挂载到 SDK 的事件分发链中。观察者注册通过链接段收集所有观察者,SDK 在 BLE 事件发生时遍历该段,调用每个观察者的回调。事件触发流程。
2026-04-01 15:44:44
523
原创 捕获Nrf52蓝牙广播包
若无连接,自动切换到慢速广播(约 562.5 ms 间隔),并持续下去。若抓包显示连接后仍有广播包,可能是工具显示残留,或设备异常重启了广播,需检查代码中是否有手动重启广播的逻辑。实测 481 μs 属于抓包工具计算误差,本质是同一事件内的快速重传,用于提高被扫描到的概率。(单位 0.625 ms),理论 187.5 ms,实测 188.561 ms,符合预期。抓包中观察到的 188.561 ms → 561.958 ms 变化,完美符合这一设计。之间的时间,表示设备每隔约 188 ms 发起一轮广播。
2026-04-01 13:34:28
291
原创 服务与任务的区别,以及解释蓝牙初始化的MTU、UUID和GATTS
MTU 在 BLE 中特指 ATT_MTU(Attribute Protocol Maximum Transmission Unit),即属性协议层允许的最大数据包大小。默认值:23 字节(其中 3 字节用于 ATT 头部,实际有效负载为 20 字节)。作用:MTU 越大,单次传输的数据量越大,可减少通信次数,提升吞吐量。如果 不是默认的 23,则通过 配置 MTU 大小。配置后,协议栈会在连接建立时协商该 MTU 值。UUID 用于唯一标识 BLE 中的服务(Service)、特征(Character
2026-03-30 20:29:30
397
原创 一次因 MPU6050 硬件异常导致的 nRF52840 启动卡顿问题总结
在默认配置下,若总线被拉低,会进入无限等待或长时间超时。:蓝牙协议栈启用后,系统空闲时会自动进入低功耗模式,可能延迟中断响应,使 I2C 驱动的等待时间被进一步拉长,最终表现为分钟级的卡顿。:MPU6050 模块存在供电不稳、接触不良或上拉电阻缺失等问题,导致其 SDA/SCL 引脚异常,将 I2C 总线持续拉低。该现象在使用纯蓝牙模板工程(未包含任何传感器初始化代码)时同样复现,说明问题与硬件连接强相关,而非软件主动访问传感器所致。系统上电后,串口日志在输出少量初始化信息后长时间停顿(约 2 分钟)。
2026-03-27 22:59:21
235
原创 协议栈烧录问题
第一个是nrf52840_xxaa是项目程序,第二个flash_s140_nrf52_7.2.0_softdevice是协议栈。协议栈(SoftDevice)只需要烧录一次,之后更新应用程序时不需要再重新烧录它。断电后不需要重新烧录协议栈,只要芯片没有被整片擦除,协议栈会一直保留在 Flash 中。
2026-03-27 17:47:43
36
原创 软件定时器
如下:(TIMER0–TIMER4),均为 32 位精度,支持定时、捕获/比较、PWM 生成(通过 PPI 联动)等功能。此外,它还有实时计数器(RTC0–RTC2),通常用于低功耗时间管理。并非独立硬件,而是构建的软件机制。其核心原理是:维护一个有序的超时列表,在硬件定时器的中断中检查列表,当某个定时器到期时,执行对应的回调函数。软件定时器确实是。之所以叫“软件定时器”,是因为它,而是通过一段软件代码来管理多个定时事件。
2026-03-26 16:10:48
309
原创 内部 RAM,内部 Flash外部 以及W25Q16 (SPI Flash)
nRF52832 的(32 KB 或 64 KB,取决于具体变体,如 QFAB 是 32 KB,QFAA 是 64 KB)和(256 KB 或 512 KB)虽然已经不少,但对于很多实际的蓝牙应用来说,,尤其是需要存储大量数据的场景。这就是为什么像青风/青云开发板(或很多 nRF52832 项目)会外挂(16 Mbit = 2 MB 的 SPI NOR Flash)的原因。
2026-03-22 17:11:24
365
原创 DMA和EasDMA的区别和配置与使用
是一种让外设不经过 CPU 直接读写内存的数据传输架构;而是(nRF52 系列,如 nRF52840)为其特定外设(如 PWM、SPI、I2S 等)内部集成的。
2026-03-22 12:27:49
305
原创 NRF芯片下的ADC采集
ADC为Analog-to-Digital Converter 的缩写,指模/数转换器或者模数转换器。是指将连续变化的模拟信号转换为离散的数字信号的器件。对应真实世界的模拟信号,。在nrf52840中的ADC为一个逐次逼近(successive-approximation)模拟数字转换器,所有nrf52840中的内部ADC称为:SAADC。其具体的属性如下所示:nRF52840 的 SAADC 具有以下主要特点::12 位(0 ~ 4095),可通过过采样获得更高有效位数。
2026-03-21 22:41:42
187
原创 关于频率(HZ)与周期(ms)的转换
如果想问“一秒有多少个 kHz”,那 1 秒就是 1/1000 个 kHz,这没意义。看门狗超时后,硬件会等待两个 LFCLK 周期(约 61 微秒) 才复位,因此回调中无法执行耗时操作(如延时 1 秒),系统很快复位。频率 = 每秒振荡次数,所以 32.768 kHz 表示每秒钟振荡 32,768 次。配置看门狗,设置回调函数 wdt_event_handler,并分配喂狗通道。若未及时按键,看门狗超时(约 2 秒,由默认配置决定),触发回调。若按键按下,则喂狗(清零计数器),同时点亮 LED2 指示。
2026-03-21 20:36:56
220
原创 RTC时钟源及其低功耗应用
RTCSYSTICKSysTick:SysTick 通常被配置为,作为 RTOS 的“心跳”。每次中断都会触发任务调度,检查是否有更高优先级的任务就绪,或是否到达当前任务的时隙。:SysTick。比如你可以用它实现HAL_Delay就是基于 SysTick)、等。所以它并不是 RTOS 专属,只是 RTOS 依赖它作为调度驱动。RTC。
2026-03-20 20:39:02
368
原创 关于nRF定时器+中断问题
nRF 一般不用中断,而是优先用事件 + PPI,因为这是 Nordic 为低功耗、无线应用量身打造的“杀手级”特性——硬件自动化、零 CPU 干预、极致省电。需求:外部传感器每产生一个脉冲(上升沿),计数 +1,当累计 500 个脉冲时产生中断(做采样或报警) counter == CC[0] == 500。(Overflow interrupt),而是。的方式,就可以驱动其他事件了,不需要下面的使能中断。counter 值 == CC[n] 的值。四、通过使用(定时器+中断)的缺点。
2026-03-12 17:09:00
58
原创 解释GPIOTE及其PPI应用
GPIOTE全称是 GPIO Tasks and Events(GPIO 任务与事件)。它是Nordic Semiconductor nRF 系列SoC(比如 nRF52、nRF53、nRF91、nRF54 系列等)中一个非常重要的硬件外设模块。GPIOTE模块通过事件模式(Event mode)让普通GPIO引脚能够产生中断(或更精确地说:生成可触发中断的事件。
2026-03-10 22:19:06
205
原创 区别于STM32,为什么NRF看不到回调函数调用的地方
问题:我调用了 HAL_UART_Transmit_IT() 或 HAL_UART_Receive_IT(),这里面使能了中断,且中断回调函数被调用了,代码里完全看不到 HAL_UART_TxCpltCallback() 或 HAL_UART_RxCpltCallback() 被调用,为什么回调函数还是能执行?
2026-03-01 21:36:03
104
原创 Nordic系列芯片中断函数及中断回调函数
Nordic Semiconductor 是一家专注于超低功耗无线通信的半导体公司,其芯片系列在物联网(IoT)领域,特别是低功耗蓝牙(Bluetooth LE)市场中占据着领先地位。其产品线涵盖了从短距离到蜂巢式蜂窝通信的广泛需求。,两个名字几乎一样,就差一个。后缀,一看就知道是回调。
2026-03-01 10:53:06
39
原创 关于keil添加了头文件仍然报找不到头文件的问题
4)点击魔术棒中的C/C++,将包含该头文件的最内层文件夹包含进去,一定要包含最内层文件夹!原文链接:https://blog.csdn.net/qq_39681558/article/details/105210811。2) 如果工程中的路径存在数字开头,则keil无法识别该路径,需要修改为以英文字符开头。1) 如果工程中有中文路径,keil是无法识别中文路径的,需要修改为英文路径。3) 如果修改了工程中的文件夹名,则需要重新将文件夹包含到工程中。于是我引用的路劲简化一下,直接lcd.h,就成功了。
2025-08-01 10:59:15
903
2
原创 通过BUG(prvIdleTask、pxTasksWaitingTerminatio不断跳转问题)了解空闲函数(prvIdleTask)和TCB
在没有其他任务可运行时(没有任何其他任务处于就绪态时)保持 CPU 忙碌这是 FreeRTOS 内部函数(定义在 tasks.c 中),负责检查并清理 pxTasksWaitingTermination 列表中的已删除任务。当任务被 vTaskDelete 标记为待删除时,FreeRTOS 将其 TCB 加入该列表。prvCheckTasksWaitingTermination 会释放 TCB 和栈内存,但前提是任务列表有效且资源可用。
2025-06-05 21:46:45
1574
原创 FreeRTOS中如何检查信号量上锁和解锁
通过 uxMessagesWaiting,可以准确判断 FreeRTOS 互斥量的上锁和解锁状态。初始化后 uxMessagesWaiting = 1 表示未锁,加锁后变为 0 表示被锁。调试时需注意断点位置和堆内存配置,以确保状态显示正确。
2025-06-05 11:17:44
268
原创 Keil 中因未引入源文件导致的函数调用与索引失败:从找不到定义到全局搜索无效
找到项目文件,通常是 F103_Moduel.uvproj 或 F103_Moduel.uvprojx,位于项目根目录。用文本编辑器(如 Notepad++)打开该文件。搜索 random.c(Ctrl+F 输入 random.c)。
2025-06-03 13:29:36
527
原创 HardFault_Handler调试及问题方法
如下所示我们找到SP寄存器,0x20001F40即为栈地址,栈里面的值依次为R0~R3、R12、PC(Return address)、xPSR(CPSR或SPSR)、LR。接下来在keil_MDK工程中,编译代码,并debug,之后全速运行,可以看到如下图所示程序进入HardFault异常。有两个连续08开头的,这是两个地址,第一个地址是卡住的具体位置,第二个是卡住的具体函数。),点击go to即找到出现异常的代码段附近下面要执行的程序。点击黄色,就跳到了卡住的具体位置。
2025-05-23 16:16:38
467
原创 printf调试时候正常,运行时打印不出来
问题是在添加了 printf 功能后,程序独立运行时无法正常打印输出,而调试模式下正常。这表明问题可能与 printf 的重定向实现、标准库配置、或编译器相关设置有关。原来是使用 Keil/IAR,printf可能需要启用。
2025-05-10 20:42:49
458
原创 not a genuine st device abort connection的问题
2.然后在Other里面把Enabled的钩子去掉。1.魔法棒里面电机Settings。
2025-05-10 19:48:37
389
原创 出一期Source Insigned的使用教程
比如在这里面注释掉gpio.h,ctrl+s之后,keil也会显示gpio.h,注意这个keil的文件必须是source insight使用的文件。之后会显示右边这一栏,如果没有,需要按照下图步骤进行。点add tree,递归添加,然后确定,就可以了。第一个是你要命名的名字,第二个是你想储存的路径。Ctrl+S(可以实现编辑了)选择你要解析的文件路径。
2025-05-08 21:13:39
1708
原创 蓝桥杯----单片机备战笔记
bit 是 C 语言中的一种数据类型,通常由特定编译器(如 Keil C51 或 SDCC)扩展支持,用于声明一个单比特变量。sbit定义:sbit 是“special bit”的缩写,是特定编译器(如 Keil C51)提供的关键字,用于声明直接映射到硬件寄存器(如端口、控制位)的单比特变量。十三、u8 i 和 int i 在for循环中引起的区别。
2025-05-05 11:43:49
1053
原创 Freertos--统计所有任务栈信息以及CPU占比和钩子函数
空闲函数(Idle Task):FreeRTOS 自动创建的一个任务,优先级最低(0),在没有其他任务可运行时执行。它的主要作用是执行空闲任务逻辑,例如进入低功耗模式或清理已删除任务的资源。钩子函数(Idle Hook Function):也叫空闲任务钩子,是用户定义的一个函数,FreeRTOS 允许你在空闲任务中调用它。钩子函数不是空闲函数本身,而是空闲任务在每次循环时可以调用的一个用户自定义函数。
2025-04-25 17:27:46
1503
原创 Freertos----中断管理
在RTOS中,需要应对各类事件。这些事件很多时候是通过硬件中断产生,怎么处理中断呢?假设当前系统正在运行Task1时,用户按下了按键,触发了按键中断。你要注意到,ISR是在内核中被调用的,ISR执行过程中,用户的任务无法执行。
2025-04-24 20:59:14
456
空空如也
空空如也
TA创建的收藏夹 TA关注的收藏夹
TA关注的人
RSS订阅