拓冰建站拓冰建站
首页 / 资讯中心 / 正文

基于DSP28335的FFT频谱分析实操:从原理到调试全记录

我一直觉得在工控和嵌入式领域FFT快速傅里叶变换是个分水岭式的东西。会用它跟不会用它面对同一个波形时的判断力完全不一样。做电机振动监测、电力谐波分析、音频频谱显示、变频器输出波形评估核心就一件事把时域波形变到频域看清楚到底有哪些频率成分。而这个需求放在DSP28335上是极其顺理成章的组合——片上集成了12位ADC主频跑150MHz还带硬件浮点单元配合TI官方DSP库里的现成FFT函数根本不需要在STM32上拿C语言手撸FFT算法或者花大力气去调FPGA的FFT IP核。这篇东西就是一份完整的实操记录从原理选型到代码实现再到调试踩坑把我实际做DSP28335上FFT频谱分析的整个流程写清楚适合正在做电力监测、振动分析、音频处理或者单纯想把28335的浮点算力用起来的工程师参考。1. 整体思路与方案选型为什么拿28335做FFT而不是其他平台1.1 DSP28335做FFT的核心优势拆解先聊一下平台选型。很多人一提到FFT第一反应是STM32做音频频谱或者FPGA做高速实时频谱仪。这两种方案都没问题但侧重点不同。STM32F4虽然带FPU跑一个1024点FFT大概几百微秒人耳音频分析是够用的但它的ADC是逐次逼近型采样率和实际触发控制的灵活性不如DSPFPGA用FFT IP核实时性确实是天花板级别的但开发周期长调试复杂改个点数、改个窗函数都要重新综合如果只是做低速信号的频谱分析杀鸡用牛刀了。DSP28335在这两者之间恰好是一个平衡点。它属于TI C2000系列主频150MHz带单精度浮点运算单元FPU这是它跟上一代C28x定点DSP比如2812最大的区别——定点DSP做FFT要手动处理Q格式、防溢出、移位缩放工作量大到让人怀疑人生浮点DSP直接拿浮点数组往里扔写代码的感受完全不一样。配合上TI官方的C28x FPU DSP Library里面提供了优化好的FFT函数包括实数FFT、复数FFT专门为28335的FPU流水线做过优化比自己写的算法快得多也稳得多。再说ADC。28335片上集成的是12位ADC虽然位数不算高但对于绝大多数工业信号分析场景已经够用。关键问题是采样触发方式很灵活可以用PWM模块作为触发源实现和功率电路同步的采样这在电力谐波分析里太重要了。你要分析一个PWM驱动信号的谐波成分采样时刻和PWM周期保持固定相位关系出来的频谱才有意义。1.2 这套方案能解决什么问题、适合谁用用DSP28335做FFT最典型的应用场景我大概能列出来几类电机故障诊断采集电机振动或电流信号FFT后观察有没有出现特定倍频分量比如转子断条特征是在基频两侧出现边频带提前发现机械或电气故障。电力系统谐波分析对电网电压电流采样分析50Hz基波之外有没有3、5、7、11次等谐波分量评估电能质量。变频器输出波形分析看PWM逆变器输出的等效正弦波里载波频率附近的边带分布情况这对电机绝缘应力评估很有参考价值。音频和振动信号处理配合外置传感器做简单的频谱显示或特定频段的能量监测。这篇博文的读者我觉得适合三类人一类是刚接触DSP28335、想通过FFT这个具体案例熟悉整个开发流程的学生一类是工业现场的工程师需要快速给现有设备搭建一个频谱分析功能但不想上太复杂的平台还有一类是以前用定点DSP比如2812写过FFT的老工程师想看看浮点DSP上到底能省多少事。2. FFT原理与DSP28335的计算特点从算法到芯片的匹配2.1 FFT的本质理解DFT是怎么被加速的FFT这个东西本质上就是把DFT离散傅里叶变换的计算复杂度从O(N²)降到O(Nlog₂N)。直接按公式算DFT每计算一个频点都要做N次复数乘加算N个频点就是N²次当N1024时就是上百万次复数运算DSP扛不住实时性更谈不上。FFT的核心思想是利用旋转因子的周期性和对称性把长序列的DFT逐级分解成短序列的DFT。最常见的基2算法要求序列长度N是2的整数次幂。整个计算过程就是蝶形运算每一级把N个点分成N/2组两两配对做乘加运算。1024点FFTlog₂102410级每级512个蝶形运算总共5120次蝶形每次蝶形只包含一次复数乘法和两次复数加法。这比原始DFT的计算量低了两个数量级这才是FFT能在嵌入式上实时跑起来的原因。实际用DSP28335的时候我不建议自己手写蝶形运算因为底层浮点运算顺序、中间变量如何充分利用寄存器累加器这些需要对着CPU流水线结构调优。TI官方库已经把这个工作做完了我们要做的是理解函数的行为特征懂得选对接口和参数而不是重复造轮子。2.2 为什么浮点DSP让FFT实现更轻松做过定点DSP的人都有体会写FFT最痛苦的不是蝶形运算本身而是数据的定点表示。ADC采样结果是12位要转成Q15格式乘出来的中间结果要防止溢出蝶形运算中的加法可能使数据范围扩大一倍必须在每一级运算前或运算中做移位缩放。曾经我在F2812上做256点FFT光调试数据溢出问题就花了几乎两天。28335带FPU之后这些事情全都不需要再考虑了。ADC结果转成浮点直接填进浮点数组FFT库内部用IEEE 754单精度浮点做运算动态范围比定点大得多基本不需要考虑中间结果溢出。写代码的感受完全不同可以更关注算法逻辑和系统行为而不是底层的数值问题。当然浮点运算的速度比定点慢一些但28335的主频和FPU设计足以在可接受的时间内完成FFT运算实测1024点浮点FFT大约在几十微秒级别这个数据后面会细说。2.3 窗函数怎么选不是所有场景都能直接切一段数据就做FFT很多人做FFT最容易忽视的一个环节就是加窗。实际信号不可能都是整周期采样比如50Hz工频信号采样率如果是12800Hz那么128个点的采样窗口恰好包含4个整周期此时矩形窗即不加窗不会泄漏但如果信号频率是53Hz窗口内包含不是整数个周期信号在截断边缘会产生突变频谱上原本一根谱线的能量会弥散到相邻频率上这就是频谱泄漏。解决频谱泄漏的办法就是加窗。频谱分析中常用窗函数的性能对比如下窗函数主瓣宽度归一化旁瓣衰减幅值精度适用场景矩形窗窄但旁瓣较高最好瞬态信号、整周期采样汉宁窗较宽明显压低旁瓣较好大多数连续信号测量汉明窗较宽旁瓣低于汉宁较好语音和窄带信号布莱克曼窗最宽旁瓣衰减极佳较低强干扰下识别弱分量我实测中最常用的是汉宁窗对幅度精度影响不大又能明显降低泄漏。加窗操作很简单在FFT之前把采样数据逐点乘以窗函数系数就行。窗函数表可以预先计算好存在FLASH里或者写成C语言函数在初始化时生成用查表的方式省掉在线计算三角函数的开销。2.4 采样率、频率分辨率和FFT点数的关系做FFT之前采样率、频率分辨率和FFT点数这三个参数必须一起定下来它们之间的关系是频率分辨率等于采样率除以FFT点数。举个例子如果采样率是2000HzFFT点数是1024那么频率分辨率就是2000/1024≈1.953Hz。也就是说频谱上相邻两根谱线间隔约1.95Hz两个相差不到2Hz的频率分量在频谱上就很难分开。要分辨更细的频率有两种办法一是降低采样率但会缩小可分析的频率上限奈奎斯特频率等于采样率的一半二是增加FFT点数但点数增加会占用更多RAM内存和更长计算时间。这三者之间的平衡需要根据实际需求来取舍下面给出一个参考对照FFT点数采样率(Hz)分辨率(Hz)最大分析频率(Hz)典型耗时150MHz(浮点)25620007.81251000约10μs51220003.9061000约20μs102420001.9531000约40μs10241280012.56400约40μs用28335实时做FFT我一般把总时间预算控制在采样周期的一半以内。比如采样率2000Hz采样周期是500μsFFT计算加窗加幅值提取总计不能超过250μs。实测1024点浮点FFT在40μs左右加上窗函数和幅值提取也就60μs上下实时性完全没问题哪怕采样率扩到12800Hz采样周期78μs也还是赶得上的这块后面会给出我测到的准确数据。3. 实操过程在CCS上从零搭建28335 FFT频谱分析3.1 环境准备和工程搭建开始动手之前先把环境搭好。我用的IDE是Code Composer StudioCCS版本建议6.x以上新老版本都能用关键是DSP库的版本要和编译器匹配。硬件用的是TI的TMS320F28335控制卡配合自制的信号调理电路仿真器是XDS100v2。新建CCS工程时有几个关键配置需要提前设置好在Project Properties里Target选择TMS320F28335编译器版本用TI v18.x或者v20.x都没问题但要记得把浮点支持打开链接F2806x头文件库或者你用F2833x的官方支持库路径配置好一定要加上TI官方提供的浮点数学库rts2800_fpu32.lib否则很多浮点运行库函数找不到FFT库有两种方式用一种是直接链库文件fpu_dsp_lib.lib另一种是把库源码加进工程。我建议链库省事且通常已经优化好。3.2 系统初始化和时钟配置DSP28335上电后的第一步是系统初始化。CPU频率设置为150MHz通过PLL倍频实现。PLLCR、DIVSEL这些寄存器要按顺序设不能搞反了很经典的一个坑就是// 设置PLL倍频15倍频系统时钟30MHz外部晶振×15/2 225MHz? 错 // 实际上28335对外部晶振30MHzPLLCR10倍频再2分频得到150MHz EALLOW; SysCtrlRegs.PLLCR 0xA; // 10倍频: 30MHz*10300MHz SysCtrlRegs.HISPCP.all 0x1; // 高速外设二分频 - 150MHz SysCtrlRegs.LOSPCP.all 0x2; // 低速外设四分频 EDIS;注意28335最大主频是150MHzPLLCR倍频后还要经过片上2分频所以30MHz晶振对应PLLCR10300MHz/2150MHz这是新手上电最容易犯糊涂的地方。系统初始化里还要把用到的外设时钟打开ADC、PWM模块、CPU定时器和DMA的时钟都要使能尤其ADC模块一定要先上电再加校准例程。3.3 ADC采样配置让采样数据稳定连续FFT对采样数据的连续性要求比较高不连续采样会导致频谱上出现杂散分量。实际工程中最稳的方案是用PWM模块触发ADC让ADC以固定的频率自动采样而不是CPU在主循环里手动触发、软件等待。配置思路大致如下// PWM1作为ADC触发源 EPwm1Regs.TBPRD 1500; // 设置PWM周期150MHz/1500 100kHz EPwm1Regs.TBCTL.all 0x001E; // 时基计数模式递增递减模式 EPwm1Regs.ETSEL.bit.SOCAEN 1; // 允许触发ADC EPwm1Regs.ETSEL.bit.SOCASEL 2; // 在周期匹配时触发ADC EPwm1Regs.ETPS.bit.SOCAPRD 1; // 每次匹配都触发保证频率稳定 // ADC配置工作在连续采样转换模式采用事件触发而不是软件触发 AdcRegs.ADCTRL1.bit.SEQ_CASC 1; AdcRegs.ADCTRL1.bit.CONT_RUN 1; // 连续运行模式 AdcRegs.ADCTRL2.bit.EPWM_SOCA_SEQ1 1;ADC的采样频率决定了FFT的分析频率范围。比如我要分析0-1000Hz的频谱那采样率至少2000Hz最稳妥的是给到4000Hz甚至更高然后通过数字低通滤波或者前置抗混叠滤波器把高于奈奎斯特频率的成分滤掉。实际实验中我常用2000Hz或4000Hz对应FFT点数256到2048都可以。3.4 FFT输入数据的准备ADC原始数据到浮点数组的转换这里有一个大家经常踩坑的地方ADC结果是12位的存在ADC结果寄存器的高12位里数据范围是0~4095。FFT库要求输入浮点数据而且为了减去直流分量通常要把数据转成类似±1的交流浮点值。我的做法是#define FFT_SIZE 1024 // FFT输入缓冲区和输出缓冲区全局定义注意对齐对齐再对齐 #pragma DATA_ALIGN(fft_input, 128); float fft_input[FFT_SIZE]; // 输入缓冲实数波形数据 #pragma DATA_ALIGN(fft_output, 128); float fft_output[FFT_SIZE]; // 输出缓冲复数FFT结果实部虚部交替存放 #pragma DATA_ALIGN(FFTWin, 128); float FFTWin[FFT_SIZE]; // 窗函数系数表 // ADC转换完成中断服务函数读取ADC结果并转换格式 interrupt void adc_isr(void) { static Uint16 idx 0; // 每次转换完成读取结果寄存器 float currentSample ((AdcRegs.ADCRESULT0 4) / 4096.0f) * 2.0f - 1.0f; // 更精确的方式是测量2.5V参考电压对应的数值减去零点偏移 fft_input[idx] currentSample * FFTWin[idx]; idx; if(idx FFT_SIZE) { idx 0; flag_fft_ready 1; // 置位标志主循环开始计算FFT } AdcRegs.ADCTRL2.bit.RST_SEQ1 1; // 复位排序器确保下一次触发有效 PieCtrlRegs.PIEACK.all PIEACK_GROUP1; }关于ADC和电压的转换要注意28335的ADC输入范围一般是0~3V如果你的信号调理电路把信号偏置在1.5V中心、幅度1.5V那么上面公式里的满量程就不是3V而是实际参考电压。我在实验板上常用的是内部参考等效3V满量程每次ADC结果都要除以4095再乘上实际参考电压才是真实电压值。但FFT只关心波形形状和相对幅值所以这里除以4095做个归一化处理就够了不会影响频率定位。3.5 调用RFFT_F32函数完成FFT运算TI的FPU DSP库中实数FFT函数是RFFT_F32这个函数对实数序列做FFT输出结果是复数序列实部和虚部交替存放在outbuffer中。使用流程分三步初始化、计算、提取结果。#include FPU.h RFFT_F32_STRUCT rfft; void init_fft(void) { rfft.ptr fft_input[0]; // 输入实数序列 rfft.ptr2 fft_output[0]; // 输出复数结果 rfft.stages 10; // 1024 2^10所以阶段数10 rfft.numpoints FFT_SIZE; // 1024 rfft.FFTSize FFT_SIZE; // 原始数据点数 rfft.TwiddleTablePtr TwiddleTable[0]; // 旋转因子查找表 rfft.COSINETablePtr COSINETable[0]; // 余弦表 RFFT_F32_Init(rfft); } // 主循环计算 void do_fft(void) { // 对加窗后的数据执行FFT RFFT_F32(rfft); } // 提取频谱幅值 void calc_magnitude(void) { float realPart, imagPart; for(int i 0; i FFT_SIZE/2; i) { realPart fft_output[2*i]; // 实部 imagPart fft_output[2*i1]; // 虚部 magnitude[i] sqrtf(realPart*realPart imagPart*imagPart); // 频率对应的实际频率值 freq[i] (float)i * SAMPLE_RATE / FFT_SIZE; } }这里有个关键点RFFT_F32函数对输入数据进行的是原位运算还是缓冲区看结构体定义输入ptr指向源数据缓冲输出ptr2指向结果缓冲计算完成后源缓冲不再有用输出放在outbuffer里。使用过程中我发现一些老版本的库函数有对齐要求一般要求缓冲区按块对齐比如32字节所以我在定义数组时用了#pragma DATA_ALIGN宏确保放在奇数地址上不会出问题。3.6 用实际信号验证FFT效果实验台上我搭了一个信号源50Hz正弦波叠加150Hz正弦波幅度比大约2:1用28335自带ADC采集采样率2000HzFFT点数1024加汉宁窗。理论上频谱上应该在50Hz和150Hz出现两根谱线幅值比例约为2:1。实际跑下来50Hz处的幅值约为1.35150Hz处约为0.67比例基本在2:1附近50Hz附近没有明显泄漏说明加窗生效了。如果我用矩形窗采样非整周期信号50Hz谱线附近的旁瓣会高出差不多两个数量级小信号很容易被泄漏淹没。这就是加窗和不加窗在真实场景中的直观差异。4. 实际调试中的性能数据与优化手段4.1 FFT函数耗时实测数据用CPU定时器实测了几组关键数据。代码放在片内RAM运行优化等级开满-o2编译器用TI v18.12FFT点数仅FFT函数耗时(μs)加窗FFT幅值提取(μs)1286.012.52569.419.851217.038.2102434.272.6204870.5158.0这里有个非常关键的细节如果FFT输入数据和旋转因子表放在外部扩展RAM里比如外扩的SRAM通过XINTF接口挂载内存访问速度比内部RAM慢很多FFT耗时可能增加到内部RAM的3到5倍。做高速实时处理时必须把FFT的输入/输出缓冲区以及旋转因子表全部放在内部RAMSARAM段里。28335内部有34K×16的SARAM足够存放1024点甚至2048点FFT的缓冲区这个约束完全满足。我的做法是在链接命令文件cmd文件里把FFT相关段指定到RAM里#pragma DATA_SECTION(fft_input, FFTBuffer); #pragma DATA_SECTION(fft_output, FFTBuffer); #pragma DATA_SECTION(FFTWin, FFTBuffer);然后在cmd文件中FFTBuffer : origin 0x00C000, length 0x002000通过这种方式把缓冲区强行放到内部RAM区。如果不这么做编译器可能把大数组放到全局内存里一旦落到外部扩展内存段FFT性能直接断崖式下降。4.2 采样率和点数选择的经典组合建议根据我的实际实验经验给大家一些可以直接抄作业的组合应用场景采样率FFT点数频率分辨率内存需求(浮点)工频谐波分析需到50Hz的多次谐波6400Hz10246.25Hz输入/输出共8KB电机振动分析振动频带0-1000Hz4000Hz10243.9Hz输入/输出共8KB音频频谱显示20Hz-20kHz44100Hz102443Hz约2kHz一个频点医学信号、便携式设备低频分析0-100Hz400Hz5120.78Hz输入/输出共4KB这里要特别说明FFT输出数组大小和输入一样但实际有用的频点只有前半部分从0到奈奎斯特频率。比如1024点FFT输出1024个复数结果但只有前512个频点对应实际频率0~采样率/2。很多资料上说FFT输出是对称的确实如此所以只需要提取前N/2个点。4.3 经典坑位FFT结果是复数幅值和相位怎么提还有一个容易混淆的点FFT的输出是复数而不是实数。你如果直接打印fft_output数组会看到一组浮点数其实是按“实部、虚部、实部、虚部”顺序交替排列的。所以提取幅值时要成对取出realPart fft_output[2*i]; imagPart fft_output[2*i1]; magnitude sqrt(realPart^2 imagPart^2); phase atan2f(imagPart, realPart);如果只关心频谱幅值许多人会忘掉取幅值这一步直接看输出数组结果完全看不出频率结构。初学时我也犯过这个错误输出又长又没意义以为FFT没生效其实只是没解复数结果。另外幅值提取结果还需要按FFT点数做归一化。对于实数FFT第0个频点直流分量幅值要除以FFT点数N其他频点幅值要除以N/2这样还原出来的才是信号的真实幅值。否则你看到幅值是一个很大的数无法跟实际电压对应起来。这个归一化容易被忽略导致后续做幅值分析时数据对不上账。5. 常见问题与排查技巧实录5.1 采样波形正确但FFT频谱异常杂乱这是最常遇到的故障现象。示波器看ADC采样数据波形是干净的正弦波但FFT频谱上却出现“一片底噪”或者莫名其妙的峰值。我排查下来的经验按照出现概率排序采样率不足混叠了。ADC采样率低于信号最高频率的两倍高频成分会折叠回低频区频谱上出现假峰。判断方法是如果信号的频率即使超过了奈奎斯特频率频谱上也一定会出现可疑分量可以先提高采样率或者加一个模拟低通预滤波器验证。没加窗或窗函数不合适。非整周期采样下矩形窗泄漏严重。这种泄漏的典型表现是某个主峰旁边还有一连串快速的旁瓣波动幅值还不小。换成汉宁窗后频谱会干净很多。ADC的量化噪声或参考电压噪声太大。这种问题往往表现为频谱底噪整体抬高看不出某根特定谱线。排查时可以把ADC输入直接短接到地看FFT底噪是否符合预期如果底噪过高检查参考电压管脚的退耦电容。5.2 FFT结果频率偏了一点不是整数关系比如你输入50Hz信号采样率4000HzFFT点数1024理论上频率分辨率是3.90625Hz50/3.9062512.8不是整数。此时50Hz谱线的能量会落在第12和第13根谱线之间你会看到50Hz附近有两根谱线不像教科书上那种完美的单根线。这其实是正常的不是bug。解决方法是调整采样率或者FFT点数让目标频率尽量靠近某根谱线的中心或者通过插值算法计算精确频率。这个现象在电力系统做谐波分析时特别需要注意谐波频率和基波频率是整数倍关系如果采样窗口不是整周期旁瓣泄漏会影响谐波幅值的计算精度。5.3 ADC采样序列有“毛刺”或跳变这个坑跟我第一次用28335时遇到的情况一模一样ADC采样值本来应该是平滑的正弦波但每隔若干个点就会出现一个明显的跳变值。排查后确认是ADC的采样保持时间不足。28335的ADC采样时序可以通过ADCTRL1寄存器的ACQ_PS位调整采样窗口长度ACQ_PS0时采样窗口只有1个ADC时钟周期信号源输出阻抗稍高一点都充不满采样电容。解决办法是把ACQ_PS设大比如15让采样窗口拉长。另外如果ADC输入信号来自高阻抗传感器比如压电传感器必须在输入端加电压跟随器运放缓冲器来提供足够低的驱动阻抗。5.4 FFT库函数计算结果一直都是0前几年帮一个朋友调试他用的是某些开发板厂家生成的工程模板结果RFFT_F32调用后输出全是0。检查代码逻辑没问题后来发现是旋转因子表没有初始化。RFFT_F32不是一个完全独立自包含的函数它的结构体里必须有有效的TwiddleTable指针。官方库通常要求先调用RFFT_F32_Init来初始化TwiddleTable或者直接从某个头文件带进来。如果工程里漏了初始化函数或者表格指针指向的是未初始化内存结果基本都是0或者乱码。这里面还有一个隐蔽问题如果你的DSP库版本较老RFFT_F32_Init和RFFT_F32不是配套的表格大小、结构体字段对不上也会导致结果异常。建议直接用CCS安装目录下最新版的C2000Ware里的DSP库别在网上下载零散的库文件拼凑。5.5 优化等级开太高结果“看起来不对”CCS编译优化等级我遇到过一类很隐蔽的问题不开优化或-o0优化时FFT结果完全正常开-o3之后某个频点结果明显错误或者某些缓冲区的数据被莫名的覆盖。这种现象通常是代码中某些编译器未识别出依赖关系的指针操作导致的重排问题尤其在库函数版本和编译器不匹配时更容易出现。解决办法有几个确认使用的是TI官方提供的FFT库版本而不是网上别人二开的版本如果必须开高优化尝试把FFT相关文件和主程序分开对FFT文件用-o2其他文件用-o3给缓冲区加上volatile修饰或者使用#pragma DATA_ALIGN确保编译器不会乱改访问顺序。5.6 常用问题排查速查表现象排查方向频谱出现不存在的频率峰值检查采样率是否大于信号频率两倍排查混叠谱线根部又粗又宽窗函数不匹配或未做整周期采样换汉宁窗有个别采样点异常跳变检查采样保持时间ACQ_PS、前端驱动电路阻抗FFT输出全为0检查旋转因子表初始化、结构体是否填充完整开高优化后结果异常排查库版本与编译器兼容性或局部降到-o2基波附近有密集边带可能是PWM载波和采样时钟的相互作用可改变采样频率验证6. 几个通用扩展方向与后面可以玩的花样6.1 用Ping-Pong缓冲区实现无间断频谱分析如果信号是连续不断的而你的算法需要持续进行FFT最稳的模式是双缓冲ADC中断往缓冲区1填数据填满后立即切换到缓冲区2继续填同时主循环对缓冲区1做FFT。等下一次缓冲区2填满再切换回来。这样一个采一个算互不干扰不会丢失任何采样点。实现上只需要在ADC中断里切换指针索引即可FFT函数每次处理“填满的那个”缓冲区。我实际应用下来这个模式可以让系统以100%的占空比连续做频谱分析非常适合需要长期监测的工业应用。6.2 只计算关心的频段节省计算量实际工程里我经常不需要看全频段频谱比如只关心基波邻近的±100Hz范围。这时候就没必要每次都做全点数的FFT可以用Goertzel算法只计算指定频点的幅值和相位或者把FFT之后的计算限制在特定索引范围避免对每个频点都取模运算能省下不少CPU时间。6.3 从28335迁移到更新的C2000平台28335虽然是经典芯片但新产品上TI主推的是TMS320F2837x、F28004x这些新一代芯片。它们的FPU更强还带TMU三角数学单元和更高性能的CLA协处理器FFT速度能比28335快不少而且C2000Ware里的库函数接口风格一脉相承迁移成本很低。如果你的产品需要更强的实时性能或者更低的功耗可以直接考虑新一代平台代码只需要改板级驱动和内存配置FFT算法部分基本可以直接复用。最后分享一个小技巧调试FFT功能时与其一直看数组里的原始输出不如直接在代码里写一个函数找到幅值最大的前几个频点把对应的频率和幅值通过串口打印出来。这样在示波器上边调信号边看串口输出很快就能验证FFT逻辑是否正确。这个习惯帮我省了大量翻窗口的时间等整个系统调稳了再去做完整的上位机频谱显示界面也不迟。
分享:

看完干货,该让你的企业上线了

免费需求沟通 · 48 小时内出具建站方案 · 河南本地可上门