[PIC®/AVR®/dsPIC®产品] 【CuriosityNano测评报告】+ AVR64DD32ADC多路电压表实验

[复制链接]
1248|6
 楼主| hu9jj 发表于 2022-11-24 13:21 | 显示全部楼层 |阅读模式
AD, ADC, AN, AVR, IO
#申请原创#

    在之前的测评计划中是准备做一个8路电压表+1路电流表的实验,实验的电路图如下:


    下面是整个实验的装置照片:


    其中显示器左边是一个可调电源。鼠标边上的盒子是一个用于测量电流的负载,其实就是对盒子里的锂电池进行充电。右边则是ADC采样电阻和AVR64DD32核心板。
    MCC的配置如下:
    开通了10个通道,目前仅测试了8路电压转换和1路电流转换,预留的一个通道是准备日后监测锂电池电压的:


    各个通道的编号在列表中可以查到:


    比较参照电压选择2.048v:


    电压采样电阻的比例是0.2/4.7,电流采样电阻是5毫欧。采样滤波是连续采样8次,然后取平均值并与之前的数据各占50%。代码如下:
  1.         ADC_Val = 0;                            //读取电压通道1
  2.         for(i=0; i<8; i++){
  3.             ADC_Val += ADC0_GetConversion(ADC_MUXPOS_AIN18_gc);
  4.             DELAY_milliseconds(1);
  5.         }
  6.         value[1] = value[1]/2 + ADC_Val>>6;     //当前转换值(8次相加)除以8(右移3位)再取50%(右移1位)与之前数值的50%相加,得到享受滤波值
  7. //        value[1] = ADC_Val>>6;
  8.         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安,理论上完全可以检测得到变化,但实际测试过程中却毫无变化,下一步准备降低参照电压再试试看。
    下面是主函数代码:
  1. int main(void)
  2. {
  3.     uint8_t i=0,j=0;
  4.     uint32_t ADC_Val;
  5.     SYSTEM_Initialize();
  6. //    USART0_Enable();
  7.     printf("Hello World\r\n");

  8.     SW0_SetDigitalInput();
  9.     SW0_SetPullUp();
  10.     SW0_EnableInterruptForFallingEdge();         //设置引脚的中断模式
  11.     PF6_SetInterruptHandler(SW0_Handler);        //指定中断处理的函数

  12.     LCD_init();                                  //LCD初始化
  13.     display_begin();
  14.     DELAY_milliseconds(2000);
  15.    
  16.     display_main();
  17.    
  18.     TCA0_EnableInterrupt();
  19.     Led0_SetHigh();
  20.    
  21.     while(1)
  22.     {
  23.         ADC_Val = 0;                            //读取电流值
  24.         for(i=0; i<8; i++){
  25.             ADC_Val += ADC0_GetConversion(ADC_MUXPOS_AIN17_gc);
  26.             DELAY_milliseconds(1);
  27.         }
  28. //        value[0] = value[0]/2 + ADC_Val>>1 - 600;  //当前转换值(8次相加)除以8(右移3位)再取50%(右移1位)与之前数值的50%相加,得到享受滤波值
  29.         value[0] = ADC_Val>>3;
  30.         LCD_write_GT_value(106,6,5,3,0,1,value[0]);//x,y,L,D,N,val :座标、长度、小数、前导零(1显示 0不显示)、字体(0大字体 1中字体)、变量
  31.         
  32.         ADC_Val = 0;                            //读取电压通道1
  33.         for(i=0; i<8; i++){
  34.             ADC_Val += ADC0_GetConversion(ADC_MUXPOS_AIN18_gc);
  35.             DELAY_milliseconds(1);
  36.         }
  37.         value[1] = value[1]/2 + ADC_Val>>6;     //当前转换值(8次相加)除以8(右移3位)再取50%(右移1位)与之前数值的50%相加,得到享受滤波值
  38. //        value[1] = ADC_Val>>6;
  39.         LCD_write_GT_value(14,2,3,1,0,1,value[1]);//x,y,L,D,N,val :座标、长度、前导零(1显示 0不显示)、字体(0大字体 1中字体)、变量
  40.         
  41.         ADC_Val = 0;                            //读取电压通道2
  42.         for(i=0; i<8; i++){
  43.             ADC_Val += ADC0_GetConversion(ADC_MUXPOS_AIN7_gc);
  44.             DELAY_milliseconds(1);
  45.         }
  46.         value[2] = value[2]/2 + ADC_Val>>6;     //当前转换值(8次相加)除以8(右移3位)再取50%(右移1位)与之前数值的50%相加,得到享受滤波值
  47. //        value[2] = ADC_Val>>6;
  48.         LCD_write_GT_value(64,2,3,1,0,1,value[2]);//x,y,L,D,N,val :座标、长度、前导零(1显示 0不显示)、字体(0大字体 1中字体)、变量

  49.         ADC_Val = 0;                            //读取电压通道3
  50.         for(i=0; i<8; i++){
  51.             ADC_Val += ADC0_GetConversion(ADC_MUXPOS_AIN27_gc);
  52.             DELAY_milliseconds(1);
  53.         }
  54.         value[3] = value[3]/2 + ADC_Val>>6;     //当前转换值(8次相加)除以8(右移3位)再取50%(右移1位)与之前数值的50%相加,得到享受滤波值
  55. //        value[3] = ADC_Val>>6;
  56.         LCD_write_GT_value(114,2,3,1,0,1,value[3]);//x,y,L,D,N,val :座标、长度、前导零(1显示 0不显示)、字体(0大字体 1中字体)、变量
  57.         
  58.         ADC_Val = 0;                            //读取电压通道4
  59.         for(i=0; i<8; i++){
  60.             ADC_Val += ADC0_GetConversion(ADC_MUXPOS_AIN1_gc);
  61.             DELAY_milliseconds(1);
  62.         }
  63.         value[4] = value[4]/2 + ADC_Val>>6;     //当前转换值(8次相加)除以8(右移3位)再取50%(右移1位)与之前数值的50%相加,得到享受滤波值
  64. //        value[4] = ADC_Val>>6;
  65.         LCD_write_GT_value(164,2,3,1,0,1,value[4]);//x,y,L,D,N,val :座标、长度、前导零(1显示 0不显示)、字体(0大字体 1中字体)、变量
  66.         
  67.         ADC_Val = 0;                            //读取电压通道5
  68.         for(i=0; i<8; i++){
  69.             ADC_Val += ADC0_GetConversion(ADC_MUXPOS_AIN6_gc);
  70.             DELAY_milliseconds(1);
  71.         }
  72.         value[5] = value[5]/2 + ADC_Val>>6;     //当前转换值(8次相加)除以8(右移3位)再取50%(右移1位)与之前数值的50%相加,得到享受滤波值
  73. //        value[5] = ADC_Val>>6;
  74.         LCD_write_GT_value(14,4,3,1,0,1,value[5]);//x,y,L,D,N,val :座标、长度、前导零(1显示 0不显示)、字体(0大字体 1中字体)、变量
  75.         
  76.         ADC_Val = 0;                            //读取电压通道6
  77.         for(i=0; i<8; i++){
  78.             ADC_Val += ADC0_GetConversion(ADC_MUXPOS_AIN19_gc);
  79.             DELAY_milliseconds(1);
  80.         }
  81.         value[6] = value[6]/2 + ADC_Val>>6;     //当前转换值(8次相加)除以8(右移3位)再取50%(右移1位)与之前数值的50%相加,得到享受滤波值
  82. //        value[6] = ADC_Val>>6;
  83.         LCD_write_GT_value(64,4,3,1,0,1,value[6]);//x,y,L,D,N,val :座标、长度、前导零(1显示 0不显示)、字体(0大字体 1中字体)、变量

  84.         ADC_Val = 0;                            //读取电压通道7
  85.         for(i=0; i<8; i++){
  86.             ADC_Val += ADC0_GetConversion(ADC_MUXPOS_AIN2_gc);
  87.             DELAY_milliseconds(1);
  88.         }
  89.         value[7] = value[7]/2 + ADC_Val>>6;     //当前转换值(8次相加)除以8(右移3位)再取50%(右移1位)与之前数值的50%相加,得到享受滤波值
  90. //        value[7] = ADC_Val>>6;
  91.         LCD_write_GT_value(114,4,3,1,0,1,value[7]);//x,y,L,D,N,val :座标、长度、前导零(1显示 0不显示)、字体(0大字体 1中字体)、变量
  92.         
  93.         ADC_Val = 0;                            //读取电压通道8
  94.         for(i=0; i<8; i++){
  95.             ADC_Val += ADC0_GetConversion(ADC_MUXPOS_AIN3_gc);
  96.             DELAY_milliseconds(1);
  97.         }
  98.         value[8] = value[8]/2 + ADC_Val>>6;     //当前转换值(8次相加)除以8(右移3位)再取50%(右移1位)与之前数值的50%相加,得到享受滤波值
  99. //        value[8] = ADC_Val>>6;
  100.         LCD_write_GT_value(164,4,3,1,0,1,value[8]);//x,y,L,D,N,val :座标、长度、前导零(1显示 0不显示)、字体(0大字体 1中字体)、变量
  101.         
  102.         printf("电流值=%d\r\n",value[0]);
  103.         printf("电压通道1=%d\r\n",value[1]);
  104.         printf("电压通道2=%d\r\n",value[2]);
  105.         printf("电压通道3=%d\r\n",value[3]);
  106.         printf("电压通道4=%d\r\n",value[4]);
  107.         printf("电压通道5=%d\r\n",value[5]);
  108.         printf("电压通道6=%d\r\n",value[6]);
  109.         printf("电压通道7=%d\r\n",value[7]);
  110.         printf("电压通道8=%d\r\n\r\n",value[8]);
  111.         
  112.         if(ms>wait){
  113.             ms = 0;
  114.             Led0_Toggle();
  115.         }
  116.     }   
  117. }


    这是通过串口收到的数据截图:


本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?注册

×
pzsh 发表于 2022-11-28 15:19 | 显示全部楼层
很棒的创作,谢谢分享
 楼主| hu9jj 发表于 2022-11-29 10:39 | 显示全部楼层
pzsh 发表于 2022-11-28 15:19
很棒的创作,谢谢分享

谢谢夸奖!待解决了电流采样检测问题,完善了电路图之后准备重新打板,将整个装置放在小盒子中使用。
sanfuzi 发表于 2022-12-1 21:05 | 显示全部楼层
不同通道之间的ADC会存在串扰的吗
kmzuaz 发表于 2022-12-1 21:47 | 显示全部楼层
AVR64DD32的性能怎么样?
 楼主| hu9jj 发表于 2022-12-2 10:57 | 显示全部楼层
sanfuzi 发表于 2022-12-1 21:05
不同通道之间的ADC会存在串扰的吗

两次转换之间加了1毫秒的延时之后,通道之间的串扰就不十分明显,我再增加延时时间试试看。
burgessmaggie 发表于 2022-12-4 20:30 | 显示全部楼层
这个ADC最大支持几个通道的?              
您需要登录后才可以回帖 登录 | 注册

本版积分规则

认证:Microchip
简介:让我们来为您提供帮助。我们可提供各种资源来帮助您解决一切问题。是否需要与我们的客户支持团队联系?您可以通过电话、在线聊天功能或电子邮件与他们联系。

151

主题

1063

帖子

11

粉丝
快速回复 在线客服 返回列表 返回顶部