{"id":259,"date":"2022-12-13T13:50:28","date_gmt":"2022-12-13T05:50:28","guid":{"rendered":"http:\/\/www.huangrongzhen.ink\/?p=259"},"modified":"2022-12-15T09:03:49","modified_gmt":"2022-12-15T01:03:49","slug":"arm-dsp-%e5%ba%93-fft-%e7%9a%84%e4%bd%bf%e7%94%a8","status":"publish","type":"post","link":"https:\/\/www.huangrongzhen.ink\/?p=259","title":{"rendered":"ARM DSP \u5e93 FFT \u7684\u4f7f\u7528"},"content":{"rendered":"<div class=\"wp-block-post-excerpt\"><p class=\"wp-block-post-excerpt__excerpt\">\u8bb0\u5f55ARM DSP \u5e93\u4e0b FFT \u7684\u4f7f\u7528\u3002 <\/p><\/div>\n\n\n<h2 class=\"wp-block-heading\"><span class=\"ez-toc-section\" id=\"%E5%AE%9E%E6%95%B0_FFT_%E7%9A%84%E4%BD%BF%E7%94%A8\"><\/span>\u5b9e\u6570 FFT \u7684\u4f7f\u7528<span class=\"ez-toc-section-end\"><\/span><\/h2>\n\n\n\n<p>\u5b9e\u6570 FFT \u5bf9\u5e94\u7684\u51fd\u6570\u4e3a arm_rfft_fast_f32\uff0c\u5bf9\u4e8e\u5b9e\u6570 FFT\uff0c\u8f93\u5165\u4fe1\u53f7\u65e0\u9700\u6309\u201c\u5b9e\u90e8\u3001\u865a\u90e8\u3001\u5b9e\u90e8\u3001\u865a\u90e8\u3001\u3001\u3001\u201d\u7684\u987a\u5e8f\u5b58\u50a8\u6570\u636e\u3002<\/p>\n\n\n\n<p>arm_rfft_fast_f32 \u51fd\u6570\u7684\u5f62\u53c2\u5982\u4e0b\u6240\u793a\u3002arm_rfft_fast_f32 \u51fd\u6570\u53ea\u652f\u6301 32\u300164\u3001128\u3001256\u3001512\u30011024\u30012048 \u548c 4096 \u4e2a\u70b9\u7684 FFT \u8ba1\u7b97\u3002\u9700\u8981\u6ce8\u610f\u7684\u662f\uff0carm_rfft_fast_f32 \u51fd\u6570\u7684\u8f93\u5165\u662f\u4e00\u4e2a\u5b9e\u5e8f\u5217\uff0c\u8f93\u51fa\u7684\u662f\u4e00\u4e2a\u865a\u5e8f\u5217\uff0c\u8f93\u51fa\u7684\u70b9\u6570\u662f\u8f93\u5165\u70b9\u6570\u7684\u4e00\u534a\u3002\u5047\u8bbe\u8f93\u5165\u7684\u6570\u636e\u91cf\u4e3a 1024 \u4e2a\u70b9\uff0c\u56e0\u4e3a\u662f\u5b9e\u5e8f\u5217\uff0c\u6240\u4ee5\u8f93\u5165\u7684\u5b57\u8282\u603b\u6570\u4e3a 1024 * 4 = 4096 \u4e2a\u5b57\u8282\uff1b\u8f93\u51fa\u7684\u6570\u636e\u91cf\u4e3a 512 \u4e2a\u70b9\uff0c\u53c8\u56e0\u4e3a\u662f\u865a\u5e8f\u5217\uff0c\u6240\u4ee5\u8f93\u51fa\u7684\u5b57\u8282\u603b\u6570\u4e3a 512 * 2 * 4 = 1024 \u4e2a\u5b57\u8282\u3002\u7efc\u4e0a\uff0carm_rfft_fast_f32 \u51fd\u6570\u8f93\u5165\u8f93\u51fa\u7684\u5b57\u8282\u603b\u6570\u662f\u4e00\u6837\u7684\u3002<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code lang=\"cpp\" class=\"language-cpp\">void arm_rfft_fast_f32(\n  arm_rfft_fast_instance_f32 * S,  \/\/\u5b9e\u6570 FFT \u63a7\u5236\u7ed3\u6784\u4f53\n  float32_t * p,                   \/\/\u5b9e\u5e8f\u5217\u6570\u636e\u8f93\u5165\uff08\u6b64\u51fd\u6570\u4f1a\u66f4\u6539\u8f93\u5165\u7f13\u51b2\u533a\u7684\u5185\u5bb9\uff09\n  float32_t * pOut,                \/\/\u7ed3\u679c\u8f93\u51fa\uff0c\u8f93\u51fa\u7684\u662f\u4e00\u4e2a\u865a\u5e8f\u5217\uff0c\u6309 \"\u5b9e\u90e8\u3001\u865a\u90e8\u3001\u5b9e\u90e8\u3001\u865a\u90e8\u3001\u3001\u3001\" \u7684\u987a\u5e8f\u5b58\u50a8\u6570\u636e\uff0c\u8f93\u5165\u8f93\u51fa\u7684\u6570\u636e\u91cf\u76f8\u540c\n  uint8_t ifftFlag)                \/\/0-FFT \u6b63\u53d8\u6362\uff0c1-FFT \u9006\u53d8\u6362<\/code><\/pre>\n\n\n\n<p>\u56e0\u4e3a arm_rfft_fast_f32 \u51fd\u6570\u7684\u8f93\u51fa\u662f\u4e00\u4e2a\u865a\u5e8f\u5217\uff0c\u6240\u4ee5\u9700\u8981\u901a\u8fc7 arm_cmplx_mag_f32 \u51fd\u6570\u6c42\u89e3\u6a21\u503c\uff0carm_cmplx_mag_f32 \u51fd\u6570\u7684\u5f62\u53c2\u5982\u4e0b\u6240\u793a\u3002<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code lang=\"cpp\" class=\"language-cpp\">void arm_cmplx_mag_f32(\n  const float32_t * pSrc,     \/\/\u8f93\u5165\uff0c\u662f\u4e00\u4e2a\u865a\u5e8f\u5217\uff0c\u6309\"\u5b9e\u90e8\u3001\u865a\u90e8\u3001\u5b9e\u90e8\u3001\u865a\u90e8\u3001\u3001\u3001\" \u7684\u987a\u5e8f\u5b58\u50a8\u6570\u636e\n        float32_t * pDst,     \/\/\u8f93\u51fa\uff0c\u662f\u4e00\u4e2a\u5b9e\u5e8f\u5217\uff0c\u5b57\u8282\u603b\u6570\u4e3a\u8f93\u5165\u5e8f\u5217\u7684\u4e00\u534a\n        uint32_t numSamples)  \/\/\u70b9\u6570<\/code><\/pre>\n\n\n\n<p>\u5b9e\u6570 FFT \u7684\u4f7f\u7528\u5982\u4e0b\u6240\u793a\u3002\u5b9e\u6570 FFT \u53d8\u6362\u4e4b\u524d\u9700\u8981\u5148\u7528 arm_rfft_fast_init_f32 \u51fd\u6570\u521d\u59cb\u5316 FFT \u63a7\u5236\u7ed3\u6784\u4f53\uff0c\u544a\u8bc9 DSP \u5e93 FFT \u53d8\u6362\u7684\u70b9\u6570\u3002<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code lang=\"cpp\" class=\"language-cpp\">#include \"arm_math.h\"\n\n\/\/FFT \u70b9\u6570\n#define FFT_LENGTH 1024\n\n\/\/\u4e3b\u51fd\u6570\nvoid main(void)\n{\n  static float32_t s_arrFFTInput[FFT_LENGTH] = {0};      \/\/FFT \u8f93\u5165\u7f13\u51b2\u533a\n  static float32_t s_arrFFTOutput[FFT_LENGTH] = {0};     \/\/FFT \u8f93\u51fa\u7f13\u51b2\u533a\n  static float32_t s_arrResult[FFT_LENGTH] = {0};        \/\/FFT \u6a21\u503c\n  static arm_rfft_fast_instance_f32 s_structRfft;        \/\/FFT \u63a7\u5236\u7ed3\u6784\u4f53\n\n  \/\/\u4e34\u65f6\u53d8\u91cf\n  u16 adc;\n  u32 waveCnt, i, pos;\n  float max;\n\n  \/\/\u6ce2\u5f62\u8ba1\u6570\u6e05\u96f6\n  waveCnt = 0;\n\n  \/\/\u4e3b\u5faa\u73af\n  while(1)\n  {\n    \/\/\u91c7\u96c6\u6ce2\u5f62\u4fe1\u53f7\n    adc = GetWaveADC();\n    s_arrFFTInput[waveCnt++] = adc;\n\n    \/\/\u91c7\u96c6\u591f\u4e86\u6570\u636e\u91cf\n    if(waveCnt &gt;= FFT_LENGTH)\n    {\n      \/\/FFT\u8ba1\u7b97\n      \/\/\u6ce8\u610f\uff1aarm_rfft_fast_f32 \u51fd\u6570\u7684\u8f93\u51fa\u662f\u4e00\u4e2a\u590d\u6570\u5e8f\u5217\uff0c\u6309\u7167 \"\u5b9e\u90e8\u3001\u865a\u90e8\u3001\u5b9e\u90e8\u3001\u865a\u90e8\u3001\u3001\u3001\" \u7684\u987a\u5e8f\u5b58\u50a8\u6570\u636e\uff0c\u4e00\u5171\u8f93\u51fa FFT_LENGTH\/2 \u4e2a\u5b9e\u6570\n      \/\/\u6240\u4ee5 arm_cmplx_mag_f32 \u51fd\u6570\u7684\u8f93\u51fa\u53ea\u6709\u524d FFT_LENGTH\/2 \u4e2a\u70b9\u662f\u6709\u610f\u4e49\u7684\n      arm_rfft_fast_init_f32(&amp;s_structRfft, FFT_LENGTH);                   \/\/\u521d\u59cb\u5316\u7ed3\u6784\u4f53\u4e2d\u7684\u53c2\u6570\n      arm_rfft_fast_f32(&amp;s_structRfft, s_arrFFTInput, s_arrFFTOutput, 0);  \/\/1024\u70b9\u5b9e\u5e8f\u5217\u5feb\u901fFFT\n      arm_cmplx_mag_f32(s_arrFFTOutput, s_arrResult, FFT_LENGTH \/ 2);      \/\/\u6c42\u89e3\u6a21\u503c\n\n      \/\/\u8ba1\u7b97\u6ce2\u5f62\u9891\u7387\n      max = 0; pos = 0;\n      for(i = 1; i &lt; FFT_LENGTH \/ 2; i++)\n      {\n        if(s_arrResult[i] &gt; max)\n        {\n          max = s_arrResult[i];\n          pos = i;\n        }\n      }\n      printf(\"rate: %.1fHz\\r\\n\", (double)pos * 1000.0 \/ (double)FFT_LENGTH);\n\n      \/\/\u6e05\u7a7a\u6ce2\u5f62\u8ba1\u6570\n      waveCnt = 0;\n    }\n    \n    \/\/\u5ef6\u65f61ms\n    DelayNms(1);\n  }\n}<\/code><\/pre>\n\n\n\n<p>\u9891\u7387\u8ba1\u7b97\u65b9\u6cd5\uff1a\u6700\u9ad8\u70b9\u6240\u5728\u4e0b\u6807 x \u91c7\u6837\u7387 \/ FFT \u70b9\u6570\u3002\u91c7\u6837\u7387\u5355\u4f4d\u662f Hz\u3002<\/p>\n\n\n\n<h2 class=\"wp-block-heading\"><span class=\"ez-toc-section\" id=\"%E5%A4%8D%E6%95%B0_FFT_%E7%9A%84%E4%BD%BF%E7%94%A8\"><\/span>\u590d\u6570 FFT \u7684\u4f7f\u7528<span class=\"ez-toc-section-end\"><\/span><\/h2>\n\n\n\n<p>\u590d\u6570 FFT \u5bf9\u5e94\u7684\u51fd\u6570\u4e3a arm_cfft_f32\uff0c\u53ea\u652f\u6301 16\u300132\u300164\u3001128\u3001256\u3001512\u30011024\u30012048 \u548c 4096 \u4e2a\u70b9\u7684 FFT \u8ba1\u7b97\uff0c\u5bf9\u4e8e\u590d\u6570 FFT\uff0c\u8f93\u5165\u4fe1\u53f7\u5fc5\u987b\u6309\u201c\u5b9e\u90e8\u3001\u865a\u90e8\u3001\u5b9e\u90e8\u3001\u865a\u90e8\u3001\u3001\u3001\u201d\u7684\u987a\u5e8f\u5b58\u50a8\u6570\u636e\u3002arm_cfft_f32 \u51fd\u6570\u7684\u5f62\u53c2\u5982\u4e0b\u6240\u793a\u3002<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code lang=\"cpp\" class=\"language-cpp\">void arm_cfft_f32(\n  const arm_cfft_instance_f32 * S,  \/\/\u590d\u6570 FFT \u63a7\u5236\u7ed3\u6784\u4f53\n        float32_t * p1,             \/\/\u6570\u636e\u8f93\u5165\u3001\u7ed3\u679c\u8f93\u51fa\uff0c\u8f93\u5165\u548c\u8f93\u51fa\u5747\u662f\u865a\u5e8f\u5217\uff0c\u5fc5\u987b\u6309\u201c\u5b9e\u90e8\u3001\u865a\u90e8\u3001\u5b9e\u90e8\u3001\u865a\u90e8\u3001\u3001\u3001\u201d\u7684\u987a\u5e8f\u5b58\u50a8\u6570\u636e\n        uint8_t ifftFlag,           \/\/0-FFT \u6b63\u53d8\u6362\uff0c1-FFT \u9006\u53d8\u6362\n        uint8_t bitReverseFlag)     \/\/0-\u7981\u7528\u8f93\u51fa\u4f4d\u7ffb\u8f6c\uff0c1-\u4f7f\u80fd\u8f93\u51fa\u4f4d\u7ffb\u8f6c\uff0c\u4e00\u822c\u9009 0<\/code><\/pre>\n\n\n\n<p>\u590d\u6570 FFT \u7684\u4f7f\u7528\u5982\u4e0b\u6240\u793a\u3002<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code lang=\"cpp\" class=\"language-cpp\">#include \"arm_math.h\"\n#include \"arm_const_structs.h\"\n\n\/\/FFT \u70b9\u6570\n#define FFT_LENGTH 1024\n\n\/\/\u4e3b\u51fd\u6570\nvoid main(void)\n{\n  static float32_t s_arrFFTInput[FFT_LENGTH * 2] = {0}; \/\/FFT \u8f93\u5165\u7f13\u51b2\u533a\n  static float32_t s_arrResult[FFT_LENGTH * 2] = {0};   \/\/FFT \u6a21\u503c\n\n  \/\/\u4e34\u65f6\u53d8\u91cf\n  u16 adc;\n  u32 waveCnt, i, pos;\n  float max;\n\n  \/\/\u6ce2\u5f62\u8ba1\u6570\u6e05\u96f6\n  waveCnt = 0;\n\n  \/\/\u4e3b\u5faa\u73af\n  while(1)\n  {\n    \/\/\u91c7\u96c6\u6ce2\u5f62\u4fe1\u53f7\n    adc = GetWaveADC();                      \/\/\u83b7\u53d6 ADC \u8f93\u5165\n    s_arrFFTInput[(2 * waveCnt) + 0] = adc;  \/\/\u5b9e\u90e8\n    s_arrFFTInput[(2 * waveCnt) + 1] = 0;    \/\/\u865a\u90e8\n    waveCnt++;                               \/\/\u8ba1\u6570\uff0c\u53ea\u9700\u8ba1\u6570\u5230\u6570\u7ec4\u5927\u5c0f\u7684\u4e00\u534a\n\n    \/\/\u91c7\u96c6\u591f\u4e86\u6570\u636e\u91cf\n    if(waveCnt &gt;= FFT_LENGTH)\n    {\n      \/\/\u865a\u6570\u5e8f\u5217\u5feb\u901fFFT\uff0carm_cfft_sR_f32_len1024 \u4e3a \"arm_const_structs.h\" \u63d0\u4f9b\u7684\u914d\u7f6e\u53d8\u91cf\uff0c\u5305\u542b\u5934\u6587\u4ef6\u540e\uff0c\u76f4\u63a5\u8c03\u7528\u5373\u53ef\n      arm_cfft_f32(&amp;arm_cfft_sR_f32_len1024, s_arrFFTInput, 0, 1);\n\n      \/\/\u6c42\u89e3\u6a21\u503c\n      arm_cmplx_mag_f32(s_arrFFTInput, s_arrResult, FFT_LENGTH);\n\n      \/\/\u8ba1\u7b97\u6ce2\u5f62\u9891\u7387\n      max = 0; pos = 0;\n      for(i = 1; i &lt; FFT_LENGTH \/ 2; i++)\n      {\n        if(s_arrResult[i] &gt; max)\n        {\n          max = s_arrResult[i];\n          pos = i;\n        }\n      }\n      printf(\"rate: %.1fHz\\r\\n\", (double)pos * 1000.0 \/ (double)FFT_LENGTH);\n\n      \/\/\u6e05\u7a7a\u6ce2\u5f62\u8ba1\u6570\n      waveCnt = 0;\n    }\n    \n    \/\/\u5ef6\u65f61ms\n    DelayNms(1);\n  }\n}<\/code><\/pre>\n","protected":false},"excerpt":{"rendered":"<p>\u8bb0\u5f55ARM DSP \u5e93\u4e0b FFT \u7684\u4f7f\u7528\u3002<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[6],"tags":[],"_links":{"self":[{"href":"https:\/\/www.huangrongzhen.ink\/index.php?rest_route=\/wp\/v2\/posts\/259"}],"collection":[{"href":"https:\/\/www.huangrongzhen.ink\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.huangrongzhen.ink\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.huangrongzhen.ink\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.huangrongzhen.ink\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=259"}],"version-history":[{"count":42,"href":"https:\/\/www.huangrongzhen.ink\/index.php?rest_route=\/wp\/v2\/posts\/259\/revisions"}],"predecessor-version":[{"id":333,"href":"https:\/\/www.huangrongzhen.ink\/index.php?rest_route=\/wp\/v2\/posts\/259\/revisions\/333"}],"wp:attachment":[{"href":"https:\/\/www.huangrongzhen.ink\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=259"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.huangrongzhen.ink\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=259"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.huangrongzhen.ink\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=259"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}