
水水更健康~ 技术力不高,欢迎轻拍指正((

可能用FPGA驱动低速ADC有点“大马拉小车”的感觉,但还是想借机熟悉Verilog。另一方面,玩耍开心就好,还是不要太在意整体成本的合理性了((
1、SPI接口和对应模式



ADS1259是SPI接口,其时钟空闲低电平,数据在时钟下降沿采样。
即时钟极性CPOL=0,时钟相位CPHA=1,对应SPI mode 1。

其SPI时钟频率不超过系统时钟的1/1.8,即应小于4MHz(7.3728/1.8)。
将时钟拉低9ms左右可复位SPI接口。一些隔离场景,需要CS脚接地以简化连线,此时仍可通过拉低时钟完成复位,这对稳定性有利。
2、转换模式和START脚
转换模式分为门控(Gate Control)和脉冲控制(Pulse Control)。
在门控模式下,START脚拉高或发送START命令会启动连续采样,只有在拉低或发送STOP命令后才会停止。采样过程中,只需等待DRDY下降沿读取数据。
门控模式适合于以固定采样频率连续采集的场景。但若配合外部模拟开关进行多通道轮询,需注意通道切换后的建立时间。

在切换瞬间采集到的并非最新值,因此应丢弃前几个无效样本。上图标示了应丢弃的样本数。
在脉冲控制模式下,拉高START引脚或发送START命令会触发一次单次采样,采样完成后自动停止。只有再次拉高START引脚或重新发送START命令,才会启动下一次采样。

脉冲控制模式下的每次转换都需要等待上图所示的建立时间,因此无法达到设定的采样频率,适合于外部触发的单次采样。门控模式下存在1个建立时间的滞后,但能保持特定采样频率连续采样。

总结:
① 由于这里希望以3.6KHz连续采样,所以应当选择门控模式;
② CS脚可以保持接地,因为拉低一段时间的SCLK同样可以复位接口;
③ START引脚可固定接地或接VDD,采样由命令控制即可,引脚控制与命令控制功能等效、互为平级。
3、命令和寄存器

这里主要关注7条命令:
START:门控模式下触发连续转换,脉冲控制模式下触发单次转换;
STOP: 停止门控模式下的连续转换,脉冲控制模式下无需关注;
RDATA:读取样本数据;
RDATAC/SDATAC:开启或退出连续读取。连续读取下无需发送RDATA命令,等待DRDY下降沿后可直接读取3字节样本数据。
RREG/WREG:读和写寄存器。

初始化与3个寄存器有关,这里的初始化流程如下:
① 0x06:RESET命令复位所有寄存器,非必需但做了更“优雅”(((
② 0x40:前4位(0100)表示WREG命令,后4位(0000)表示起始地址,即从0h开始写入;
③ 0x02:写入寄存器数量减1,初始化需写3个寄存器。
④ 0x05、0x10、0x06 :对应寄存器CONFIG0~2,设置采样频率3.6KHz、SINC2、门控模式等。
SPI主机是copy的 https://github.com/nandland/spi-master
控制逻辑比较简单: 考虑到这里ADC的隔离电源和FPGA上电不同步,因此上电先延时一段时间等待硬件稳定,然后发送一段初始化序列,最后进入采样状态,中途可以发送停止或重启命令(后者实际没有写,俺想其实停止的时候可以由单片机控制断电,复电时重新初始化)。
这里萌新想尝试三段式状态机。(虽然后来又感觉,不复杂的过程顺着思路直接描述其实可读性更好欸!或许可以相信综合器的智慧、并没有必要执着于三段式。)

三段式的第一段负责时序逻辑:更新次态到现态;自增延时计数器。

第二段是组合逻辑:描述状态的转移规律,由现态推出次态。
延时状态对应三种不同延时值,上电延时的时间最长。

第三部分负责各状态下的输出:在spi_tx_ready上升沿,将对应状态的命令发送给ADC。
例子的网盘链接在结尾贴出。
1、系数的生成

用MATLAB FDATool生成199阶的低通。抽头数是阶数加1,为200。

点击设置量化参数,这里的ADC是24位,因此系数和输入输出位宽均设置成24位。

点击“文件” - “导出”,选择导出系数为二进制。

删除导出文件中的注释,仅保留二进制系数。
在VSCode中按住shift+alt,框选多余的空格并删除。

把系数重命名为txt文本,保存在工程目录下,将文件路径添加到云源中。

通过这种方式,综合器会把系数文本替换到数组中。 2、IP核的使用

设置输入和系数位宽均为24bit,输出位宽是固定的54bit,119阶抽头数200。

乘法器阵列长度越大,运算速度越快。由于ADC采样频率很低,选最小长度以节省资源。 3、输出的截位 数据有效位宽是24bit,而IP核固定输出位宽54bit,需要截取其中的一部分。

输入一个使ADC饱和的信号,在ILA中观察FIR滤波器的输出。
由于高4位始终不变,将第50位作为符号位,截取[50:27]。

后来发现,这样做幅值是正常的,但信号的底部或顶部在一些频点会发生翻转。

尝试向上截取[51:28]后,在任何情况下都不会翻转。
但大多数时间高2位都相同,使幅值小了一半。

翻转的本质在于滤波器输出范围略超出[50:27],这可能是因为滤波器有带内波动,饱和时一些频点的幅度大于0dB导致溢出。
考虑到实际信号的幅值通常较小,这里添加钳位,牺牲一部分动态范围,保障小幅值时的精度。
demo下载链接:
https://pan.baidu.com/s/1us9ABtsoEGmKXm9fSLoTGA?pwd=4kw7