原电路板由于功能比较多,测试可能会存在干扰项。
为排除其他干扰项,我单独做了一块ADC验证板来排查问题。
测试板只保留了USB和硬件串口和ADC功能,尽量使用简单而短的布线;
板子的工程文件在附件,使用立创EDA专业版绘制。
PCB:
原理图:
实际电路板上,Ω电阻不是全部焊接,用作跳线功能:
单片机VCC使用线性稳压器的3.3V供电;
单片机的ADC参考电压直连单片机VCC,没有使用431电路进行稳压;
单片机的Ucap使用线性稳压的3.3V供电;
电源的电容全部焊接;
电池和USB电源焊接二极管选择供电,实际使用电池供电;
单片机测试程序是从原工程的基础上简化来的,主要功能是进行USB转串口,
源代码没有作整理,只展示部分相关的功能代码;
单片机主频设置为24MHz,使用USB的内部48MHz时钟进行分频;
ADC时钟设置为4分频,
ADCTIM设置:采样时间31,通道保持时间3,通道选择时间0;
ADC每次采样都关闭全局中断 EA,采样结束后再打开 EA;
测试软件运行逻辑:
每100ms读取一次6个通道的ADC值,读取16次后进行最大最小值以及平均值的统计输出;
数据同时向USB转串口以及硬件串口进行发送;
输出格式为文本:
xxx_ADC = ADC值,MAX = ADC值,MIN = ADC值,Jump = ADC值\r\n
xxx_ADC 是通道采样的平均值,MAX 是16次采样的最大值,MIN 是16次采样的最小值,Jump 是16次采样的最大值减最小值;
读取ADC值的函数:
- void read_adc_val(void)
- {
- u8 i;
- u16 adc_tmp[6];
-
- if(adc_r_cnt < 16){
- // 读ADC结果
- adc_tmp[0] = ADC_get(VIN1_CHN);
- adc_tmp[1] = ADC_get(VIN2_CHN);
- adc_tmp[2] = ADC_get(VIN3_CHN);
- adc_tmp[3] = ADC_get(VIN4_CHN);
- adc_tmp[4] = ADC_get(VREF_CHN);
- adc_tmp[5] = ADC_get(VCC_CHN);
-
- // 储存最值
- for(i = 0;i < 6;i++){
- adc_read[i] += adc_tmp[i];
-
- if(adc_tmp[i] > adc_res_max[i]){
- adc_res_max[i] = adc_tmp[i];
- }
- if(adc_tmp[i] < adc_res_min[i]){
- adc_res_min[i] = adc_tmp[i];
- }
- }
-
- adc_r_cnt++;
- }
- else{
- show_adc_flag = true;
- }
- }
复制代码
发送ADC数据函数:
- // 发送ADC结果
- void show_adc_res(void)
- {
- u16 u_tmp;
- xdata char c_buf[20];
- // 数据采集完成
- if(show_adc_flag == true){
- // 发送字符串
- put_up_string(uart_adc_name[show_adc_idx]);
- // 发送平均值
- print_NUM_to_string(c_buf,(adc_read[show_adc_idx]/16),4,0,false);
- put_up_string(c_buf);
-
- put_up_string(",MAX = ");
- // 发送最大值
- print_NUM_to_string(c_buf,adc_res_max[show_adc_idx],4,0,false);
- put_up_string(c_buf);
-
- put_up_string(",MIN = ");
- // 发送最小值
- print_NUM_to_string(c_buf,adc_res_min[show_adc_idx],4,0,false);
- put_up_string(c_buf);
-
- put_up_string(",Jump = ");
- // 发送跳动值
- u_tmp = (adc_res_max[show_adc_idx] - adc_res_min[show_adc_idx]);
- print_NUM_to_string(c_buf,u_tmp,4,0,false);
- put_up_string(c_buf);
-
- put_up_string("\r\n");
- // 复位计数器
- adc_r_cnt = 0;
- adc_read[show_adc_idx] = 0;
- adc_res_max[show_adc_idx] = 0;
- adc_res_min[show_adc_idx] = 4096;
- // 发送循环
- show_adc_idx ++;
- if(show_adc_idx > 5){
- show_adc_idx = 0;
- show_adc_flag = false;
- }
- // 发送数据
- Check_UART_Busy_Send();
- }
-
- }
复制代码
ADC通道的 VIN4_ADC 连接电池使用可调电阻分压;
ADC通道的 VREF_ADC 连接单片机 ADC_REF 引脚进行对半分压;
ADC通道的 VCC_ADC 连接单片机 VCC 引脚进行对半分压;
其余ADC通道使用分压电阻连接,分压电阻输入悬空(约等于10KΩ电阻下拉);
在打开USB转串口功能时,单片机读取的ADC结果(取其一):
VIN1_ADC = 0001,MAX = 0006,MIN = 0000,Jump = 0006
VIN2_ADC = 0000,MAX = 0005,MIN = 0000,Jump = 0005
VIN3_ADC = 0000,MAX = 0005,MIN = 0000,Jump = 0005
VIN4_ADC = 3147,MAX = 3148,MIN = 3143,Jump = 0005
VREF_ADC = 2044,MAX = 2047,MIN = 2040,Jump = 0007
VCC_ADC = 2045,MAX = 2051,MIN = 2043,Jump = 0008
关闭USB转串口功能时,单片机读取的ADC结果(取其一):
VIN1_ADC = 0000,MAX = 0001,MIN = 0000,Jump = 0001
VIN2_ADC = 0000,MAX = 0000,MIN = 0000,Jump = 0000
VIN3_ADC = 0000,MAX = 0000,MIN = 0000,Jump = 0000
VIN4_ADC = 3147,MAX = 3148,MIN = 3147,Jump = 0001
VREF_ADC = 2044,MAX = 2045,MIN = 2044,Jump = 0001
VCC_ADC = 2044,MAX = 2045,MIN = 2044,Jump = 0001
经过多次测试基本是相同的结果。
测试视频已上传到附件。
使用此ADC测试板测得的问题现象与原工程上出现的现象基本一致,
都是在打开USB功能时出现ADC跳动值变大的现象,关闭USB功能后ADC值正常。
如果需要此测试电路板的可以联系寄出,
如果需要继续测试哪些内容的请继续提出。
|