基于STM32驱动AD7606并进行数据显示

基于STM32驱动AD7606并进行数据显示,包含了并行总线(FMC)和SPI两种最常用的接口方式。

AD7606驱动基础

关键特性

  • 核心特性:8通道同步采样、16位分辨率、最高200Ksps采样率、输入范围±5V或±10V。
  • 关键配置:AD7606没有内部寄存器,其量程(由RANGE引脚控制)和过采样(由OS0,OS1,OS2引脚组合控制)均通过外部IO配置。
  • 供电注意:AD7606必须使用单5V供电,但其与STM32的通信接口电平由VIO(或称VDRIVE)引脚决定,此引脚需接STM32的IO口电压(3.3V或5V)。

下表总结了过采样引脚配置:

OS2 OS1 OS0 过采样率 说明
0 0 0 无过采样 最高200Ksps采样率
0 0 1 2倍 硬件内部采集2个样本求平均
0 1 0 4倍 硬件内部采集4个样本求平均
... ... ... ... ...
1 1 0 64倍 硬件内部采集64个样本求平均

过采样与速率的关系:过采样倍率越高,ADC转换时间越长,可得到的最大采样频率就越低。例如,设置1Ksps采样率且64倍过采样,是指AD7606内部以64Ksps采样并求平均,你得到的是平均值。

硬件连接方式

AD7606与STM32的连接主要有并行总线SPI串行两种方式。

  1. 并行总线(推荐用于高速或多通道应用)
    并行接口通常通过STM32的FMC(Flexible Memory Controller)总线实现,优点是读取速度快,适合多通道高速同步采样。

    • 关键引脚连接
      • DB0-DB15:连接至FMC数据总线。
      • CS(片选)、RD(读信号):连接至FMC控制引脚。
      • CONVST A/CONVST B(转换启动):可短接共用STM32一个IO,或分别控制以实现更灵活同步。
      • BUSY(忙信号):连接至STM32一个IO,用于查询转换状态,也可配置为中断。
      • OS0,OS1,OS2,RANGE:连接至STM32普通IO口用于配置。
  2. SPI接口(推荐用于IO引脚紧张的应用)
    SPI接口优点是占用IO少,但读取速度低于并行方式。

    • 关键引脚连接
      • SER引脚(模式选择)需接高电平,使AD7606工作于串口模式。
      • DB7(或标注为DOUTA)作为SPI的MISO,连接STM32 SPI的MISO
      • RD(或标注为SCLK)作为SPI的SCK,连接STM32 SPI的SCK
      • CS连接STM32的SPI片选或普通IO。
      • CONVST A/CONVST BBUSYOS0,OS1,OS2,RANGE连接方式同并行模式。

软件驱动实现

初始化配置

  1. GPIO和总线初始化

    • 并行模式(FMC):需配置STM32的FMC控制器,包括地址、数据总线和控制信号时序。AD7606_CtrlLinesConfig函数(可参考)即进行此类初始化,配置FMC和GPIO时钟,并设置相关引脚为复用功能。
    • SPI模式:初始化STM32的SPI外机(建议使用硬件SPI以获得更高速度),并配置相关GPIO。
  2. AD7606复位和参数设置

    // 复位AD7606 (高脉冲宽度典型值50ns)
    void AD7606_Reset(void)
    {
        RST_1;  // 拉高复位引脚
        HAL_Delay(1); // 短暂延时
        RST_0;  // 拉低复位引脚
        // 也可用多个NOP指令满足50ns最小脉宽
    }
    
    // 设置过采样模式
    void AD7606_SetOversampling(uint8_t os_mode)
    {
        // 根据os_mode设置OS0, OS1, OS2引脚电平
        // 例如,无过采样: OS0=0, OS1=0, OS2=0
        switch(os_mode) {
            case 0: OS0_0; OS1_0; OS2_0; break;
            case 2: OS0_0; OS1_0; OS2_1; break;
            case 4: OS0_0; OS1_1; OS2_0; break;
            // ... 其他过采样模式
            case 64: OS0_1; OS1_1; OS2_0; break;
            default: OS0_0; OS1_0; OS2_0; break;
        }
    }
    
    // 设置输入量程 (0: ±5V, 1: ±10V)
    void AD7606_SetRange(uint8_t range)
    {
        if(range) {
            RAGE_1; // 设置为±10V
        } else {
            RAGE_0; // 设置为±5V
        }
    }
    

    初始化时依次调用:AD7606_Reset -> AD7606_SetOversampling -> AD7606_SetRange

  3. 转换启动与定时采样
    通常使用STM32的定时器产生精确的采样脉冲。

    // 启动一次转换
    void AD7606_StartConv(void)
    {
        CVA_0; // CONVST A拉低
        CVB_0; // CONVST B拉低 (若并联则可统一控制)
        // 延时至少25ns (最小CONVST脉冲宽度)
        CVA_1; // 上升沿启动转换
        CVB_1;
    }
    
    // 配置定时器控制采样频率 (示例使用TIM4)
    void MX_TIM4_Init(uint32_t ulFreq)
    {
        // ... 定时器基础配置
        uint16_t usPrescaler, usPeriod;
        // 根据所需采样频率ulFreq计算预分频和周期
        if (ulFreq <= 100) {
            usPrescaler = 42000-1;
            usPeriod = 2000 / ulFreq;
        } else if(ulFreq <= 200000) {
            usPrescaler = 42-1;
            usPeriod = 2000000 / ulFreq;
        }
        htim4.Init.Prescaler = usPrescaler;
        htim4.Init.Period = usPeriod - 1;
        // ... 调用HAL_TIM_Base_Init等函数完成初始化
    }
    

    在定时器中断中调用AD7606_StartConv()启动转换。

数据读取

  1. 检查转换状态
    在启动转换后,需检测BUSY信号。

    // 查询方式等待转换完成
    while(HAL_GPIO_ReadPin(BUSY_GPIO_Port, BUSY_Pin) == GPIO_PIN_SET); // 等待BUSY变低
    // 或者配置BUSY引脚为下降沿触发外部中断,在中断服务函数中读取数据
    
  2. 读取转换结果

    • 并行模式读取

      // 并行读取多个通道数据 (例如6通道)
      void AD7606_ReadData(void)
      {
          uint8_t i;
          uint16_t usReadValue;
          AD_CS_LOW(); // 片选使能
          for (i = 0; i < CH_NUM; i++) { // CH_NUM为通道数,如6
              // 通过FMC数据总线读取16位数据
              usReadValue = *(__IO uint16_t *)FSMC_AD7606_ADDR; 
              // 存储数据到缓冲区
              if (g_tAD.usWrite < FIFO_SIZE) {
                  g_tAD.usBuf[g_tAD.usWrite] = usReadValue;
                  ++g_tAD.usWrite;
              }
          }
          AD_CS_HIGH(); // 关闭片选
      }
      
    • SPI模式读取

      // 通过SPI读取一个通道的16位数据
      uint16_t AD7606_ReadBytes(void)
      {
          uint8_t high_byte, low_byte;
          uint16_t value;
          // 先读取高8位
          high_byte = SPI_ReadWriteByte(0xFF); 
          // 再读取低8位
          low_byte = SPI_ReadWriteByte(0xFF); 
          value = (high_byte << 8) | low_byte;
          return value;
      }
      
      // 读取所有通道
      void AD7606_ReadAllChannels(uint16_t *dataBuf)
      {
          uint8_t i;
          AD_CS_LOW();
          for(i = 0; i < 8; i++) { // 循环8个通道
              dataBuf[i] = AD7606_ReadBytes();
          }
          AD_CS_HIGH();
      }
      

数据显示与处理

读取到的原始数据是16位有符号整数(补码格式)。

  1. 数据转换与显示

    // 将原始值转换为实际电压值
    float AD7606_ToVoltage(int16_t raw_value, uint8_t range)
    {
        float range_voltage;
        if(range == 0) { 
            range_voltage = 5.0f;   // ±5V量程
        } else {
            range_voltage = 10.0f;  // ±10V量程
        }
        // 16位有符号数范围: -32768 到 +32767
        return (raw_value / 32768.0f) * range_voltage;
    }
    
    // 通过串口打印数据 (以通道1为例)
    void USART1_SendData(float voltage)
    {
        char buffer[50];
        int length = snprintf(buffer, sizeof(buffer), "Ch1 Voltage: %.3f V\r\n", voltage);
        HAL_UART_Transmit(&huart1, (uint8_t*)buffer, length, HAL_MAX_DELAY);
    }
    
  2. 高级应用:FFT分析
    若需要进行频谱分析,可使用STM32的DSP库进行FFT。

    // 准备工作
    #include "arm_math.h"
    #define FFT_SIZE 128 // 采样点数
    float32_t InputBuffer[FFT_SIZE]; // FFT输入数组
    float32_t OutputBuffer[FFT_SIZE]; // FFT输出数组
    arm_rfft_fast_instance_f32 S; // FFT实例结构体
    
    // 初始化FFT
    arm_rfft_fast_init_f32(&S, FFT_SIZE);
    
    // 在主循环或特定函数中
    // 1. 将ADC采样值(如int16_t)转换为浮点数并存入InputBuffer
    // 2. 执行FFT
    arm_rfft_fast_f32(&S, InputBuffer, OutputBuffer, 0);
    // 3. (可选)计算幅值
    // arm_cmplx_mag_f32(OutputBuffer, Magnitude, FFT_SIZE/2);
    

    具体FFT数据存放和处理细节可参考。

参考代码 AD7606高精度采样通过STM32显示代码 www.youwenfan.com/contentcnm/70824.html

常见问题与优化

  • 采样时序问题:确保CONVST脉冲宽度(至少25ns)和读取时序满足数据手册要求。使用FMC或硬件SPI通常能较好地满足时序。
  • 数据抖动:可采用过采样(牺牲速度换取稳定性)或在软件中进行数字滤波(如均值滤波)。
  • 实时波形显示:可配合J-Scope等工具实时显示采集的波形。
  • SPI速度限制:全速采样时(如200Ksps 8通道),SPI需高速时钟。若用软件模拟SPI,可能因IO速度导致数据读取不及时,此时应选用硬件SPI或并行方案。
posted @ 2025-11-25 10:47  chen_yig  阅读(0)  评论(0)    收藏  举报