STM32F407驱动AD7606采样:用HAL库的TIM生成PWM,SPI中断读取数据保姆级教程

张开发
2026/4/19 13:01:33 15 分钟阅读
STM32F407驱动AD7606采样:用HAL库的TIM生成PWM,SPI中断读取数据保姆级教程
STM32F407驱动AD7606全流程实战从PWM配置到SPI数据解析在工业测量和电力监控领域AD7606作为一款16位8通道同步采样ADC芯片凭借±10V宽输入范围和200kSPS采样率成为许多嵌入式开发者的首选。但对于刚接触STM32和AD7606配合使用的工程师来说从硬件连接到软件配置的全流程实现往往充满挑战。本文将用HAL库演示如何通过TIM生成精确PWM信号驱动AD7606转换并利用SPI中断高效读取数据。1. 硬件架构设计与关键参数解析AD7606的SPI接口模式相比并行模式能节省大量IO资源特别适合STM32F407这类引脚资源有限的控制器。典型连接方案中需要重点关注五个核心信号线CONVST由TIM3_CH1驱动启动转换的PWM信号频率决定采样率BUSY连接PA5转换状态指示下降沿触发中断SCLK/MISOSPI2接口时钟速率影响数据读取速度CSPA2SPI片选必须在BUSY中断内精确控制RSTPA1硬件复位确保初始状态可靠关键参数验证当TIM3时钟源为42MHz时分频值42配合100的ARR值可产生10kHz PWM100μs周期。98%占空比意味着低电平持续2μs完全满足AD7606要求的最小25ns CONVST低脉冲宽度。芯片基准电压选择直接影响量程计算基准源配置输入范围LSB值内部2.5V±5V152μV外部5V±10V305μV2. CubeMX工程配置详解2.1 时钟树与定时器配置在Clock Configuration标签页确保HCLK设置为168MHzAPB1 Timer Clocks保持42MHzAPB2 Peripheral Clocks保持84MHzTIM3参数配置要点/* PWM Generation Parameters */ htim3.Instance TIM3; htim3.Init.Prescaler 42-1; // 42MHz/42 1MHz htim3.Init.CounterMode TIM_COUNTERMODE_UP; htim3.Init.Period 100-1; // 1MHz/100 10kHz htim3.Init.ClockDivision TIM_CLOCKDIVISION_DIV1; sConfig.OCMode TIM_OCMODE_PWM1; sConfig.Pulse 98; // 98%占空比 sConfig.OCPolarity TIM_OCPOLARITY_HIGH;2.2 SPI接口特殊设置AD7606的SPI模式必须满足hspi2.Init.CLKPolarity SPI_POLARITY_HIGH; // CPOL1 hspi2.Init.CLKPhase SPI_PHASE_1EDGE; // CPHA0 hspi2.Init.DataSize SPI_DATASIZE_16BIT; // 16位传输 hspi2.Init.BaudRatePrescaler SPI_BAUDRATEPRESCALER_4; // 10.5MHz常见陷阱若将CPHA误设为2EDGE会导致读取的数据始终为0xFFFF。这是AD7606数据手册中明确指出的时序要求。3. 驱动层代码实现技巧3.1 精确的复位序列硬件复位必须满足最小50ns低脉冲要求void AD7606_Reset(void) { HAL_GPIO_WritePin(AD7606_RST_GPIO_Port, AD7606_RST_Pin, GPIO_PIN_RESET); __NOP(); __NOP(); __NOP__(); // 约17ns 168MHz HAL_GPIO_WritePin(AD7606_RST_GPIO_Port, AD7606_RST_Pin, GPIO_PIN_SET); HAL_Delay(1); // 确保稳定 }3.2 中断驱动的数据采集BUSY下降沿触发的中断服务流程立即拉低CS引脚通过SPI读取16位数据恢复CS为高电平存储数据到缓冲区void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin) { if(GPIO_Pin AD7606_BUSY_Pin) { uint16_t rawData[8]; HAL_GPIO_WritePin(AD7606_CS_GPIO_Port, AD7606_CS_Pin, GPIO_PIN_RESET); HAL_SPI_Receive(hspi2, (uint8_t*)rawData, 8, HAL_MAX_DELAY); HAL_GPIO_WritePin(AD7606_CS_GPIO_Port, AD7606_CS_Pin, GPIO_PIN_SET); for(int ch0; ch8; ch) { adcValues[ch] AD7606_ConvertToVoltage(rawData[ch]); } } }4. 数据后处理与验证4.1 二进制补码转电压值AD7606输出的是16位二进制补码转换算法需考虑符号位float AD7606_ConvertToVoltage(uint16_t raw) { int16_t signedValue (raw 0x8000) ? -(int16_t)((~raw 1) 0x7FFF) : (int16_t)raw; return (signedValue * referenceVoltage) / 32768.0f; }4.2 采样结果验证方法通过USB转串口输出采样值void PrintADCResults(void) { printf(CH1:%.3fV\tCH2:%.3fV\tCH3:%.3fV\tCH4:%.3fV\r\n, adcValues[0], adcValues[1], adcValues[2], adcValues[3]); printf(CH5:%.3fV\tCH6:%.3fV\tCH7:%.3fV\tCH8:%.3fV\r\n, adcValues[4], adcValues[5], adcValues[6], adcValues[7]); }实际调试中发现当输入接地时采样值应在±1LSB范围内波动。若出现持续偏移需检查模拟地是否与数字地单点连接参考电压引脚是否添加足够去耦电容输入阻抗匹配是否合理

更多文章