• 正文
  • 相关推荐
申请入驻 产业图谱

AD5933阻抗测量芯片(5):如何用AD5933做个简易频谱仪

10小时前
169
加入交流群
扫码加入
获取工程师必备礼包
参与热点资讯讨论

在去年更新AD5933这个系列的时候,进行了电容电阻的一系列测量,本期我们在前面的基础上给这块板子配一块OLED显示屏,将其包装为阻抗测量仪。

硬件采用之前的AD5933装置,软件使用U8g2作为GUI库实现OLED屏幕绘制。

1、AD5933芯片使用回顾

AD5933使用I2C协议进行通讯,其通讯地址为7位0x0D是I2C总线地址。

AD5933内部框架图如图所示,主要由三部分组成:待测阻抗Z和反馈电阻RFB构成的反相放大器网络、DDS激励信号源部分以及采样加离散傅里叶变换组成的分析部分。

离散傅里叶变化的输出结果包含实部R和虚部I两个部分,可以根据这两个部分来获得阻抗的相位信息。

通过平方和计算得到模值Mag,这里的模值并不代表真实阻抗。

严格来说这个模值和导纳有关,倒数和一个系数相乘得到真实的阻抗值,系数可以通过两点校订来得到。

同时需要注意的是,相同的阻抗的比例系数在不同频率下可能会变化,这点是由AD5933的内部系统决定的。

AD5933的扫描流程如上图所示,首先,将频率扫描参数(起始频率、增量次数、频率增量)写入对应的寄存器;然后将 AD5933 置于待机模式,也可通过向控制寄存器发送复位命令使设备进入待机模式;接着向控制寄存器发送起始频率命令进行初始化;等待足够的稳定时间后,向控制寄存器发送启动频率扫描命令;之后轮询状态寄存器,检查 DFT 转换是否完成,若未完成则持续轮询,若完成则读取实部和虚部数据寄存器的值;读取完成后,再次轮询状态寄存器,检查频率扫描是否完成,若未完成则向控制寄存器发送增量频率或重复频率命令,继续扫描流程;

2、交互代码

初始化阶段包括:初始化微秒级定时器htim1,初始化数字电位器MCP4017,复位AD5933,设置AD5933幅度,设置AD5933增益,设置AD5933采样建立时间,设置AD5933频率、起始频率、步进点位。

     float sweep_ohm[32];     float log_ratio = 1.0f;     float max_impedance = 0.0f;     uint8_t max_index = 0;     if (kSweepPoints > 1)     {       log_ratio = powf(kSweepEndHz / kSweepStartHz, 1.0f / (kSweepPoints - 1));     }     for (uint8_t i = 0; i < kSweepPoints; i++)     {       float current_freq = kSweepStartHz * powf(log_ratio, i);       AD5933SetDDS(current_freq);       AD5933GetALL(Repeat);       sweep_ohm[i] = ad5933data.R;       ad5933data.SweepData[i].Frequency = current_freq;       ad5933data.SweepData[i].Real = ad5933data.Real;       ad5933data.SweepData[i].Imag = ad5933data.Imag;       ad5933data.SweepData[i].R = ad5933data.R;       if (ad5933data.R > max_impedance)       {         max_impedance = ad5933data.R;         max_index = i;       }     }
     ad5933data.SweepPointCount = kSweepPoints;     ad5933data.MaxImpedanceIndex = max_index;     ad5933data.Frequent = ad5933data.SweepData[max_index].Frequency;     ad5933data.Real = ad5933data.SweepData[max_index].Real;     ad5933data.Imag = ad5933data.SweepData[max_index].Imag;     ad5933data.R = ad5933data.SweepData[max_index].R;     UpdateSweepGraph(sweep_ohm, kSweepPoints, kSweepStartHz, kSweepEndHz);     u8g2_FirstPage(&u8g2);       do       {         MainGUI(&u8g2);       } while (u8g2_NextPage(&u8g2));

循环函数中,设置频率按指数倍增,初始频率500HZ截止频率100KHZ,总计32个频点,将每个频点数据记录下来并记录阻抗最高点。

voidMainGUI(u8g2_t *u8g2){  char line[32];  constuint8_t graph_x = 18;  constuint8_t graph_y = 20;  constuint8_t graph_w = 108;  constuint8_t graph_h = 34;  float min_value = 0.0f;  float max_value = 1.0f;  float start_freq = sweep_graph_start_freq;  float end_freq = sweep_graph_end_freq;  u8g2_SetFont(u8g2, u8g2_font_5x7_tf);  snprintf(line, sizeof(line), "F:%.0f", ad5933data.Frequent);  u8g2_DrawStr(u8g2, 0, 7, line);  snprintf(line, sizeof(line), "Ohm:%.1f", ad5933data.R);  u8g2_DrawStr(u8g2, 64, 7, line);  snprintf(line, sizeof(line), "R:%.1f", ad5933data.Real);  u8g2_DrawStr(u8g2, 0, 14, line);  snprintf(line, sizeof(line), "I:%.1f", ad5933data.Imag);  u8g2_DrawStr(u8g2, 64, 14, line);  u8g2_DrawFrame(u8g2, graph_x, graph_y, graph_w, graph_h);  if (sweep_graph_count >= 2)  {    min_value = sweep_graph_points[0];    max_value = sweep_graph_points[0];    for (uint8_t i = 1; i < sweep_graph_count; i++)    {      if (sweep_graph_points[i] < min_value)      {        min_value = sweep_graph_points[i];      }      if (sweep_graph_points[i] > max_value)      {        max_value = sweep_graph_points[i];      }    }    if (max_value <= min_value)    {      max_value = min_value + 1.0f;    }    for (uint8_t i = 1; i < sweep_graph_count; i++)    {      uint8_t x0 = (uint8_t)(graph_x + 2 + ((uint16_t)(graph_w - 5) * (i - 1)) / (sweep_graph_count - 1));      uint8_t x1 = (uint8_t)(graph_x + 2 + ((uint16_t)(graph_w - 5) * i) / (sweep_graph_count - 1));      uint8_t y0 = (uint8_t)(graph_y + graph_h - 3 - (uint8_t)(((sweep_graph_points[i - 1] - min_value) * (graph_h - 6)) / (max_value - min_value)));      uint8_t y1 = (uint8_t)(graph_y + graph_h - 3 - (uint8_t)(((sweep_graph_points[i] - min_value) * (graph_h - 6)) / (max_value - min_value)));      u8g2_DrawLine(u8g2, x0, y0, x1, y1);    }  }  snprintf(line, sizeof(line), "%.0f", max_value);  u8g2_DrawStr(u8g2, 0, graph_y + 5, line);  snprintf(line, sizeof(line), "%.0f", min_value);  u8g2_DrawStr(u8g2, 0, graph_y + graph_h - 1, line);  if (end_freq >= 1000.0f)  {    snprintf(line, sizeof(line), "%.0fk", start_freq / 1000.0f);  }  else  {    snprintf(line, sizeof(line), "%.0f", start_freq);  }  u8g2_DrawStr(u8g2, graph_x, 63, line);  if (end_freq >= 1000.0f)  {    snprintf(line, sizeof(line), "%.0fk", end_freq / 1000.0f);  }  else  {    snprintf(line, sizeof(line), "%.0f", end_freq);  }  u8g2_DrawStr(u8g2, 104, 63, line);

显示界面将页面分为两个部分,上部分四个参数为阻抗最高点的频率、实部、虚部、计算后阻抗。

下部分为32个指数倍增频率点构成的扫频网络显示。

3、器件测试

相关推荐