厉害厉害,赞一个
SDR开发还是一个蛮复杂的任务,上次虽然用python把基本流程跑通了,但是移植到具体的单片机上时还是遇到了不少的困难,突破困难后再看以前遇到的问题可能简单的不值一提,
由于基础差,sdr依赖的知识点又比较多,在未突破前几乎是困难重重,但是最终突破后的成就感还是令人欣慰的。
***********************************************************************************************************************************
这是我设计的流程图
初期为了简化硬件依赖,尽可能充分利用单片机内的自带资源,架构采用的是中波直采架构,
直采架构的优点是不用因硬件变频而需再引入si5351和模拟开关
天线信号,经过LNA低噪放大,直接进入单片机的ADC引脚进行采样,ADC的采样率设置的是2.4M理论上讲可以接收1.2M以内的中波信号
数字化的射频信号经DDC数字下变频,分解为IQ信号,
由于经过下变频,此时的IQ信号在基带,已经不需要2.4M的采样率,下一步经过DEC数据抽取降低到48K,
48K的IQ信号经过AM解码转变为音频数字信号
音频数字信号经过dac转换为模拟信号
模拟信号再经LM386放大后驱动喇叭
***********************************************************************************************************************************
这是我设计的LNA的电路图,为了简化低通网滤波,我直接用磁棒天线和可调电容调谐到一个固定的频率
在LNA上我卡了很长一段时间,最初犯了一个低级而致命的错误,LNA放大倍数不够而导致无法采集到足够的射频信号,因中波信号强度在10uv-到100uv,
经过一级放大有时信号太弱
***********************************************************************************************************************************
这是我放大20倍时的信号波形,可以看到峰峰值只有4mv,此时经过ad转换后无法进行后续解析出音频信号
***********************************************************************************************************************************
这是我增加一级放大后,20x20=400倍的信号波形,可以很明显的看到AM信号了,你们可能想象不到当我看到这个AM波形时自己激动的心情无法言表
***********************************************************************************************************************************
这是项目的依赖列表
单片机我选用的是stm32f407vg,选用f4主要是看中f4具有浮点运算能力
开发工具我还是选用我熟悉的vscode
插件还是platfromio
框架是选用的stm32cube框架,也就是基于HAL库来进行的单片机编程
***********************************************************************************************************************************
由于是用stm32cubeide进行的可视化配置,我这里把核心配置做一个说明
工程配置,代码生成勾选第一个选项
***********************************************************************************************************************************
时钟配置144M,这样PCLK2为72M,二分频后36M,36M/15=2.4M可以达到f407的最大采样率
***********************************************************************************************************************************
SYS配置Timebase Source为SysTick
***********************************************************************************************************************************
RCC配置时钟为外部晶振
***********************************************************************************************************************************
ADC1采用通道IN0,时钟二分频,12位精度,数据右对齐,开启持续转换,开启DMA请求,为了达到最大采样率,使用软件启动
***********************************************************************************************************************************
DMA开启循环模式,内存指针递增,数据宽度半字
***********************************************************************************************************************************
DAC开启通道1,启用缓存,time6触发
***********************************************************************************************************************************
DMA开启循环模式,内存指针递增,数据宽度半字
***********************************************************************************************************************************
启用TIM6,72分频,计数模式向上,计数装填21,这样72M/72/21=47.6K,开启自动装填,触发事件为updateEvent
***********************************************************************************************************************************
这是项目结构
***********************************************************************************************************************************
docs是相关截图说明文件
***********************************************************************************************************************************
include是头文件
***********************************************************************************************************************************
dsp.h只公开了compute_lo,process_sig两个函数
***********************************************************************************************************************************
main.h是公共头文件和常量
***********************************************************************************************************************************
src/core文件夹下的内容是通过stm32cubeide可视化工具配置自动生成的代码原样复制过来的,这里面的文件不建议直接修改,方便后期在可视化工具变更后同步覆盖
***********************************************************************************************************************************
dsp.c文件是dsp处理的核心文件,几乎所有的dsp相关处理逻辑都在这里,为了提高性能,调用了cmsis-dsp库函数
***********************************************************************************************************************************
lo_i,lo_q是NCO查表数据变量
***********************************************************************************************************************************
compute_lo是根据选择的频率生成NCO查表数据
***********************************************************************************************************************************
mix_sig是数字混频函数
***********************************************************************************************************************************
sum_filter是我自己编写的移动求和过滤抽取器,后面会用多级cic进行替代
***********************************************************************************************************************************
demod_am是am解码函数
***********************************************************************************************************************************
int2float是把数字射频信号映射到[-1,1]之间方便混频,混频数据值也在[-1,1]这个范围
***********************************************************************************************************************************
float2int是把[-1,1]范围的数据重新映射到[0,4096]之间
***********************************************************************************************************************************
process_sig是把上面的dsp处理逻辑串联起来进行数据处理
***********************************************************************************************************************************
main.c是程序主文件
***********************************************************************************************************************************
adc_value,dac_value是adc,dac数据存储变量
***********************************************************************************************************************************
Error_Handler是异常处理函数
***********************************************************************************************************************************
SystemClock_Config是系统时钟配置函数
***********************************************************************************************************************************
main函数是程序入口文件,在这里进行硬件初始化设置
***********************************************************************************************************************************
HAL_ADC_ConvHalfCpltCallback,HAL_ADC_ConvCpltCallback是adc采集一半和完成回调,回调函数里面把adc数据传递给process_sig进行数据处理,处理后的音频数据填充到dac
***********************************************************************************************************************************
这里有个注意事项就是platfromio默认配置是未开启浮点运算的,需要增加一个脚本和配置项才能正常启用浮点运算
***********************************************************************************************************************************
Test目录是我用python写的算法测试
creatSignal是模拟信号创建
sum_filter是滑动求和过滤器
compute_lo是NCO数据表创建
***********************************************************************************************************************************
我们来测试一下NCO数据表创建和滑动求和过滤器
***********************************************************************************************************************************
项目工程介绍完了,我们来试听一下效果,由于未进行进一步的滤波处理,噪音较大,但是能够出声,说明整体逻辑是正确的,这是艰难而伟大的一步跨越,为后续学习优化奠定了基础。
项目地址:direct-rf-v1中分支
XXXXXXXXXXXXXXXXX/zhuxianguo/stm32-f407vg-sdr
视频链接:
【STM32-F407VG-SDR-中波直采架构-哔哩哔哩】 XXXXXXXXXXXXXX/ohKx7ZD
***********************************************************************************************************************************
为保证文章的完整性,补充项目代码和视频文件如下:
项目代码:
视频文件:
STM32-F07VG-SDR.mp4 点击下载
***********************************************************************************************************************************
[修改于 1年2个月前 - 2023/10/14 20:05:04]
天线这里是20*20的放大
在三极管这边稍微处理一下,调个工作点,可能就直接出音频了
天线这里是20*20的放大在三极管这边稍微处理一下,调个工作点,可能就直接出音频了
实际AM信号完全可以不用IQ解调,用数字半波检波,IQ信号优势更多的是可以解调SSB边带信号,ASK,FSK,PSK等数字信号,这里用IQ信号解调AM纯粹是因为AM信号算法最简单,方便学习信号处理入门而已
牛!后面可以考虑使用内置高速ADC的芯片实现更多的功能了
每当看到这种帖子,总能让我为之一振,感觉到了未来和希望。
引用WernerPleischner发表于7楼的内容没抗混叠滤波器
有前置lc选频的
200字以内,仅用于支线交流,主线讨论请采用回复功能。