STM32F401+nRF24L01無線傳輸音頻(對講機原型)


嘗試結合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組成簡單的放大電路.

輸出端電路

輸出端先經過以及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采樣的輸出來判斷, 需要寫代碼將數組輸出到存儲, 需要加一些片外存儲


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM