|
演示代碼
GitHub FwLib_STC8/tree/master/demo/spi/nrf24l01_audio
Gitee FwLib_STC8/tree/master/demo/spi/nrf24l01_audio
使用說(shuō)明 https://www.cnblogs.com/milton/p/15852161.html
無(wú)線音頻傳輸?shù)膶?shí)現(xiàn)
大部分低端MCU不帶DAC轉(zhuǎn)換, 但是可以使用PWM模擬, 對(duì)于音頻傳輸
- 人普通談話的聲波頻率在500-2000Hz之間, 人耳可以聽(tīng)到的聲波的頻率范圍在20Hz至20kHz之間
- 用于通話, 8kHz的帶寬就能達(dá)到較好的語(yǔ)音傳輸效果
- 通過(guò)PWM模擬DAC, 因?yàn)镻WM是方波, 其頻率會(huì)引入底噪, 底噪的頻率是PWM頻率的倍數(shù)
- PWM頻率在8KHz時(shí), 在聽(tīng)感上底噪很大, 與傳輸?shù)囊纛l一樣明顯, 將PWM的頻率調(diào)節(jié)到16kHz以上才能有效抑制底噪
發(fā)送部分
發(fā)送部分需要實(shí)現(xiàn)的是8kHz采樣, 并通過(guò)NRF24L01將每秒的8000字節(jié)數(shù)據(jù)發(fā)送出去.
語(yǔ)音輸入
語(yǔ)音輸入可以使用駐極體話筒加S9013放大輸入或者直接使用MAX9814. 在測(cè)試階段建議使用后者, 可以保證采樣輸入不失真, 在調(diào)通后再用駐極體話筒電路替換.
ADC音頻采樣
因?yàn)锳DC采樣需要實(shí)現(xiàn)準(zhǔn)確的每秒8000采樣, 所以不能用DMA方式, 在STC8H(包括STM32等其它MCU)下, 無(wú)法在DMA情況下精確調(diào)節(jié)每秒的采樣個(gè)數(shù), 因?yàn)锳DC的采樣頻率, 采樣周期和轉(zhuǎn)換周期在不同MCU中都是固定的, 所以很難正好做到8kHz的采樣. 具體的實(shí)現(xiàn)中有兩種方式:
1.定時(shí)器驅(qū)動(dòng)采集
通過(guò)定時(shí)器設(shè)置為8kHz, 在中斷中發(fā)起ADC轉(zhuǎn)換, 是比較容易實(shí)現(xiàn)的. 這時(shí)候需要將ADC也實(shí)現(xiàn)為中斷方式, 因?yàn)锳DC的轉(zhuǎn)換時(shí)間比較長(zhǎng), 如果在定時(shí)器中斷中做同步的ADC轉(zhuǎn)換, 容易影響主進(jìn)程. 需要有定時(shí)器的中斷處理和ADC的中斷處理, 定時(shí)器的中斷處理單純用于發(fā)起轉(zhuǎn)換, ADC的中斷才用于讀出結(jié)果.
2.連續(xù)采集定時(shí)讀取
通過(guò)定時(shí)器設(shè)置為8kHz, 將ADC的采集設(shè)置為循環(huán)方式(中斷采集, 但是在中斷時(shí)再次發(fā)起), 在定時(shí)器中斷中僅僅讀取采集結(jié)果. 這種方式也能實(shí)現(xiàn)8kHz的采樣. 因?yàn)檫@種方式實(shí)際上會(huì)多消耗電量, 所以實(shí)際使用中還是采用了前一種方法.
NRF24L01發(fā)送
NRF24L01在設(shè)置為1Mbps帶寬時(shí)實(shí)際傳輸速度能達(dá)到23k字節(jié)每秒, 因此對(duì)于8bit 8kHz采樣的傳輸是沒(méi)問(wèn)題的. 因?yàn)镹RF24L01傳輸時(shí)的響應(yīng)和重發(fā)機(jī)制, 在信號(hào)不好時(shí), 容易導(dǎo)致發(fā)送中斷, 為了避免傳輸時(shí)間的波動(dòng)影響, 在實(shí)現(xiàn)中使用了雙數(shù)組做緩沖. 采樣到發(fā)送之間的邏輯為
兩個(gè)256字節(jié)數(shù)組作為全局變量, 同時(shí)定義變量指向當(dāng)前寫(xiě)入的數(shù)組編號(hào)和寫(xiě)入位置
ADC中斷讀取結(jié)果時(shí), 往當(dāng)前編號(hào)的數(shù)組和位置中寫(xiě)入并移動(dòng)位置, 當(dāng)寫(xiě)滿一個(gè)數(shù)組時(shí), 將此數(shù)組標(biāo)記為可發(fā)送, 并切換到下一個(gè)數(shù)組繼續(xù)寫(xiě)入
在主進(jìn)程中, 判斷當(dāng)前是否有可發(fā)送的數(shù)組, 如果可發(fā)送, 則在循環(huán)中按32個(gè)字節(jié)一組將數(shù)據(jù)全部發(fā)送.
因?yàn)樵谡J瞻l(fā)的信號(hào)強(qiáng)度下, NRF24L01的發(fā)送速度是比采樣速度快的, 所以基本上NRF24L01的發(fā)送是發(fā)送 -> 等待 -> 發(fā)送的狀態(tài)
接收部分
接收部分要實(shí)現(xiàn)的是將NRF24L01接收到的數(shù)據(jù)進(jìn)行存儲(chǔ), 并按照8kHz的頻率, 將每個(gè)值設(shè)為PWM輸出的占空比, 實(shí)現(xiàn)DAC模擬
RNF24L01接收
因?yàn)镹RF24L01發(fā)送是集中發(fā)送, 而PWM還原是勻速的, 所以在接收也需要有緩沖, 接收的機(jī)制和發(fā)送相似
兩個(gè)256字節(jié)數(shù)組作為全局變量, 同時(shí)定義變量指向當(dāng)前寫(xiě)入的數(shù)組編號(hào)和寫(xiě)入位置
NRF24L01通過(guò)中斷接收數(shù)據(jù), 在接收時(shí), 往當(dāng)前編號(hào)的數(shù)組和位置中寫(xiě)入并移動(dòng)位置, 當(dāng)寫(xiě)滿一個(gè)數(shù)組時(shí), 將此數(shù)組標(biāo)記為可用, 并切換到下一個(gè)數(shù)組繼續(xù)寫(xiě)入
PWM模擬DAC還原
初始化一個(gè)PWM輸出, PWM周期為256對(duì)應(yīng)8bit的占空比調(diào)節(jié)范圍, 確保PWM頻率不低于16kHz. 在8kHz定時(shí)器的中斷中, 判斷當(dāng)前讀取的數(shù)組和位置, 每次讀取一個(gè)值, 并將其設(shè)置為PWM占空比. 如果數(shù)組不可用, 就不做任何操作, 如果此時(shí)將占空比設(shè)為0, 會(huì)產(chǎn)生噪音.
音頻輸出
測(cè)時(shí)階段, 可以在PWM輸出上串聯(lián)一個(gè)200R的電阻后值連喇叭, 可以聽(tīng)到輸出的音頻. 這個(gè)電阻不能太小, 測(cè)試中如果阻值小于100R, 會(huì)導(dǎo)致MCU供電不足反復(fù)重啟. 在確定音頻輸出沒(méi)問(wèn)題后, 可以替換為 PAM8403 音頻放大模塊.
在使用 PAM8403 模塊時(shí)
- 模塊需要獨(dú)立供電, 測(cè)試中如果與MCU都使用USB2TTL供電, 會(huì)使MCU供電不足而導(dǎo)致聲音輸出異常
- 模塊與MCU的輸出可以不共地, 即模塊MCU的PWM輸出和地, 可以直接接入PAM8403的音頻輸入
- 因?yàn)槭菃温暤佬盘?hào), 所以只能用PAM8403的一個(gè)聲道, L或者R都可以
接線說(shuō)明
在測(cè)試中發(fā)送部分使用的是 STC8H3K32S2, 接收部分使用的是 STC8H1K08, 你可以使用STC8H系列的任意一個(gè)型號(hào)
- 共同的連接部分(NRF24L01)
- 8H3K32S2/8H1K08 NRF24L01
- P35(SS, Ignored) => CSN 16
- P34(MOSI) => MOSI 15
- P33(MISO) => MISO 14
- P32(SPCLK) => CLK 13
- P36(INT2) => IRQ 17
- P37(IO) => CE 18
- 發(fā)送部分
- STC8H3K32S2 MAX9814
- P11(ADC1) => MIC
- 3.3V => VDD
- 3.3V => GAIN
- GND => A/R
- GND => GND
- ADC, 如果是STC8H3K32S2, 使用ADC采樣要將AVcc, AGnd 和 ADC_Vref+ 正確連線
- AVcc => 3.3V
- AGnd => GND
- ADC_Vref+ => 3.3V
- P11 => Output(MAX9814) or MIC
- 接收部分
- STC8H1K08 PAM8403
- P10(PWM1P) => 200R => L or R input
- GND => _|_ Input
- Ext 3.3V/5V => VCC
- Ext GND => GND
復(fù)制代碼
注意:
MCU的pin腳布局不一定相同, STC8H3K32S2和STC8H1K08都是20pin的封裝, 但是pin腳布局就不一樣
燒錄發(fā)送部分和接收部分時(shí), 注意要調(diào)換 nrf24l01.c 中的 RX_ADDRESS 和 TX_ADDRESS
效果演示
B站視頻 https://www.bilibili.com/video/BV1kZ4y1Z78v
調(diào)試說(shuō)明
因?yàn)檫@個(gè)演示實(shí)際上包含了定時(shí)器, ADC采樣, NRF24L01發(fā)送, 接收, PWM調(diào)制這幾個(gè)環(huán)節(jié), 任一個(gè)環(huán)節(jié)出問(wèn)題, 都會(huì)導(dǎo)致演示失敗. 在調(diào)試中, 需要遵循化整為零, 逐個(gè)確認(rèn)的原則, 對(duì)每個(gè)節(jié)點(diǎn)是否工作正常進(jìn)行確認(rèn).
定時(shí)器調(diào)試
因?yàn)?kHz的輸出較難觀測(cè), 可以用一個(gè)uint16_t的全局變量自增到8000后串口輸出觀察時(shí)間間隔是否正確
ADC調(diào)試
先通過(guò)同步模式, 查看ADC采集是否正確, STC8H1K和STC8H3K的ADC接線是不一樣的, 如果接線不正確, 輸出的就是噪音.
同步采樣沒(méi)問(wèn)題后, 再通過(guò)中斷方式采集檢查是否正確
中斷沒(méi)問(wèn)題后, 就可以結(jié)合定時(shí)器, 通過(guò)定時(shí)器發(fā)起采樣
NRF24L01 調(diào)試
可以參考前面的例子SPI驅(qū)動(dòng)nRF24L01無(wú)線模塊 單獨(dú)運(yùn)行 NRF24L01 進(jìn)行收發(fā)是否功能正常
PWM 調(diào)試
有條件的可以用邏輯分析儀, 輸出正常后, 用音頻進(jìn)行測(cè)試, 可以參考PWM輸出音頻這個(gè)例子, 循環(huán)播放一段8bit音頻檢查PWM輸出是否正確, 因?yàn)橐纛l較大, 測(cè)試這個(gè)需要使用Flash容量至少32K字節(jié)的芯片, 例如STC8H3K32S2.
最小系統(tǒng)聯(lián)調(diào)
最小系統(tǒng)的發(fā)送端先不使用ADC, 使用固定的8bit音頻作為輸入進(jìn)行發(fā)送, 接收端先不外接音頻放大, 直接用200歐串聯(lián)小喇叭進(jìn)行檢查, 工作正常的情況下, 音頻播放效果應(yīng)當(dāng)是非常好的
在最小系統(tǒng)聯(lián)調(diào)沒(méi)問(wèn)題后, 就可以開(kāi)始調(diào)試ADC, 沒(méi)問(wèn)題后最后加入音頻放大模塊.
|
評(píng)分
-
查看全部評(píng)分
|