打印
[技术问答]

N76E003多路AD转换不稳定

[复制链接]
745|10
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
CLEE|  楼主 | 2020-4-11 11:25 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
使用n76e003单片机AD转换三路输入模拟电压信号,发现各路之间有干扰。如果有两路或三路同时有输入信号那么各路AD转换后输出值存在波动。如果只有一路有输入信号那么AD转换输出值非常稳定,不知道是什么原因。

使用特权

评论回复
沙发
antusheng| | 2020-4-11 22:08 | 只看该作者
应该是没弄好。

使用特权

评论回复
板凳
antusheng| | 2020-4-11 22:08 | 只看该作者
内部是不会串的。是不是没有充放电完全。

使用特权

评论回复
地板
天灵灵地灵灵| | 2020-4-11 23:10 | 只看该作者
不会啊,没遇到过。代码发来看看。

使用特权

评论回复
5
CLEE|  楼主 | 2020-4-12 22:01 | 只看该作者

/*******************  头文件  *******************/
#include "N76E003.h"
#include "Common.h"
#include "Delay.h"
#include "SFR_Macro.h"
#include "Function_define.h"
/*******************  函数声明  *******************/
void Avg_value(void);       //获取ADC转换平均值
void Get_Voltage(void);     //获取ADC电压值
void ADC_Inquiry(void);     //ADC转换查询
/*******************  变量 *******************/
extern UINT16 xdata SystemData[];
extern UINT8 adc_count;      //ADC转换次数计数器
extern UINT16 xdata adc_buf[];     //ADC转换值缓存数组
extern UINT16 adc_avg;       //ADC转换平均值
extern UINT16 Voltage;       //ADC转换电压值
extern UINT16 xdata Vol_Value[3];
extern UINT8 Vol_Count;
/*******************  函数体 *******************/
void ADC_Inquiry(void)     //ADC转换查询方式
{
if(ADCS == 0 && ADCF == 1)
{  
  clr_ADCF;
  adc_buf[adc_count] = (ADCRH<<4)+ADCRL;
  adc_count++;
  if(adc_count == 10)
  {
   clr_ADCEN;  //还没有处理完数据的时候先将ADC关闭掉,
  }
  else
  set_ADCS;        //启动新一轮ADC转换
}
}
void Get_Voltage(void)    //获取ADC电压值
{
Avg_value();
if(adc_count == 11)
{
  if((ADCCON0 & 0X0F) == 0X05) //VBUS电压
  {
   Vol_Value[Vol_Count++] = (UINT16)(adc_avg * ((float)3300 / 4096)*SystemData[37]/10000);
   if(Vol_Count == 3)
      {
    Voltage = Vol_Value[1] * 5 + Vol_Value[2] * 6;
     Vol_Count = 0;
    Enable_ADC_AIN0;   //切换到D+电压
    SystemData[0] = Voltage;  //更新VBUS电压
    if(Voltage < 50)  SystemData[0] = 0;
   }      
  }
  else if((ADCCON0 & 0X0F) == 0X00) //D+电压
  {
   Voltage = (UINT16)(((float)adc_avg * (float)3330 / 4096));
   Enable_ADC_AIN4;   //切换到D-电压
   SystemData[1] = Voltage;  //更新D+电压
   if(Voltage < 79)  SystemData[1] = 0;   
  }  
  else if((ADCCON0 & 0X0F) == 0X04) //D-电压
  {
   Voltage = (UINT16)(((float)adc_avg * (float)3330 / 4096));
   Enable_ADC_AIN5;   //切换到VBUS电压
   SystemData[2] = Voltage;  //更新D-电压
   if(Voltage < 79)  SystemData[2] = 0;
  }
  adc_count = 0;
  set_ADCEN;
  set_ADCS;         //启动ADC转换   
}
}

void Avg_value(void)       //获取ADC转换平均值
{
UINT8 i,j;
UINT16 adc_data;      //ADC转换循环索引
if(adc_count == 10)
{
  //=== 求10次AD转换平均值,去掉最大值2个,最小值2个,计算余下6个平均值 ===//
  for(j=9; j>0; j--)
  {
   for(i=0; i<j; i++)     //ADC转换值从小到大排序
   {
    if(adc_buf[i] > adc_buf[i+1])
    {
     adc_data = adc_buf[i];
     adc_buf[i] = adc_buf[i+1];
     adc_buf[i+1] = adc_data;
    }
   }
  }
  //=== 计算平均值 ===//
  adc_avg = (adc_buf[2]+adc_buf[3]+adc_buf[4]+adc_buf[5]+adc_buf[6]+adc_buf[7]) / 6;
    adc_count = 11;  
}  
}






使用特权

评论回复
6
xuanhuanzi| | 2020-4-12 23:40 | 只看该作者
没看出来3路啊。

使用特权

评论回复
7
CLEE|  楼主 | 2020-4-13 11:27 | 只看该作者

Enable_ADC_AIN0;
Enable_ADC_AIN4;
Enable_ADC_AIN5; 这三路

使用特权

评论回复
8
jasontu| | 2020-4-14 07:49 | 只看该作者
看代码上面,你的代码处理已经避开了你说的问题。
不同通道切换,内部的电容还没有放光电。
可以降低sample rate, 或是放弃切完通道第一笔值,作平均采样

使用特权

评论回复
9
168LiYA| | 2020-4-14 11:09 | 只看该作者
技术支持,Q415021063.

使用特权

评论回复
10
xch| | 2020-4-14 11:36 | 只看该作者
尽量增加采样时间。

使用特权

评论回复
11
CLEE|  楼主 | 2020-4-14 17:14 | 只看该作者
N76E003 AD转换时钟就是系统时钟无法再分频,除非系统时钟分频,但是我的程序必须运行在16M时钟,所以无法降低系统来达到AD采样的理想效果。昨天收到的新唐的MS51XB9AE这个单片机,可以完美替代N76E003,功能更强大。其中AD采集时间和速率可调,程序稍微修改就可以了。现在AD转换值输出很稳了,但是N76E003的问题还是很想解决,因为之前已经出了很多产品了,虽然没有影响,但是还是想把问题解决。

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

8

主题

43

帖子

0

粉丝