
兼测3.5mm耳机的cw32电压电流表
简介
一个使用基于CW32f030的地文星立创开发板的电压/电流表,兼具标定、电压电流模拟测试、阻值量测、耳机测试功能
简介:一个使用基于CW32f030的地文星立创开发板的电压/电流表,兼具标定、电压电流模拟测试、阻值量测、耳机测试功能开源协议
:MIT License
描述
概述
要说玩电,还有什么比超电磁炮更搭的设计呢?深度定制的“とある科学の电压电流表(CW32)”logo与御坂美琴帅气的放电pose构成了本作的灵魂面板。同时考虑到经济因素,拼版了多款不同外观(科技以换皮为本嘛)
功能上实现了电压电流测试/测试值标定/分压法测电阻/3.5mm耳机功能测试几大部分。功能设计上主要是如下考量:
1. 电压电流测试和测试值标定是活动的主要方向,不解释
2. 分压法测电阻精度并不高,并且精度是随待测物阻值大小不同而发生变化的,但是贵在设计简易,后续用于扩展外部配件扩展(如光敏二极管探头用于照度、光源flicker、紫外线强度等)。
3. 3.5mm耳机测试包含了耳机open检测、按键功能检测、Standard(美标)/ OMTP 线序检测,原理上比较简单但是我没有见过相似的东西,是我在此案中最想实现的功能。
操作方面key1 标定通道切换,key2 标定,key3模式切换(测试模式切换和标定y值切换复用),参见以下流程图:
外观设计
外壳使用立创eda速学速成,虽然新手上路设计上存在一些瑕疵,但是基本没有翻车。
除正面开孔外,侧面也引出了丰富的接口,dc插口、USB供电接口、5v/3.3v/adc/电阻量测/spi/串口均有引出,甚至还设计了一个3.5mm耳机口用于测试3.5mm耳机!
功能特色
1. 使用cw32 adc转换序列的全部4个通道同时采集和读值;
2.一屏内同时显示adc平均值、瞬时值、标定后的量测值,方便直接调试和确认;
3.使用反色标记量测值接近和超出量程,使用`-0`标记量测值低于标定的下限(由于电路未设计读取负电压,因此如果计算出负值是错误的)
4. 显示帧序列和帧率信息
5. 标定快捷、明了。使用key1 切换模式 (1:普通 2:3v电压量程 3:30v电压量程 4:电流 5:以电压读值的模式显示电流),使用key3切换标定点;标定时按下key2 adc直接设置成功并显示新值;模式、标定x、标定y对应显示在左方、中间、右方,并且使用等号相连,非常直观。
(按下key2后量测值实时应用更新)
6. 阻值量测功能(图示分别为接入电阻/open/short)
6. 3.5mm耳机电气测试(图示分别为耳机未插入/插入/按下线控按键),通过为耳机加载dc电平判断耳机是否插入、音频单元是否断线、耳机按键按下的状态、耳机是否包含mic、耳机线序标准
电路设计
示例教程相同的部分不再赘述,主要做了如下调整:
1. 使用I2C OLED屏幕,丰富内容显示和调试,同时节约了大量io,从而有机会引出其他功能pin
2. 除电压量测、电流量测、参考电压量测外,增加了不经过分压adc直接读值、串联电阻分压法测电阻(实际我焊接的电阻使用了100k/510ohm,与原理图有差异,注意需修改代码中的阻值常量)
由于电阻量测必须对器件进行供电,考虑到功耗问题不能使用太高的供电电压, 因此在不增加放大电路的前提下, 无法像电压量测电路一样同时使用两路ADC进行处理;最简易的办法就是使用开关切换串联分压电阻,人工读取当前分压电阻对应的阻值读数. 当然如果进一步完善,可以使用模拟开关芯片控制或者使用gpio比较之类的方法感知当前选择的分压电阻,但是当前方案也不是不能接收,毕竟示波器的10x探头不也是人工设置的嘛?分压法测电阻本质是为未来做光敏二极管探头做预留.
经过后期测试验证,发现直接测电阻存在一定波动,需要修改电路为adc增加滤波电容。
3. 设计了3.5mm耳机测试电路,可以用于测试耳机断线、4段式耳机制式、线控按钮功能。原理图使用了直接标注线路网络的方式,省略了4个adc的网络输出标签
测试原理参考Android 3.5毫米耳机:配件规范
此功能在电路设计阶段仅粗估了可行性,没有进行详细的功能设计,依赖算法控制gpio输出高低电平进行测试和验证。四路gpio均串接2.2k电阻分压,使用对称的电路方便比较和计算。这样的做法提高了设计效率,保留了验证和调整空间。
设计时依最坏情况分析:
a. 对gpio电流预估,3.3v接入一个有功能发声的耳机,每个端子串联2.2k电阻,输出电流小于1.5ma是安全的。
b. 对音频单元功耗预估,当音频单元阻值高于1k时,测试回路功耗u^2/r<3.3*3.3/(2.2k+1k)=3.4mW ;当音频单元阻值低于1k时,测试回路功耗I^2*R<1.5/1000*1.5/1000*1000=0.00225mW, 均低于音频单元的常规功耗,因此对耳机来说也是安全的。
经过实物验证,使用了t、r1输出高电平,r2、s输出低电平,使用adc一次性读取每个2.2k电阻的电压,直接比较adc读数判定耳机的方案。
测试原理简化如下:
由于供电电压并不稳定,输出电压本身有波动;adc也缺少滤波电容,采集到的数据有较大波动并不漂亮,后续可以对电路做如下调整(但是目前实测能稳定快速的判断,因此也可以完全不改动):
- IO_T/IO_R1改为接一路单独的ldo,IO_R2、IO_S改为直接接地
- Adc引脚增加滤波电容
4. 通过二极管链接USB,避免同时插入dc插头和USB时对USB倒灌电流损坏设备。
程序设计
1. 经过调试验证发现OLED屏幕刷新速度较慢(使用了软I2C每次均刷新整个屏幕,帧率为10fps),并且这样的刷新速度实测人眼可正常阅读。因此程序设计为主函数全速刷新显示内容,每次循环获取一次adc信息并完整绘制整个屏幕。
2. 使用定时器每1ms获取一次adc数据(4个通道)同时从数字通道读取按键状态。使用if条件和模式变量,判断是否需要切换工作的adc(cw32转换序列最多4个通道,此项目使用了8个通道,因此必须切换通道)、调节gpio输出、保存校准参数
3. 使用多段函数标定,包含0和1.由于没有设计量测负电压的功能,当ADC读数低于0时,显示-0。
// 标定的y的值
u8 *adj_names[][4] = {
{ (uint8_t*)"=0mV",
(uint8_t*)"=500mV",
(uint8_t*)"=1.0V",
(uint8_t*)"=2.5V"
},
{ (uint8_t*)"=0V",
(uint8_t*)"=1V",
(uint8_t*)"=10V",
(uint8_t*)"=20V"
},
{ (uint8_t*)"=0mA",
(uint8_t*)"=500mA",
(uint8_t*)"=1.5A",
(uint8_t*)"=3A"
},
{ (uint8_t*)"=0mV",
(uint8_t*)"=50mV",
(uint8_t*)"=150mV",
(uint8_t*)"=300mV"
},
};
使用(x1, y1) (x2, y2) 两个座标点拟合直线,利用标定值转换adc读数为国际单位计量值
float calib_value(uint16_t adc, uint16_t next_cali_index, float y1, float y2 ) {
return (y2 - y1) * (adc - cali[next_cali_index - 1]) / (cali[next_cali_index] - cali[next_cali_index - 1]) + y1;
}
4. 测试值根据数值大小自动转换为mKM单位,并根据测试精度保留有效位数。为避免测试值超量程,接近上限时使用反色显示测试结果。
5. 标定。改为13个数据,读取标定时直接读取到全局变量数组;标定保存函数改为保存后重新从flash读取标定值,确保保存的有效性。
// 读取标定结果
void read_vol_cur_calibration(void)
{
flash_read(0, cali, 13);
if(cali[0] != 0x88) //还没校准过时,计算理论值,并存储
{
cali[1] = 0;
cali[2] = 4096 * 0.5 / 3;
cali[3] = 4096 / 3;
cali[4] = 4096 * 2.5 / 3;
cali[5] = 0;
cali[6] = 4096 / 1.5 / 23;
cali[7] = 4096 * 10 / 1.5 / 23;
cali[8] = 4096 * 20 / 1.5 / 23;
cali[9] = 0;
cali[10] = 4096 * 50 / 1500;
cali[11] = 4096 * 150 / 1500;
cali[12] = 4096 * 300 / 1500;
}
}
// 保存标定结果
void save_calibration(void)
{
cali[0] = 0x88;
flash_erase();
flash_write(0, cali, 13);
read_vol_cur_calibration();
}
设计图

BOM


评论