数字电压表设计教程之使用FPGA实现SPI协议通讯

天资达人 科技创新 2025-10-08 3382 0

代码解析

LTC2308通过一个标准4线SPI数字接口进行通信。LTC2308模数转换芯片有8个ADC通道和12位的分辨率,输入信号时钟频率范围不超过500KHz,按照Nyquist采样定理则建议输入信号在250KHz以下。

以下是DE10-Standard开发板上的LTC2308电路:

c92816c8-8c65-11f0-8c8f-92fbcf53809c.png

从电路图可知,LTC2308的COM引脚接GND,代表当前DE10-Standard开发板上的LTC2308被固定为单极性输入。

LTC2308的SPI协议时序图如下:

LTC2308控制模块(adc_ltc2308.v)框图如下:

c9ea0724-8c65-11f0-8c8f-92fbcf53809c.png

信号列表如下:

模块参数设计:

DE10-Standard开发板手册(DE10-Standard_User_manual.pdf)提到如果想设置采样率100Ksps,只需设置tHCONVST 为 320即可。接下来看看320这个数值是如何计算出来的。

根据LTC2308数据手册我们知道其最高采样率是500ksps, SCK最高能达到40MHz, tCONV 的典型值是1.3 us,最大值是 1.6 us。100Ksps的时间周期是10us,40MHz的时间周期是25ns。一次整个过程(包括转换和采样)要占用10us/25ns=400 个周期。1.6us/25ns= 64, 那么tCONV 最多占用64个时钟周期。

caa64cb8-8c65-11f0-8c8f-92fbcf53809c.png

根据时序图和代码来看,64+12+320=396大约是400 。

adc_ltc2308.v代码里面参数设定如下:

cb03b56a-8c65-11f0-8c8f-92fbcf53809c.png

代码详解:

一旦检测到触发信号measure_start的上升沿,adc_ltc2308 模块的系统复位信号就置0:

cb62783e-8c65-11f0-8c8f-92fbcf53809c.png

设计一个计数器,对LTC2308的一次完整转换和采集过程所需的时钟周期数进行数节拍:

cbba2c96-8c65-11f0-8c8f-92fbcf53809c.png

输出ADC_CONVST信号(也就是标记出tWHCONV时间段):

cc126b7c-8c65-11f0-8c8f-92fbcf53809c.png

输出SCK时钟,ADC_SCK周期为40MHz,但每一次只有12个周期输出,其他时间输出低电平0 :

cc6f7fec-8c65-11f0-8c8f-92fbcf53809c.png

在clk下降沿时刻,将转换完成的数据写入到到寄存器中:

ccc84f14-8c65-11f0-8c8f-92fbcf53809c.png

measure_done是一次采集完成标志,每次检测到LTC2308的触发信号上升沿时measure_done信号归0,当一次采集完成后置1:

measure_done是一次转换+传输+采样完成的标志,measure_done信号在开始新一轮采样后清0,当传输完成后置1:

cd2131b0-8c65-11f0-8c8f-92fbcf53809c.png

reset_n、clk_enable、measure_done、ADC_CONVST和ADC_SCK信号波形标出如下:

cd7c7e6c-8c65-11f0-8c8f-92fbcf53809c.png

根据输入(measure_ch)的通道选择不同的配置字存储到寄存器config_cmd:

cdd7c736-8c65-11f0-8c8f-92fbcf53809c.png

然后根据LTC2308的时序图标记出配置字的三个阶段(三个状态):config_init(配置初始化时间段) 、config_enable(可配置时间段) 和 config_done(配置完成时间段)。

config_init(配置初始化时间段):初始状态下,将配置字的高字节赋给ADC_SDI

config_enable(可配置时间段):将配置字剩余的5个bit逐个赋给ADC_SDI

config_done(配置完成时间段):配置完成阶段将0赋给ADC_SDI

ce390f46-8c65-11f0-8c8f-92fbcf53809c.png

ce9a4022-8c65-11f0-8c8f-92fbcf53809c.png

打开~DE10_Standard_ADCstp1.stp 文件(关于Signaltap调试工具的使用请参考之前的推文:SDRAM读写),采样时钟设置的是PLL outclk_0输出的100M,ADC_CONVST作为触发信号:

cef44770-8c65-11f0-8c8f-92fbcf53809c.png

可得到 LTC2308控制模块(adc_ltc2308.v)内部信号的波形如下。

测量11次,第一次的数据忽略, 取后面10次的数据:

cf5d2dc6-8c65-11f0-8c8f-92fbcf53809c.png

ADC_CLK 输出12个时钟周期:

cfbb2a84-8c65-11f0-8c8f-92fbcf53809c.png

若 stp1.stp 文件采样时钟设置为PLL outclk_1输出的40M,则波形细节如下:

ADC_CONVST占用4个时钟周期(tick=0、1、2、3):

d017cce4-8c65-11f0-8c8f-92fbcf53809c.png