尝试结合STM32F401的ADC, PWM, SPI(NRF24L01)和TIM, 试验了一下音频的无线传输(对讲机原型)

工作机制

音频采样

因为硬件的限制, 包括STM32F401片内存储, 内存大小, PWM频率, 以及之前实际测试NRF24L01得到的经验数据, 采样使用了最基础的8bit分辨率, 采样频率为16KHz附近

  • SYSCLK使用25MHz, APB2CLK使用一半频率, 即12.5MHz
  • ADC在APB2CLK基础上8分频, 所以ADC时钟为12.5MHz/8
  • ADC使用8bit分辨率, 对应11个ADC时钟, 采样周期设置为84, 所以每次采样为95个ADC周期, 这样实际采样频率为 12500000 / 8 / 95 = 16,447 Hz, 接近16KHz
  • 使用ADC2DMA, DMA使用一个32byte大小的uint8_t数组

无线传输

  • 使用fastwrite机制, 即一直保持在发状态, 只要FIFO TX队列未满就一直往里写, 如果满了就检查MAX_RT标志位, 如果置位则拉低再拉高CE重置发送状态
  • 采样端使用DMA的传输完成中断, 对应32个byte的DMA内存, 每次采集满32个byte都会触发中断, 此时调用NRF24L01进行发送
  • 接收端使用IRQ中断接收, 创建一个128Byte的接收数组, 循环写入. 每次接收中断就往里面写32个byte, 往后增长, 到右边界后再从0开始

音频输出

  • 接收端也使用25MHz的SYSCLK
  • 接收端启用PWM输出, 输出分辨率为8bit
  • 接收端启用Prescaler=0, Period=1561的定时器TIM3, 这个配置对应的频率为 25000000 / (0 + 1)(1561 + 1) = 16,005 Hz, 接近16KHz. (注: 这里频率选择有些问题, 应该要比发送端频率略高, 这样才能保证在持续发送中, 播放不被接收打断)
  • 每次定时器触发中断, 都会在128byte的接收数组中检查是否有新数据, 有则前进一格并以此值修改PWM占空比, 无则跳过. 如果已经到达数组右边界则返回到数组0下标.

电路

输入端电路

输入端使用一个驻极体二极管加S9014组成简单的放大电路. 电路图取自网图, 元件的取值说明

  • R1 取值范围在1KR至3.3KR, 不要超过5KR, 否则声音太小
  • C1 取值范围在0.1uF至1uF都可以, 不要太小
  • R2 可以用1MR至1.5MR
  • R3 取值10KR
  • Q1 使用任意小功率NPN三极管均可, 实测过9013, 9014, 8050, 2N222, 基本没区别
  • C2 10uF的独石电容或更大的47uF的电解电容都可以

输出端电路

输出端先经过以及RC低通滤波(R=20, C=10uF), 再使用PAM8403进行放大

项目代码

项目代码在Github: https://github.com/IOsetting/stm32f4-hal-projects/tree/main/Projects/WalkieTalkieDemo

可以使用Keil5 MDK打开和编译

测试记录

  1. 采样: 采样工作正常, 观察输出可以看到有动静时采样值的变化
  2. 传输: 仅在10米以内距离测试, 出现MAX_RT标志的比例很小, 至少从16KHz采样, 32byte一个package的发送速率看, 发送和接收都不是瓶颈. 当有墙体阻挡时错误率上升明显
  3. 播放: 背景噪音大, 在近距离时容易互相干扰产生啸叫. 播放效果较差, 沙沙声明显. 在加入低通滤波后能听清人声, 但是依然未能达到"能听"的水平.

电路部分原型

电路部分原型

发送端

下一步

因为传输不是瓶颈, 所以改进的方向主要是音质. 可能需要从几个方面进行排查:

  1. 播放方面. 这块是比较容易排查的, 比如使用单频音源输出, 使用预录的音源输出, 需要评估使用多高的PWM频率以及RC滤波参数能达到可接受的播放效果
  2. 采样方面. 如果有示波器会很方便, 没有示波器的话, 只能通过ADC采样的输出来判断, 需要写代码将数组输出到存储, 需要加一些片外存储

参考

STM32F401+nRF24L01无线传输音频(对讲机原型)的更多相关文章

  1. STC8H开发(八): NRF24L01无线传输音频(对讲机原型)

    目录 STC8H开发(一): 在Keil5中配置和使用FwLib_STC8封装库(图文详解) STC8H开发(二): 在Linux VSCode中配置和使用FwLib_STC8封装库(图文详解) ST ...

  2. STC8H开发(九): STC8H8K64U模拟USB HID外设

    目录 STC8H开发(一): 在Keil5中配置和使用FwLib_STC8封装库(图文详解) STC8H开发(二): 在Linux VSCode中配置和使用FwLib_STC8封装库(图文详解) ST ...

  3. STC8H开发(十): SPI驱动Nokia5110 LCD(PCD8544)

    目录 STC8H开发(一): 在Keil5中配置和使用FwLib_STC8封装库(图文详解) STC8H开发(二): 在Linux VSCode中配置和使用FwLib_STC8封装库(图文详解) ST ...

  4. STC8H开发(十一): GPIO单线驱动多个DS18B20数字温度计

    目录 STC8H开发(一): 在Keil5中配置和使用FwLib_STC8封装库(图文详解) STC8H开发(二): 在Linux VSCode中配置和使用FwLib_STC8封装库(图文详解) ST ...

  5. STC8H开发(十二): I2C驱动AT24C08,AT24C32系列EEPROM存储

    目录 STC8H开发(一): 在Keil5中配置和使用FwLib_STC8封装库(图文详解) STC8H开发(二): 在Linux VSCode中配置和使用FwLib_STC8封装库(图文详解) ST ...

  6. STC8H开发(十三): I2C驱动DS3231高精度实时时钟芯片

    目录 STC8H开发(一): 在Keil5中配置和使用FwLib_STC8封装库(图文详解) STC8H开发(二): 在Linux VSCode中配置和使用FwLib_STC8封装库(图文详解) ST ...

  7. STC8H开发(十四): I2C驱动RX8025T高精度实时时钟芯片

    目录 STC8H开发(一): 在Keil5中配置和使用FwLib_STC8封装库(图文详解) STC8H开发(二): 在Linux VSCode中配置和使用FwLib_STC8封装库(图文详解) ST ...

  8. STC8H开发(十五): GPIO驱动Ci24R1无线模块

    目录 STC8H开发(一): 在Keil5中配置和使用FwLib_STC8封装库(图文详解) STC8H开发(二): 在Linux VSCode中配置和使用FwLib_STC8封装库(图文详解) ST ...

  9. STC8H开发(十六): GPIO驱动XL2400无线模块

    目录 STC8H开发(一): 在Keil5中配置和使用FwLib_STC8封装库(图文详解) STC8H开发(二): 在Linux VSCode中配置和使用FwLib_STC8封装库(图文详解) ST ...

  10. SDL开发笔记(二):音频基础介绍、使用SDL播放音频

    若该文为原创文章,未经允许不得转载原博主博客地址:https://blog.csdn.net/qq21497936原博主博客导航:https://blog.csdn.net/qq21497936/ar ...

随机推荐

  1. Ubuntu安装jdk的步骤

    .markdown-body { line-height: 1.75; font-weight: 400; font-size: 16px; overflow-x: hidden; color: rg ...

  2. [转帖]一文深度讲解JVM 内存分析工具 MAT及实践(建议收藏)

    https://juejin.cn/post/6911624328472133646 1. 前言 熟练掌握 MAT 是 Java 高手的必备能力,但实践时大家往往需面对众多功能,眼花缭乱不知如何下手, ...

  3. [转帖]MySQL如何在InnoDB中重建索引并更新统计数据?

    https://geek-docs.com/mysql/mysql-ask-answer/356_mysql_how_can_i_rebuild_indexes_and_update_stats_in ...

  4. 开启大页与否对CacheBuffer的影响的学习

    开启大页与否对CacheBuffer的影响的学习 背景 最近遇到数据库压力较高的场景. 原厂工程师到位后修改了几个参数(自己以为参数没问题) 然后最近一周环境就比较正常了. 这个地方很打脸, 自己没有 ...

  5. [转帖]TiDB 查询优化及调优系列(三)慢查询诊断监控及排查

    https://zhuanlan.zhihu.com/p/509984029   本章节介绍如何利用 TiDB 提供的系统监控诊断工具,对运行负载中的查询进行排查和诊断.除了 上一章节介绍的通过 EX ...

  6. [转帖]Day64_Kafka(二)

    第二讲 Kafka架构 课程大纲 课程内容 学习效果 掌握目标 Kafka架构 Kafka就 掌握 Kafka ack Exactly once Kafka log Kafka log 掌握 Kafk ...

  7. 【转帖】Linux 调优篇:虚拟化调优(hugepage 大页内存)* 叁

    一. 大页(HugePages)概念Hugepage的引入二. hugepages相关概念三.Regular Pages 与 HugePagesa.Regular Pagesb.Huge Pages四 ...

  8. OpenEuler2203安装Redislabs的简单记录

    OpenEuler2203安装Redislabs的简单记录 背景 操作系统国产化的需求下 想着都转型到openEuler上面来. 应用和容器都没什么问题了,现在考虑一下一些企业软件 最近一直在想研究一 ...

  9. 京东ES支持ZSTD压缩算法上线了:高性能,低成本 | 京东云技术团队

    ​ 1 前言 在<ElasticSearch降本增效常见的方法>一文中曾提到过zstd压缩算法[1],一步一个脚印我们终于在京东ES上线支持了zstd:我觉得促使目标完成主要以下几点原因: ...

  10. 如何用etcdctl产生分布式环境中的递增ID

    作者:张富春(ahfuzhang),转载时请注明作者和引用链接,谢谢! cnblogs博客 zhihu Github 公众号:一本正经的瞎扯 用golang代码当然很简单,我这里是在shell环境中, ...