CKS32F4xx系列DSP功能
CKS32F4xx系列使用高性能的32位內(nèi)核,支持浮點(diǎn)運(yùn)算單元(FPU),同時(shí)還支持DSP指令以及存儲(chǔ)保護(hù)(MPU)用來(lái)加強(qiáng)應(yīng)用的安全性。
DSP介紹
CKS32F4xx系列擁有兩個(gè)DSP指令:MAC指令(32位乘法累加)和SIMD指令。32位乘法累加(MAC)單元包括新的指令集,能夠在單周期內(nèi)完成一個(gè)32×32+64→64的操作或兩個(gè)16×16的操作。而SIMD指令與硬件乘法器一起工作(MAC),使所有這些指令都能在單個(gè)周期內(nèi)執(zhí)行。受益于SIMD指令的支持,CKS32F4xx系列能在單周期內(nèi)完成高達(dá)32×32+64→64的運(yùn)算,為其他任務(wù)釋放處理器的帶寬,而不是被乘法和加法消耗運(yùn)算資源。
DSP源碼庫(kù)具有以下功能:
提供浮點(diǎn)數(shù)的各種基本運(yùn)算函數(shù),如向量加減乘除等運(yùn)算。
CommonTables
arm_common_tables.c文件提供位翻轉(zhuǎn)或相關(guān)參數(shù)表。
ComplexMathFunctions
復(fù)雜數(shù)學(xué)功能,如向量處理,求模運(yùn)算的。
ControllerFunctions
控制功能函數(shù)。包括正弦余弦,PID電機(jī)控制,矢量Clarke變換,矢量Clarke逆變換等。
FastMathFunctions
快速數(shù)學(xué)功能函數(shù)。提供了一種快速的近似正弦,余弦和平方根等,相比CMSIS計(jì)算庫(kù)要快的數(shù)學(xué)函數(shù)。
FilteringFunctions
濾波函數(shù)功能,主要為FIR和LMS(最小均方根)等濾波函數(shù)。
MatrixFunctions
矩陣處理函數(shù)。包括矩陣加法、矩陣初始化、矩陣反、矩陣乘法、矩陣規(guī)模、矩陣減法、矩陣轉(zhuǎn)置等函數(shù)。
StatisticsFunctions
統(tǒng)計(jì)功能函數(shù)。如求平均值、最大值、最小值、計(jì)算均方根RMS、計(jì)算方差/標(biāo)準(zhǔn)差等。
SupportFunctions
支持功能函數(shù),如數(shù)據(jù)拷貝,Q格式和浮點(diǎn)格式相互轉(zhuǎn)換,Q任意格式相互轉(zhuǎn)換。
TransformFunctions
變換功能。包括復(fù)數(shù)FFT(CFFT)/復(fù)數(shù)FFT逆運(yùn)算(CIFFT)、實(shí)數(shù)FFT(RFFT)/實(shí)數(shù)FFT逆運(yùn)算(RIFFT)、和DCT(離散余弦變換)和配套的初始化函數(shù)。
DSP庫(kù)運(yùn)行環(huán)境搭建
接下來(lái)我們講解如何搭建DSP庫(kù)運(yùn)行環(huán)境,只要運(yùn)行環(huán)境搭建好了,使用DSP庫(kù)里面的函數(shù)來(lái)做相關(guān)處理就非常簡(jiǎn)單了。在MDK里面搭建CKS32F4xx系列的DSP運(yùn)行環(huán)境(使用.lib方式)是很簡(jiǎn)單的,分為3個(gè)步驟:
1
添加文件
首先,我們?cè)诶坦こ棠夸浵滦陆―SP_LIB文件夾,存放我們將要添加的相關(guān)文件,如圖1所示:
然后,打開(kāi)工程,新建DSP_LIB分組,并將.lib文件添加到工程里面,如圖2所示:
2
添加頭文件包含路徑
添加好.lib文件后,我們要添加頭文件包含路徑,將第一步拷貝的Include文件夾和DSP_LIB文件夾加入頭文件包含路徑,如圖3所示:
3
添加全局宏定義
最后,為了使用DSP庫(kù)的所有功能,我們還需要添加幾個(gè)全局宏定義:
1,__FPU_USED
2,__FPU_PRESENT
3,ARM_MATH_CM4
4,__CC_ARM
5,ARM_MATH_MATRIX_CHECK
6,ARM_MATH_ROUNDING
添加方法:點(diǎn)擊魔法棒→C/C++選項(xiàng)卡,然后在Define里面進(jìn)行設(shè)置,如圖4所示:
這里,兩個(gè)宏之間用“,”隔開(kāi)。并且,上面的全局宏里面,我們沒(méi)有添加__FPU_USED,因?yàn)檫@個(gè)宏定義在Target選項(xiàng)卡設(shè)置Code Generation的時(shí)候選擇了:Use FPU(如果沒(méi)有設(shè)置Use FPU,則必須設(shè)置!!),故MDK會(huì)自動(dòng)添加這個(gè)全局宏,因此不需要我們手動(dòng)添加了。這樣,在Define處要輸入的所有宏為:
CKS32F40_41xxx,USE_STDPERIPH_DRIVER,ARM_MATH_CM4,__CC_ARM,ARM_MATH_MATRIX_CHECK,ARM_MATH_ROUNDING 共6個(gè)。
至此,CKS32F4xx系列的DSP庫(kù)運(yùn)行環(huán)境就搭建完成了。為了方便調(diào)試,本章例程我們將MDK的優(yōu)化設(shè)置為-O0優(yōu)化,以得到最好的調(diào)試效果。
DSP FFT測(cè)試
關(guān)于FFT這里就不再詳細(xì)介紹。如果我們要自己實(shí)現(xiàn)FFT算法,對(duì)于不懂數(shù)字信號(hào)處理的人來(lái)說(shuō),是比較難的,不過(guò),DSP庫(kù)里面就有FFT函數(shù)給我們調(diào)用,因此我們只需要知道如何使用這些函數(shù),就可以迅速的完成FFT計(jì)算。DSP庫(kù)里面提供了定點(diǎn)和浮點(diǎn) FFT 實(shí)現(xiàn)方式,并且有基4的也有基2的,大家可以根據(jù)需要自由選擇實(shí)現(xiàn)方式。
注意:對(duì)于基4的FFT輸入點(diǎn)數(shù)必須是4n,而基2的FFT 輸入點(diǎn)數(shù)則必須是2n,并且基4的FFT算法要比基2的快。本章我們將采用DSP庫(kù)里面的基4浮點(diǎn)FFT算法來(lái)實(shí)現(xiàn)FFT變換,并計(jì)算每個(gè)點(diǎn)的模值,所用到的函數(shù)有:
FFT變換用到的函數(shù)
arm_status arm_cfft_radix4_init_f32( arm_cfft_radix4_instance_f32 * S, uint16_t fftLen,uint8_t ifftFlag,uint8_t bitReverseFlag)
void arm_cfft_radix4_f32(const arm_cfft_radix4_instance_f32 * S,float32_t * pSrc)
void arm_cmplx_mag_f32(float32_t * pSrc,float32_t * pDst,uint32_t numSamples)
arm_cfft_radix4_init_f32用于初始化FFT運(yùn)算相關(guān)參數(shù),其中:fftLen用于指定 FFT長(zhǎng)度(16/64/256/1024/4096),本章設(shè)置為1024;ifftFlag用于指定是傅里葉變換(0)還是反傅里葉變換(1),本章設(shè)置為0;bitReverseFlag用于設(shè)置是否按位取反,本章設(shè)置為1;最后,所有這些參數(shù)存儲(chǔ)在一個(gè) arm_cfft_radix4_instance_f32結(jié)構(gòu)體指針S里面。
arm_cfft_radix4_f32就是執(zhí)行基4浮點(diǎn)FFT運(yùn)算的,pSrc傳入采集到的輸入信號(hào)數(shù)據(jù)(實(shí)部+虛部形式),同時(shí)FFT變換后的數(shù)據(jù),也按順序存放在pSrc里面,pSrc必須大于等于 2倍fftLen長(zhǎng)度。另外,S結(jié)構(gòu)體指針參數(shù)是先由arm_cfft_radix4_init_f32函數(shù)設(shè)置好,然后傳入該函數(shù)的。
arm_cmplx_mag_f32用于計(jì)算復(fù)數(shù)模值,可以對(duì)FFT變換后的結(jié)果數(shù)據(jù),執(zhí)行取模操作。pSrc為復(fù)數(shù)輸入數(shù)組(大小為 2*numSamples)指針,指向FFT變換后的結(jié)果;pDst 為輸出數(shù)組(大小為 numSamples)指針,存儲(chǔ)取模后的值;numSamples就是總共有多少個(gè)數(shù)據(jù)需要取模。
通過(guò)這三個(gè)函數(shù),我們便可以完成 FFT 計(jì)算,并取模值。
主函數(shù)
int main(void)
{
arm_cfft_radix4_instance_f32 scfft;
float time;
u8 buf[50];
u16 i;
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);//設(shè)置系統(tǒng)中斷優(yōu)先級(jí)分組2
delay_init(168); //初始化延時(shí)函數(shù)
Debug_USART_Config(); //初始化串口波特率為115200
TIM3_Int_Init(65535,84-1); //1Mhz計(jì)數(shù)頻率,最大計(jì)時(shí)65ms左右超出
arm_cfft_radix4_init_f32(&scfft,FFT_LENGTH,0,1);//初始化scfft結(jié)構(gòu)體,設(shè)定FFT相關(guān)參數(shù)
while(1)
{
for(i=0;i
{
fft_inputbuf[2*i]=100+10*arm_sin_f32(2*PI*i/FFT_LENGTH)+30*arm_sin_f32(2*PI*i*4/FFT_LENGTH)+50*arm_cos_f32(2*PI*i*8/FFT_LENGTH); //生成輸入信號(hào)實(shí)部
fft_inputbuf[2*i+1]=0;//虛部全部為0
}
TIM_SetCounter(TIM3,0);//重設(shè)TIM3定時(shí)器的計(jì)數(shù)器值
timeout=0;
arm_cfft_radix4_f32(&scfft,fft_inputbuf); //FFT計(jì)算(基4)
time=TIM_GetCounter(TIM3)+(u32)timeout*65536;
sprintf((char*)buf,"%0.3fms ",time/1000);
printf(" FFT基4運(yùn)算運(yùn)行時(shí)間為: %s", buf);
arm_cmplx_mag_f32(fft_inputbuf,fft_outputbuf,FFT_LENGTH);
printf(" %d point FFT runtime:%0.3fms ",FFT_LENGTH,time/1000);
printf("FFT Result: ");
for(i=0;i
{
printf("fft_outputbuf[%d]:%f ",i,fft_outputbuf[i]);
}
delay_ms(2000);
delay_ms(2000);
delay_ms(2000);
}
}
主函數(shù)里面通過(guò)我們前面介紹的三個(gè)函數(shù):arm_cfft_radix4_init_f32、 arm_cfft_radix4_f32和arm_cmplx_mag_f32來(lái)執(zhí)行FFT變換并取模值。每隔6秒就會(huì)重新生成一個(gè)輸入信號(hào)序列,并執(zhí)行一次FFT計(jì)算,將 arm_cfft_radix4_f32 所用時(shí)間統(tǒng)計(jì)出來(lái),同時(shí)將取模后的模值通過(guò)串口打印出來(lái)。
審核編輯:劉清
-
處理器
+關(guān)注
關(guān)注
68文章
19159瀏覽量
229112 -
dsp
+關(guān)注
關(guān)注
552文章
7962瀏覽量
348252 -
MPU
+關(guān)注
關(guān)注
0文章
346瀏覽量
48735 -
浮點(diǎn)運(yùn)算
+關(guān)注
關(guān)注
0文章
19瀏覽量
11158
原文標(biāo)題:MCU微課堂|CKS32F4xx系列DSP功能
文章出處:【微信號(hào):中科芯MCU,微信公眾號(hào):中科芯MCU】歡迎添加關(guān)注!文章轉(zhuǎn)載請(qǐng)注明出處。
發(fā)布評(píng)論請(qǐng)先 登錄
相關(guān)推薦
評(píng)論