拿到ADI的EVAL-AD7616SDZ评估板时,很多工程师的第一反应是既兴奋又忐忑——这款16位双通道同步采样ADC的性能确实令人期待,但如何快速搭建原型系统却是个现实挑战。本文将带你用STM32F4开发板,以最直接的方式完成从硬件连接到双SPI数据采集的全流程实现。
AD7616支持四种工作模式,我们选择软件串口模式来实现寄存器配置功能。评估板上的跳线设置如下:
与STM32F407 Nucleo板的连接需要特别注意双SPI的时钟同步问题。以下是关键连接表:
| 评估板引脚 | STM32F4引脚 | 功能说明 |
|---|---|---|
| CNVST | PE3 | 转换启动信号 |
| SCLK | PE2 | SPI4主时钟 |
| SDIA | PE6 | SPI4主数据线 |
| SDOA | PE5 | SPI4从数据线 |
| SDIB | PF7 | SPI5主数据线 |
| SDOB | PF6 | SPI5从数据线 |
| CS | PE4 | 片选信号 |
| BUSY | PA5 | 转换状态指示 |
| RESET | PA4 | 复位信号 |
注意:SPI4和SPI5必须使用同源时钟,在STM32F4中SPI2/3和SPI4/5是两组共享时钟源的SPI接口。
双SPI配置的核心在于主从模式的协同工作。以下是使用标准外设库的初始化代码:
c复制// SPI主从模式初始化
void SPI4_5_Init(void)
{
SPI_InitTypeDef SPI_InitStruct;
GPIO_InitTypeDef GPIO_InitStruct;
// 启用时钟
RCC_APB2PeriphClockCmd(RCC_APB2Periph_SPI4, ENABLE);
RCC_APB2PeriphClockCmd(RCC_APB2Periph_SPI5, ENABLE);
// 配置SPI4为主模式
SPI_InitStruct.SPI_Direction = SPI_Direction_2Lines_FullDuplex;
SPI_InitStruct.SPI_Mode = SPI_Mode_Master;
SPI_InitStruct.SPI_DataSize = SPI_DataSize_16b;
SPI_InitStruct.SPI_CPOL = SPI_CPOL_High;
SPI_InitStruct.SPI_CPHA = SPI_CPHA_1Edge;
SPI_InitStruct.SPI_NSS = SPI_NSS_Soft;
SPI_InitStruct.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_16;
SPI_InitStruct.SPI_FirstBit = SPI_FirstBit_MSB;
SPI_Init(SPI4, &SPI_InitStruct);
// 配置SPI5为从模式
SPI_InitStruct.SPI_Mode = SPI_Mode_Slave;
SPI_InitStruct.SPI_Direction = SPI_Direction_2Lines_RxOnly;
SPI_Init(SPI5, &SPI_InitStruct);
SPI_Cmd(SPI4, ENABLE);
SPI_Cmd(SPI5, ENABLE);
}
GPIO初始化时需要特别注意BUSY信号的检测方式。推荐使用外部中断而非轮询,以提高系统响应速度:
c复制// BUSY信号中断配置
void BUSY_EXTI_Config(void)
{
EXTI_InitTypeDef EXTI_InitStruct;
NVIC_InitTypeDef NVIC_InitStruct;
// 配置PA5为外部中断输入
GPIO_InitStruct.GPIO_Pin = GPIO_Pin_5;
GPIO_InitStruct.GPIO_Mode = GPIO_Mode_IN;
GPIO_InitStruct.GPIO_PuPd = GPIO_PuPd_NOPULL;
GPIO_Init(GPIOA, &GPIO_InitStruct);
SYSCFG_EXTILineConfig(EXTI_PortSourceGPIOA, EXTI_PinSource5);
EXTI_InitStruct.EXTI_Line = EXTI_Line5;
EXTI_InitStruct.EXTI_Mode = EXTI_Mode_Interrupt;
EXTI_InitStruct.EXTI_Trigger = EXTI_Trigger_Falling;
EXTI_InitStruct.EXTI_LineCmd = ENABLE;
EXTI_Init(&EXTI_InitStruct);
NVIC_InitStruct.NVIC_IRQChannel = EXTI9_5_IRQn;
NVIC_InitStruct.NVIC_IRQChannelPreemptionPriority = 0x0F;
NVIC_InitStruct.NVIC_IRQChannelSubPriority = 0x0F;
NVIC_InitStruct.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStruct);
}
AD7616的初始化流程需要严格按照时序要求:
以下是关键操作函数:
c复制// 寄存器写入函数
int32_t AD7616_WriteReg(ad7616_dev *dev, uint8_t reg, uint16_t value)
{
uint16_t txData = 0x8000 | ((reg & 0x3F) << 9) | (value & 0x1FF);
CLR_CS();
SPI4_SendByte(SPI4, txData);
SET_CS();
return 0;
}
// 双通道数据读取
int32_t AD7616_ReadDualChannel(uint16_t *chA, uint16_t *chB)
{
uint16_t dummy = 0;
CLR_CS();
*chA = SPI4_ExchangeData(SPI4, dummy);
*chB = SPI4_ExchangeData(SPI5, dummy);
SET_CS();
return 0;
}
采样触发和数据采集的典型流程:
c复制void AD7616_SampleProcess(void)
{
static uint16_t chA_data, chB_data;
// 启动转换
SET_CNV();
delay_us(1);
CLR_CNV();
// 等待BUSY下降沿(在中断处理中设置标志)
while(!busy_flag);
busy_flag = 0;
// 读取数据
AD7616_ReadDualChannel(&chA_data, &chB_data);
// 数据处理...
}
在实际测试中,我们发现几个影响性能的关键因素:
时钟分频与采样速率关系:
| SPI分频系数 | 单通道采样时间 | 双通道同步时间 |
|---|---|---|
| SPI_BaudRatePrescaler_2 | 不稳定 | 不稳定 |
| SPI_BaudRatePrescaler_4 | 1.2μs | 1.8μs |
| SPI_BaudRatePrescaler_8 | 2.0μs | 3.0μs |
| SPI_BaudRatePrescaler_16 | 3.5μs | 6.0μs |
提示:当需要更高采样率时,可考虑以下优化方案:
- 使用DMA传输减少CPU开销
- 适当提高APB2总线时钟
- 改用并行接口模式
常见问题排查指南:
寄存器写入失败
同步采样数据错位
采样值不稳定
c复制// 优化的DMA读取示例
void AD7616_InitDMA(void)
{
DMA_InitTypeDef DMA_InitStruct;
// 配置SPI4 RX DMA
DMA_InitStruct.DMA_Channel = DMA_Channel_4;
DMA_InitStruct.DMA_PeripheralBaseAddr = (uint32_t)&SPI4->DR;
DMA_InitStruct.DMA_Memory0BaseAddr = (uint32_t)adc_buffer;
DMA_InitStruct.DMA_DIR = DMA_DIR_PeripheralToMemory;
DMA_InitStruct.DMA_BufferSize = BUF_SIZE;
DMA_InitStruct.DMA_PeripheralInc = DMA_PeripheralInc_Disable;
DMA_InitStruct.DMA_MemoryInc = DMA_MemoryInc_Enable;
DMA_InitStruct.DMA_PeripheralDataSize = DMA_PeripheralDataSize_HalfWord;
DMA_InitStruct.DMA_MemoryDataSize = DMA_MemoryDataSize_HalfWord;
DMA_InitStruct.DMA_Mode = DMA_Mode_Circular;
DMA_InitStruct.DMA_Priority = DMA_Priority_High;
DMA_InitStruct.DMA_FIFOMode = DMA_FIFOMode_Disable;
DMA_Init(DMA2_Stream0, &DMA_InitStruct);
DMA_Cmd(DMA2_Stream0, ENABLE);
SPI_I2S_DMACmd(SPI4, SPI_I2S_DMAReq_Rx, ENABLE);
}
通过本方案实现的双通道同步采集系统,在1MSPS采样率下通道间延迟小于10ns,完全满足大多数工业检测和医疗设备的应用需求。实际项目中可根据具体需求调整过采样率和数字滤波参数,在速度和精度之间取得最佳平衡。