#申请原创#
在之前的测评计划中是准备做一个8路电压表+1路电流表的实验,实验的电路图如下:
下面是整个实验的装置照片:
其中显示器左边是一个可调电源。鼠标边上的盒子是一个用于测量电流的负载,其实就是对盒子里的锂电池进行充电。右边则是ADC采样电阻和AVR64DD32核心板。
MCC的配置如下:
开通了10个通道,目前仅测试了8路电压转换和1路电流转换,预留的一个通道是准备日后监测锂电池电压的:
各个通道的编号在列表中可以查到:
比较参照电压选择2.048v:
电压采样电阻的比例是0.2/4.7,电流采样电阻是5毫欧。采样滤波是连续采样8次,然后取平均值并与之前的数据各占50%。代码如下:
ADC_Val = 0; //读取电压通道1
for(i=0; i<8; i++){
ADC_Val += ADC0_GetConversion(ADC_MUXPOS_AIN18_gc);
DELAY_milliseconds(1);
}
value[1] = value[1]/2 + ADC_Val>>6; //当前转换值(8次相加)除以8(右移3位)再取50%(右移1位)与之前数值的50%相加,得到享受滤波值
// value[1] = ADC_Val>>6;
LCD_write_GT_value(14,2,3,1,0,1,value[1]);//x,y,L,D,N,val :座标、长度、前导零(1显示 0不显示)、字体(0大字体 1中字体)、变量
开始测试时数据波动很大,而且后续通道的读数会受到之前通道数据的影响,最后在每次采样后延时1毫秒,这样读数才比较稳定。
经过反复修改,实际数值为右移6位时,电压数值与实际比较接近,当可调电源的电压输出为1.4v时,采样转换的数值为1.5v:
两者相差0.1v,这点误差应该可以忽略不计,因为可调电源的电压表也不是很准确,而我又没有高位电压表来校准,在实际使用过程中也没有那么高的需求。
经过测试,8路电压表除了第一通道有初始值0.1外,其他通道均基本正常,只是电流检测不正常,无论是否接负载,检测结果没有变化。按照电路设计,采样电阻为5毫欧时,如果有1安电流通过,采样电阻两端将产生5毫伏电压,而MCU的ADC分辨率应为2.048v/4096=0.5毫伏,应该可以检测到0.1安的电流变化,我采用的锂电池充电负载电流约为0.2~0.5安,理论上完全可以检测得到变化,但实际测试过程中却毫无变化,下一步准备降低参照电压再试试看。
下面是主函数代码:
int main(void)
{
uint8_t i=0,j=0;
uint32_t ADC_Val;
SYSTEM_Initialize();
// USART0_Enable();
printf("Hello World\r\n");
SW0_SetDigitalInput();
SW0_SetPullUp();
SW0_EnableInterruptForFallingEdge(); //设置引脚的中断模式
PF6_SetInterruptHandler(SW0_Handler); //指定中断处理的函数
LCD_init(); //LCD初始化
display_begin();
DELAY_milliseconds(2000);
display_main();
TCA0_EnableInterrupt();
Led0_SetHigh();
while(1)
{
ADC_Val = 0; //读取电流值
for(i=0; i<8; i++){
ADC_Val += ADC0_GetConversion(ADC_MUXPOS_AIN17_gc);
DELAY_milliseconds(1);
}
// value[0] = value[0]/2 + ADC_Val>>1 - 600; //当前转换值(8次相加)除以8(右移3位)再取50%(右移1位)与之前数值的50%相加,得到享受滤波值
value[0] = ADC_Val>>3;
LCD_write_GT_value(106,6,5,3,0,1,value[0]);//x,y,L,D,N,val :座标、长度、小数、前导零(1显示 0不显示)、字体(0大字体 1中字体)、变量
ADC_Val = 0; //读取电压通道1
for(i=0; i<8; i++){
ADC_Val += ADC0_GetConversion(ADC_MUXPOS_AIN18_gc);
DELAY_milliseconds(1);
}
value[1] = value[1]/2 + ADC_Val>>6; //当前转换值(8次相加)除以8(右移3位)再取50%(右移1位)与之前数值的50%相加,得到享受滤波值
// value[1] = ADC_Val>>6;
LCD_write_GT_value(14,2,3,1,0,1,value[1]);//x,y,L,D,N,val :座标、长度、前导零(1显示 0不显示)、字体(0大字体 1中字体)、变量
ADC_Val = 0; //读取电压通道2
for(i=0; i<8; i++){
ADC_Val += ADC0_GetConversion(ADC_MUXPOS_AIN7_gc);
DELAY_milliseconds(1);
}
value[2] = value[2]/2 + ADC_Val>>6; //当前转换值(8次相加)除以8(右移3位)再取50%(右移1位)与之前数值的50%相加,得到享受滤波值
// value[2] = ADC_Val>>6;
LCD_write_GT_value(64,2,3,1,0,1,value[2]);//x,y,L,D,N,val :座标、长度、前导零(1显示 0不显示)、字体(0大字体 1中字体)、变量
ADC_Val = 0; //读取电压通道3
for(i=0; i<8; i++){
ADC_Val += ADC0_GetConversion(ADC_MUXPOS_AIN27_gc);
DELAY_milliseconds(1);
}
value[3] = value[3]/2 + ADC_Val>>6; //当前转换值(8次相加)除以8(右移3位)再取50%(右移1位)与之前数值的50%相加,得到享受滤波值
// value[3] = ADC_Val>>6;
LCD_write_GT_value(114,2,3,1,0,1,value[3]);//x,y,L,D,N,val :座标、长度、前导零(1显示 0不显示)、字体(0大字体 1中字体)、变量
ADC_Val = 0; //读取电压通道4
for(i=0; i<8; i++){
ADC_Val += ADC0_GetConversion(ADC_MUXPOS_AIN1_gc);
DELAY_milliseconds(1);
}
value[4] = value[4]/2 + ADC_Val>>6; //当前转换值(8次相加)除以8(右移3位)再取50%(右移1位)与之前数值的50%相加,得到享受滤波值
// value[4] = ADC_Val>>6;
LCD_write_GT_value(164,2,3,1,0,1,value[4]);//x,y,L,D,N,val :座标、长度、前导零(1显示 0不显示)、字体(0大字体 1中字体)、变量
ADC_Val = 0; //读取电压通道5
for(i=0; i<8; i++){
ADC_Val += ADC0_GetConversion(ADC_MUXPOS_AIN6_gc);
DELAY_milliseconds(1);
}
value[5] = value[5]/2 + ADC_Val>>6; //当前转换值(8次相加)除以8(右移3位)再取50%(右移1位)与之前数值的50%相加,得到享受滤波值
// value[5] = ADC_Val>>6;
LCD_write_GT_value(14,4,3,1,0,1,value[5]);//x,y,L,D,N,val :座标、长度、前导零(1显示 0不显示)、字体(0大字体 1中字体)、变量
ADC_Val = 0; //读取电压通道6
for(i=0; i<8; i++){
ADC_Val += ADC0_GetConversion(ADC_MUXPOS_AIN19_gc);
DELAY_milliseconds(1);
}
value[6] = value[6]/2 + ADC_Val>>6; //当前转换值(8次相加)除以8(右移3位)再取50%(右移1位)与之前数值的50%相加,得到享受滤波值
// value[6] = ADC_Val>>6;
LCD_write_GT_value(64,4,3,1,0,1,value[6]);//x,y,L,D,N,val :座标、长度、前导零(1显示 0不显示)、字体(0大字体 1中字体)、变量
ADC_Val = 0; //读取电压通道7
for(i=0; i<8; i++){
ADC_Val += ADC0_GetConversion(ADC_MUXPOS_AIN2_gc);
DELAY_milliseconds(1);
}
value[7] = value[7]/2 + ADC_Val>>6; //当前转换值(8次相加)除以8(右移3位)再取50%(右移1位)与之前数值的50%相加,得到享受滤波值
// value[7] = ADC_Val>>6;
LCD_write_GT_value(114,4,3,1,0,1,value[7]);//x,y,L,D,N,val :座标、长度、前导零(1显示 0不显示)、字体(0大字体 1中字体)、变量
ADC_Val = 0; //读取电压通道8
for(i=0; i<8; i++){
ADC_Val += ADC0_GetConversion(ADC_MUXPOS_AIN3_gc);
DELAY_milliseconds(1);
}
value[8] = value[8]/2 + ADC_Val>>6; //当前转换值(8次相加)除以8(右移3位)再取50%(右移1位)与之前数值的50%相加,得到享受滤波值
// value[8] = ADC_Val>>6;
LCD_write_GT_value(164,4,3,1,0,1,value[8]);//x,y,L,D,N,val :座标、长度、前导零(1显示 0不显示)、字体(0大字体 1中字体)、变量
printf("电流值=%d\r\n",value[0]);
printf("电压通道1=%d\r\n",value[1]);
printf("电压通道2=%d\r\n",value[2]);
printf("电压通道3=%d\r\n",value[3]);
printf("电压通道4=%d\r\n",value[4]);
printf("电压通道5=%d\r\n",value[5]);
printf("电压通道6=%d\r\n",value[6]);
printf("电压通道7=%d\r\n",value[7]);
printf("电压通道8=%d\r\n\r\n",value[8]);
if(ms>wait){
ms = 0;
Led0_Toggle();
}
}
}
这是通过串口收到的数据截图:
|
此文章已获得独家原创/原创奖标签,著作权归21ic所有,未经允许禁止转载。
共1人点赞
|