共2条
1/1 1 跳转至页
AD 困扰已久:AD出来的数据和实际加在芯片通道上的模拟值有出入
问
对浏览帖子的大侠表示由衷的感谢。如题,小弟是在MPLAB IDE内挂接PICC开发程序的,使用的芯片是16f877a。AD的两个寄存器的值设为ADCON1=0x00,ADCON0=0x41(当然通道会变),也就是说采用Fosc/8的模式,数据是左对齐,AD转换的分辨率为8位,每次AD结束后取ADRESH中的内容即可,而且AD的最大转换范围是单片机的供电电压5v,小弟每次AD之间都会有100微秒的间隔(采样捕捉时间和通道转换时间),每个通道不停的AD十次,得到十次的和(用sum表示)后,然后用average=sum*5/2550取得均值(浮点型)。到产品实际上电检测的时候发现,每次AD转换出来的数据比实际加在芯片通道上的直流模拟值要小,比如1v的变0.6v了,1.9v的变1.2v了,2v的变1.8v了,有大侠知道是什么原因吗??感激不尽
答 1:
哎,自己顶一个把采样滤波的函数和中断函数贴出来
void filter(void)// 均值滤波
{
unsigned int i,sum=0;
for(i=0; i<10; i++)
{
delay(20);//捕捉时间约200多us
ADGO=1;
while (!flagperend);//flagperend初始化时为0
sum=sum+adconvert;
flagperend=0;
}
average=sum*5/2550;//average浮点型,sum为unsigned char型
}
void interrupt ISR(void)
{
if(ADIE&&ADIF)
{
ADIF=0;
adconvert=ADRESH;
flagperend=1;
}
if(TMR1IE&&TMR1IF)
{
TMR1IF=0;
delaycount--;
}
if(EEIE&&EEIF)
{
EEIF=0;
flagwrite=1;
}
} 答 2: 有没有大侠赐教一二??难道自己还忽略了那些重要的寄存器的设置吗,还是ADCON0和ADCON1的设置有问题?? 答 3: 自己顶上去,急啊 答 4: *首先不要一次就取10次相加求平均,先取一次,看结果
答 5: 感谢大侠小弟明天按指示去调一下~~~~ 答 6: 我晕,还要明天啊,老大 答 7: AD采样值偏小的两个可能:第一是采样时间不够,在ADON和ADGO之间必须有一个足够的采样时间,第一是采样的AD信号阻抗偏大,比如大于10K,在这种情况下必须适当延长采样时间。建议信号内阻不要超过10K。
具体采样时间和信号内阻有关算法在每个数据手册中都有详细说明。
答 8: 回复感谢xieyuanbin大哥,小弟已经延时了近400微秒的采样捕捉时间和通道转换时间了,结果还是不行,头疼的问题啊,我的程序里面有错误吗?与AD有关的ADCON1的值是初始化中设好后一直不变的,而ADCON0中的值是根据通道变化在改变的,在中断中读ADRESH的值。也已经根据javie大哥的建议去试,只采样一次还是和采样十次取均值一样的结果,很郁闷啊,我还测了一下单片机的供电电压(即AD的参考电压)为5.1v,应该问题不大啊~~ 答 9: 400us?老大你能不能搞大一点啊,877A我没做过A/D,不过别的型号我都是1ms的 答 10: 好的,试去 答 11: 我觉得你的信号源内阻太大,我延时20US,精度很准确,16F74(8位AD)及12F675(10位AD)都用过 答 12: 参考电压有点偏高,不过误差应该没这么大5.1V的参考电压偏高,不过在这样的情况下3V读出数应该在2.97V左右。既然能得出结果,那么程序基本是没有问题的,ADON和ADGO均是ADCON0中的位,看你的程序也找不出毛病,再给两个建议:第一关掉AD中断,采用死等的办法看看结果是否符合,第二,你先告诉我你的AD口外面都接了什么?是否有平滑滤波电容?至少要有一个的。 答 13: 感谢诸位的指点十分感谢xieyuanbin,qianlong30的指点,你们都说到了点上。因为硬件是公司设计的,信号源内阻太大的问题我只能够从软件上适应了。一直觉得延时已经够长够狠了,后来按照javie大哥的指示,我把延时搞到了毫秒级,AD的值正常了!!再次感谢几位大侠的耐心指点~~~~
void filter(void)// 均值滤波
{
unsigned int i,sum=0;
for(i=0; i<10; i++)
{
delay(20);//捕捉时间约200多us
ADGO=1;
while (!flagperend);//flagperend初始化时为0
sum=sum+adconvert;
flagperend=0;
}
average=sum*5/2550;//average浮点型,sum为unsigned char型
}
void interrupt ISR(void)
{
if(ADIE&&ADIF)
{
ADIF=0;
adconvert=ADRESH;
flagperend=1;
}
if(TMR1IE&&TMR1IF)
{
TMR1IF=0;
delaycount--;
}
if(EEIE&&EEIF)
{
EEIF=0;
flagwrite=1;
}
} 答 2: 有没有大侠赐教一二??难道自己还忽略了那些重要的寄存器的设置吗,还是ADCON0和ADCON1的设置有问题?? 答 3: 自己顶上去,急啊 答 4: *首先不要一次就取10次相加求平均,先取一次,看结果
答 5: 感谢大侠小弟明天按指示去调一下~~~~ 答 6: 我晕,还要明天啊,老大 答 7: AD采样值偏小的两个可能:第一是采样时间不够,在ADON和ADGO之间必须有一个足够的采样时间,第一是采样的AD信号阻抗偏大,比如大于10K,在这种情况下必须适当延长采样时间。建议信号内阻不要超过10K。
具体采样时间和信号内阻有关算法在每个数据手册中都有详细说明。
答 8: 回复感谢xieyuanbin大哥,小弟已经延时了近400微秒的采样捕捉时间和通道转换时间了,结果还是不行,头疼的问题啊,我的程序里面有错误吗?与AD有关的ADCON1的值是初始化中设好后一直不变的,而ADCON0中的值是根据通道变化在改变的,在中断中读ADRESH的值。也已经根据javie大哥的建议去试,只采样一次还是和采样十次取均值一样的结果,很郁闷啊,我还测了一下单片机的供电电压(即AD的参考电压)为5.1v,应该问题不大啊~~ 答 9: 400us?老大你能不能搞大一点啊,877A我没做过A/D,不过别的型号我都是1ms的 答 10: 好的,试去 答 11: 我觉得你的信号源内阻太大,我延时20US,精度很准确,16F74(8位AD)及12F675(10位AD)都用过 答 12: 参考电压有点偏高,不过误差应该没这么大5.1V的参考电压偏高,不过在这样的情况下3V读出数应该在2.97V左右。既然能得出结果,那么程序基本是没有问题的,ADON和ADGO均是ADCON0中的位,看你的程序也找不出毛病,再给两个建议:第一关掉AD中断,采用死等的办法看看结果是否符合,第二,你先告诉我你的AD口外面都接了什么?是否有平滑滤波电容?至少要有一个的。 答 13: 感谢诸位的指点十分感谢xieyuanbin,qianlong30的指点,你们都说到了点上。因为硬件是公司设计的,信号源内阻太大的问题我只能够从软件上适应了。一直觉得延时已经够长够狠了,后来按照javie大哥的指示,我把延时搞到了毫秒级,AD的值正常了!!再次感谢几位大侠的耐心指点~~~~
共2条
1/1 1 跳转至页
回复
有奖活动 | |
---|---|
【有奖活动】分享技术经验,兑换京东卡 | |
话不多说,快进群! | |
请大声喊出:我要开发板! | |
【有奖活动】EEPW网站征稿正在进行时,欢迎踊跃投稿啦 | |
奖!发布技术笔记,技术评测贴换取您心仪的礼品 | |
打赏了!打赏了!打赏了! |