在去年更新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个指数倍增频率点构成的扫频网络显示。
169