录音机调试第五天
關(guān)于畢設(shè)的一些調(diào)試感悟系列
1.硬件平臺(tái)的搭建
用的是正點(diǎn)原子的硬件平臺(tái)-阿波羅(STM32H743),所以基本不用額外調(diào)試硬件系統(tǒng),只是程序調(diào)試上需要多花一些時(shí)間進(jìn)行調(diào)整。
設(shè)計(jì)的硬件系統(tǒng)包括LCD屏的顯示、WM8978模塊和SD卡存儲(chǔ)模塊
暫時(shí)發(fā)現(xiàn)需要改進(jìn)的地方包括以下幾點(diǎn):
(1)對(duì)于TFT屏的顯示
(2)對(duì)于SD卡的文件管理系統(tǒng)的調(diào)整
? 可以這樣實(shí)現(xiàn),需要將兩個(gè)例程放在一起,用單片機(jī)的一個(gè)管腳作為輸入信號(hào)的標(biāo)志位,從而讓單片機(jī)執(zhí)行不同的程序。(模擬出音頻播放的功能來(lái))
如果這樣,那我也可以進(jìn)行頻譜的顯示,從而來(lái)實(shí)現(xiàn)對(duì)音頻信號(hào)的頻譜分析結(jié)果。
(3)對(duì)于麥克風(fēng)模塊的工作模式的理解
2.軟件系統(tǒng)的調(diào)試
軟件系統(tǒng)包括的任務(wù)是硬件系統(tǒng)的中的驅(qū)動(dòng)程序的編寫和使用DSP庫(kù)對(duì)采集的聲音信號(hào)進(jìn)行顯示:高級(jí)一點(diǎn)的話,需要使用低通濾波器,對(duì)于高頻噪聲進(jìn)行濾除。
1)TFTLCD屏-7寸 RGB TFTLCD
實(shí)現(xiàn)點(diǎn)陣顯示
2)麥克風(fēng)模塊-WM8978
可以找到聲音進(jìn)入主控的接口部分,進(jìn)行數(shù)據(jù)的保存,并實(shí)現(xiàn)FFT的數(shù)據(jù)輸入
3)SD卡存儲(chǔ)文件的管理
可以實(shí)現(xiàn)對(duì)存入的文件,進(jìn)行訪問(wèn),并進(jìn)行音頻播放
3.暫時(shí)的安排
1)讀一讀正點(diǎn)原子的開發(fā)資料,理解例程中的數(shù)據(jù)傳遞的流程
下面是兩個(gè)開發(fā)板提供商的開源資料:
野火
原子
從上面的實(shí)驗(yàn)教程中挑選如下的五個(gè)實(shí)驗(yàn)進(jìn)行應(yīng)用性學(xué)習(xí):
(1)音樂(lè)播放實(shí)驗(yàn)
學(xué)習(xí)利用SAI使用I2S協(xié)議驅(qū)動(dòng)wm8978
通過(guò)DMA進(jìn)行數(shù)據(jù)的傳輸:用SAI 的子模塊A,其TX 是使用的DMA1 數(shù)據(jù)流 5 的通道87 來(lái)傳輸?shù)?#xff1b;并且將DMA2 數(shù)據(jù)流3 設(shè)置為:雙緩沖循環(huán)模式,外設(shè)和存儲(chǔ)器寬度相同(16 位/32 位),并開啟DMA 傳輸完成中斷(方便填充數(shù)據(jù))。給緩沖器填充數(shù)據(jù)需要在傳輸完成一次后,在中斷中調(diào)用這個(gè)函數(shù) sai_tx_callback();
wav_play_song函數(shù),是播放 WAV的最終執(zhí)行函數(shù),該函數(shù)解析完 WAV文件后,
設(shè)置 WM8978和 I2S的參數(shù)(采樣率,位數(shù)等),并開啟 DMA,然后不停填充數(shù)據(jù),實(shí)現(xiàn) WAV播放,該函數(shù)還進(jìn)行了按鍵掃描控制,實(shí)現(xiàn)上下取切換和暫停 /播放等操作。該函數(shù)通過(guò)判斷wavtransferend是否為 1來(lái)處理是否應(yīng)該填充數(shù)據(jù),而到底填充到哪個(gè) buf saibuf1或 saibuf2則是通過(guò) wavwitchbuf標(biāo)志來(lái)確定的,當(dāng) wavwitchbuf=0時(shí),說(shuō)明 DMA正在使用 saibuf2,程序應(yīng)該填充 saibuf1;當(dāng) wavwitchbuf=1時(shí),說(shuō)明 DMA正在使用 saibuf1,程序應(yīng)該填充 saibuf2
上圖是I2S的通信需要配置的信號(hào)引腳定義。
(2)錄音機(jī)實(shí)驗(yàn)
(3)SD卡的存儲(chǔ)實(shí)驗(yàn)
(4)DSP實(shí)驗(yàn)
(5)RGB TFT顯示實(shí)驗(yàn)
? 調(diào)用單片機(jī)的LCD屏和TFT屏的函數(shù)庫(kù)的封裝是否一致呢?
(6)DMA數(shù)據(jù)傳輸實(shí)驗(yàn):理解雙緩沖含義
? 編碼后的結(jié)果,會(huì)直接由DMA傳輸?shù)絻?nèi)存,只有等256點(diǎn)全部傳輸完才會(huì)進(jìn)入到DMA的中斷,這樣保證了每個(gè)采樣點(diǎn)的間隔時(shí)間都是一致的。
? DMA發(fā)送完成中斷指的是每次指定字節(jié)發(fā)送完成后便產(chǎn)生一個(gè)中斷。
? 為了方便接收音頻數(shù)據(jù),我們使用DMA 傳輸完成中斷,每當(dāng)一個(gè)緩沖接數(shù)據(jù)滿了,硬件自動(dòng)切換為下一個(gè)緩沖,同時(shí)進(jìn)入中斷服務(wù)函數(shù),將已滿緩沖的數(shù)據(jù)寫入SD 卡的wav 文件。
對(duì)于數(shù)據(jù)傳輸?shù)氖崂砣缦?#xff1a;
首先聲音信號(hào)經(jīng)過(guò)麥克風(fēng)模塊,完成ADC轉(zhuǎn)換(ADC轉(zhuǎn)換過(guò)程),將采集的信號(hào)按照(轉(zhuǎn)換后的數(shù)據(jù)存儲(chǔ)過(guò)程)存儲(chǔ)到SD卡中,進(jìn)而完成音頻信號(hào)的采集;對(duì)于音頻信號(hào)的播放,主控首先從SD卡中讀取(從SD卡中讀取數(shù)據(jù)的過(guò)程)對(duì)應(yīng)扇區(qū)的數(shù)據(jù),然后對(duì)讀取到的數(shù)據(jù)進(jìn)行DAC轉(zhuǎn)換(對(duì)讀取到的數(shù)據(jù)進(jìn)行DAC轉(zhuǎn)換的過(guò)程),然后把轉(zhuǎn)換后的電壓值輸送到麥克風(fēng)集成模塊中。
故而在閱讀例程中需要解決兩個(gè)問(wèn)題:
(1)麥克風(fēng)模組對(duì)于音頻信號(hào)的采集方式
? 內(nèi)部ADC的轉(zhuǎn)換過(guò)程:
? 內(nèi)部DAC的轉(zhuǎn)換過(guò)程:
WAV是微軟公司開發(fā)的一種音頻格式文件,用于保存Windows平臺(tái)的音頻信息資源,它符合資源互換文件格式(Resource Interchange File Format, RIFF)文件規(guī)范。標(biāo)準(zhǔn)格式化的WAV文件和CD格式一樣,也是44.1K的取樣頻率,16位量化數(shù)字,因此在聲音文件質(zhì)量和CD相差無(wú)幾! WAVE是錄音時(shí)用的標(biāo)準(zhǔn)的WINDOWS文件格式,文件的擴(kuò)展名為“WAV”,數(shù)據(jù)本身的格式為PCM或壓縮型,屬于無(wú)損音樂(lè)格式的一種。
WAVE整體結(jié)構(gòu)如表 WAVE文件結(jié)構(gòu) :
data chunk是WAVE文件主體部分,包含聲音數(shù)據(jù),一般有兩個(gè)編碼格式:PCM和ADPCM,ADPCM(自適應(yīng)差分脈沖編碼調(diào)制)屬于有損壓縮,現(xiàn)在幾乎不用, 絕大部分WAVE文件是PCM編碼。PCM編碼聲音數(shù)據(jù)可以說(shuō)是在“數(shù)字音頻技術(shù)”介紹的源數(shù)據(jù),主要參數(shù)是采樣頻率和量化位數(shù)。絕大部分WAVE文件是PCM編碼。
PCM編碼聲音數(shù)據(jù)可以說(shuō)是在“數(shù)字音頻技術(shù)”介紹的源數(shù)據(jù),主要參數(shù)是采樣頻率和量化位數(shù)。
今天的分享可能有點(diǎn)稀疏,大體是因?yàn)閿?shù)據(jù)在麥克風(fēng)模塊內(nèi)部轉(zhuǎn)換完成后,就會(huì)直接從DMA中轉(zhuǎn)移到SD卡中,在轉(zhuǎn)移過(guò)程中,采集的數(shù)據(jù)會(huì)被WM8978模塊進(jìn)行PCM編碼,然后數(shù)據(jù)被以WAV格式存儲(chǔ)到SD卡中。故而分析數(shù)據(jù),必須從SD卡中進(jìn)行數(shù)據(jù)的獲取。從WAV格式的編碼中,我們知道數(shù)據(jù)被放在最后,有一個(gè)統(tǒng)計(jì)數(shù)據(jù)大小的標(biāo)志符,它的后面是采集得到的所有音頻數(shù)據(jù)。在程序中利用如下函數(shù)獲得起始位置:
wavx->datastart=wavx->datastart+8; //數(shù)據(jù)流開始的地方.
除此之外,我還需要知道目前在程序中采用的采樣率和采集的數(shù)據(jù)位數(shù)是多少:
采樣率:44.1kHz
采集的數(shù)據(jù)寬度:16bit (采集信號(hào)的實(shí)部) (對(duì)于虛部直接賦0)
采集的數(shù)據(jù)量:4096
對(duì)于已經(jīng)是實(shí)現(xiàn)的DSP頻譜分析中采用的上述參數(shù)是多少:
采樣率:1024hz
采集的數(shù)據(jù)寬度:32bit
采集的數(shù)據(jù)量:1024
關(guān)于f_write函數(shù)你知道多少呢?下面是它的參數(shù)定義
FRESULT f_write (
FIL* fp, // [IN] Pointer to the file object structure /
const void buff, // [IN] Pointer to the data to be written */
UINT btw, //[IN] Number of bytes to write /
UINT bw // [OUT] Pointer to the variable to return //number of bytes written
);
(2)SD在程序中對(duì)于數(shù)據(jù)的存儲(chǔ)方式
? 在SD卡中進(jìn)行數(shù)據(jù)的讀取:
?
? 在SD卡中進(jìn)行數(shù)據(jù)的寫入:
例程中通過(guò)下面的函數(shù)來(lái)對(duì)SD的寫入數(shù)據(jù),所以想在這里對(duì)寫入的數(shù)據(jù)進(jìn)行分析。
2)可以在網(wǎng)上尋找STM中DSP模塊的使用
后續(xù)的安排是,轉(zhuǎn)換過(guò)程中,數(shù)據(jù)的輸入方式和轉(zhuǎn)換過(guò)程,前提是了解到上述采集模塊對(duì)于數(shù)據(jù)的處理方式。
可以先嘗試把例程中的幅度譜先調(diào)試出來(lái),然后再考慮數(shù)據(jù)的流向,從而只需要更改數(shù)據(jù)就可以了。
操作如下,將F4的顯示程序,直接搬到H7的平臺(tái)上,進(jìn)行平臺(tái)的移植。
參考網(wǎng)址一:https://blog.csdn.net/hduxiejun/article/details/46287341?utm_medium=distribute.pc_relevant.none-task-blog-2%7Edefault%7EBlogCommendFromBaidu%7Edefault-17.control&dist_request_id=&depth_1-utm_source=distribute.pc_relevant.none-task-blog-2%7Edefault%7EBlogCommendFromBaidu%7Edefault-17.control
close all; %Turn off all the pictures clc; DC=1; %The magnitude of the dc signal Amp1=1; %The amplitude of the first signal Amp2=3; %The amplitude of the second signal Amp3=5; %The frequency of the third signal Fre1=10;%The frequency of the first signal ) Fre2=40;%The frequency of the Second signal Fre3=80;%The frequency of the third signal Fs=40960; %The sampling frequency N=4096; %The sampling points t=[0:1/Fs:1]; %Sampling time S=DC+Amp1*sin(2*pi*Fre1*t)+Amp2*sin(2*pi*Fre2*t)+Amp3*sin(2*pi*Fre3*t); %信號(hào) %Display the original signal subplot(3,1,1); plot(S,'b'); grid on; xlabel(' Frequency/HZ'); ylabel('Voltage'); title('The original signal'); Y = fft(S,N); %Do FFT transform Module = (abs(Y)); %:Acquire modulus subplot(3,1,2); F=([1:N]-1)*Fs/N; h = stem(F(1:N/320)/10,Module(1:N/320),'fill','--'); set(get(h,'BaseLine'),'LineStyle',':') set(h,'MarkerFaceColor','red') grid on; xlabel(' FFTout[i]'); ylabel('FFT module'); title('the module value of FFT'); Module=Module/(N/2); Module(1)=Module(1)/2; F=([1:N]-1)*Fs/N; subplot(3,1,3); h = stem(F(1:N/320),Module(1:N/320),'fill','--'); set(get(h,'BaseLine'),'LineStyle',':') set(h,'MarkerFaceColor','red') grid on; xlabel(' Frequency /HZ'); ylabel('Voltage'); title('Amplitude - frequency curves');note: plot(x) 當(dāng)x 為一向量時(shí),以x 元素的值為縱坐標(biāo),x 的序號(hào)為橫坐標(biāo)值繪制曲線。
可以借助MATLAB的程序來(lái)理解博主在單片機(jī)中實(shí)現(xiàn)FFT的處理過(guò)程和相關(guān)信號(hào)的定義。
參考網(wǎng)址二:https://blog.csdn.net/ysudykx/article/details/79515134#%E7%BB%93%E6%9E%9C?utm_medium=distribute.pc_relevant.none-task-blog-baidujs_title-4&spm=1001.2101.3001.4242
參考網(wǎng)址三:
https://www.cnblogs.com/menlsh/p/4154070.html
采樣率: Fs
采樣點(diǎn):N = 1/Fs
頻譜幅度:直流是原來(lái)的N倍,交流是原來(lái)的N/2倍
基波頻率(采樣分辨率):f = Fs/N 即顯示頻譜是的頻率間隔
基4采樣:輸入的點(diǎn)數(shù)必須是4^n 即(16/64/256/1024/4096)
例程中用到函數(shù)的參數(shù)定義:
//畫線
//x1,y1:起點(diǎn)坐標(biāo)
//x2,y2:終點(diǎn)坐標(biāo)
void LCD_DrawLine(u16 x1, u16 y1, u16 x2, u16 y2)
//在指定區(qū)域內(nèi)填充單個(gè)顏色
//(sx,sy),(ex,ey):填充矩形對(duì)角坐標(biāo),區(qū)域大小為:(ex-sx+1)*(ey-sy+1)
//color:要填充的顏色
void LCD_Fill(u16 sx,u16 sy,u16 ex,u16 ey,u16 color)
eg: LCD_Fill(0,240,0,260,WHITE);
經(jīng)過(guò)一番苦心鉆研,可算是把頻譜分析的圖像做出來(lái)了,目前的實(shí)現(xiàn)過(guò)程是自定義了一個(gè)輸入信號(hào),如果把自定義的輸入信號(hào),換成采集的音頻的數(shù)據(jù),就可以完成頻譜的顯示工作了。
故暫時(shí)是有一個(gè)潛在問(wèn)題,按照奈奎斯特采樣定律,采樣率是輸入信號(hào)頻率的兩倍以上才可以,而輸入信號(hào)的頻率是100Hz~2kHz,故需要處理的數(shù)據(jù)是4096個(gè)。
3)確定調(diào)試方案的步驟
目前有兩個(gè)思路來(lái)解決這個(gè)FFT轉(zhuǎn)換,思路一是借助SD卡作為數(shù)據(jù)轉(zhuǎn)換的媒介,需要先完成ADC轉(zhuǎn)換,然后把數(shù)據(jù)存儲(chǔ)到SD卡中,然后調(diào)用DSP中的FFT函數(shù),分別對(duì)采集的數(shù)據(jù)的進(jìn)行處理,然后并且把數(shù)據(jù)存儲(chǔ)到另一個(gè)扇區(qū)。思路二是直接在程序中定義一個(gè)數(shù)組,然后調(diào)用FFT對(duì)數(shù)據(jù)進(jìn)行處理,完成后,把數(shù)據(jù)直接存儲(chǔ)到SD卡中。
接收數(shù)據(jù)的方式有兩種,一種是在DMA中斷中,進(jìn)行數(shù)據(jù)的存儲(chǔ),因?yàn)橛玫氖请p緩存,所以需要注意的接收次序。另一種是在SD卡中,在聲音播放的位置,把聲音都讀出來(lái),然后進(jìn)行數(shù)據(jù)的分析。
第一步,先用串口將采集到的音頻數(shù)據(jù),進(jìn)行串口打印顯示
實(shí)驗(yàn)的數(shù)據(jù):
利用之前的MATLAB對(duì)采集的數(shù)據(jù)進(jìn)行初步分析,還算可以。
第二步,隨后根據(jù)采集的音頻數(shù)據(jù),按照采樣分辨率進(jìn)行數(shù)據(jù)的頻譜分析
第三步,將MATLAB顯示的頻譜轉(zhuǎn)移到LCD屏幕上
總結(jié)
- 上一篇: 关于jesd204B调试总结
- 下一篇: 可以在中断服务程序执行malloc吗?