cubemx,stm32f103c8t6最小系统板,arm的dsp库实现傅里叶变换,adc timer触发采样,dma传输,根据幅值最大点求信号频率,dds产生信号,dds简易信号发生器,只是记录一下

刚上大学的时候就很喜欢示波器,这个暑假想着弄一个,现在弄的基本差不多了,以后有时间了再优化优化

串口一是用来往电脑传fft结果看是否正确的,adc采集输入正弦波,我在串口一中断里加了几个判断,让ad9834产生正弦三角或者扫频,频率增加等功能,其他GPIO都是给ad9834用的,你不用就不用管,我也在头文件里标好9834的引脚了,照着连就可以

dma中点add,选自己的adc1,要注意,如果定时器触发的话,不能选circular,我自认为的解释是如果定时器触发,就是每次触发后,adc都会自动采集数据传送到缓冲区,然后再次触发又会从缓冲区的头部开始传输,所以我一开始串口打印的adc输入值不连续,data width选word,或半字也可以,取决于你的adc分辨率,我12位,图省心选了word,

这是adc设置,转换模式里enable,选我这里选的,每次计时器溢出会触发定时器的采样,相对于中断的好处是不需要进入中断服务处理,更省时间,把时间都留给fft(尽管这样,c8t6的速度还是很慢,我每次加了频率之后,要过一两秒才能出结果,一点都不实时,有条件的还是上f4吧)

tim3像图这样设置,不分频,我给APB2的设置是36Mhz,除以351,大概是102400,1024点的fft,能测试以1000分辨率的频率,我只是拿来测试,过两天用立创30块嫖的f4vgt6就能把分辨率拉高了

时钟树,不多说了

arm的dsp库非常方便,不需要像stm32官方库要复制进去,直接在keil里打勾就可以用

然后Include arm_math.h,ad9834是我用来产生标准正弦波测试fft结果的,没有可以不用,可以直接用matlab产生正弦波数组,或者直接在keil里写正弦的数组也一样,然后fft,效果是一样的

adcbuffer是dma传输到的位置,rxbuffer是串口接收缓冲区,用来接收串口的指令来控制9834产生不同波形,index用来判断哪个是fftout里最大的值,至于fftinput为什么是*2,因为他有虚数的部分,所以等下咱们赋值的时候咱们就要*2的赋值

要加上这两行才能启动adc的定时器触发和dma

主函数里是fft过程,cfft是fft过程,紧接着是求幅值,不过求不求都一样,因为咱们的输入没有虚数,赋值那样赋值是为了让虚部设置为0

注释掉的部分,图片最上面的发送数据底下,是没有外部正弦波时用的,自己设置一个正弦数组

最底下注释掉的部分是把fft结果打印出来,然后那个printf,是我用来给串口屏显示用的,你们直接注释就行,把fftoutput【0】设为0,让直流量为0,最后打印的时候,要把fftoutput先除以4096乘以3.3(adc值转为电压值),然后除以N/2(这是离散傅里叶变化的公式),这样才是真正的信号的幅度,如果要自己修改参数,修改定时器溢出时间可以设置adc采样率,采样率越大,能正确测得的频率越高,1024是fft的点数,最后fftout的元素是以采样率/fft点数为分辨率的,也就是fftoutput[1]是1000hz,fftoutput[2]是2000hz,加油吧,printf重定向部分在我的工程写好了,没什么有价值的东西,只是有一些坑可以让也想弄fft的同学避一避,比如dma不能设置circular,adc不能用continuous mode,还有就是定时器触发,dma加定时器触发就能最大限度的把时间留给fft了,希望大家看完能觉得有用,谢谢大家,我的第一篇

通过百度网盘分享的文件:sss.zip
链接:https://pan.baidu.com/s/1DG-oLDNSIsfxCm2G97-S8A?pwd=gusq 
提取码:gusq

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值