在线等,看看这个AD采集为何不正确
本帖最后由 孤独将一 于 2013-7-10 15:30 编辑//===================AD 转换==========]
void ADC_Convect(unsigned char channel)
{
ADMUX = channel & 0x07;
AD_value =((int)( ADCL+ADCH*256)) * 500.0 / 1023.0;
put_char(AD_value/100 +0x30); put_char('.');put_char(AD_value/10%10+0x30);put_char(AD_value%10+0x30);put_char('V');
put_char('\n');
_delay_ms(500);
}
int main()
{
DDRA = 0xf8;
usart_init();
ADCSRA = 0xe6; //启动转换,64分频
_delay_ms(200);
while(1)
{
ADC_Convect(5);
}
return 0;
}===============================================
1:代码简化,芯片AVR16的,直接用片上AD0。AREF接的外置5v。
2:我采集到串口的每次都是5v,虽然以前做过更复杂采集的,但这次不知道为何,哪错了。
3:输出接到0V或不接
=========================================================
解决,不是代码问题,是硬件AVCC接了5v,导致ADMUX=0时通道采集到的可定时5V there are so many thing wrong that it probably makes sense for you to go back to more basic stuff.
some suggestions:
1) read the datasheet. make you you understand it;
2) change the structure of your code. I would break down your code into two pieces, one initialize the adc module and another performs the adc and returns its result.
((int)( ADCL+ADCH*256))
换成
((unsigned int) ADCL+(unsigned int)ADCH*256))
试试
millwood0 发表于 2013-7-10 01:43 static/image/common/back.gif
there are so many thing wrong that it probably makes sense for you to go back to more basic stuff.
...
Thank you, I saw datasheet several times. But still don't know what's wrong. 本帖最后由 孤独将一 于 2013-7-10 09:13 编辑
lcw_swust 发表于 2013-7-10 09:04 static/image/common/back.gif
((int)( ADCL+ADCH*256))
换成
((unsigned int) ADCL+(unsigned int)ADCH*256))
我就是换成这个也是AD_value =ADC * 500.0 / 1023.0;问题也是5V 怎么没有看到启动转换的代码呢。 .titrwh 发表于 2013-7-10 09:19 static/image/common/back.gif
怎么没有看到启动转换的代码呢。 ...
你指的是不是:put_char('.');put_char(AD_value/10%10+0x30);put_char(AD_value%10+0x30);put_char('V');数据处理这
转换就是ADCSRA = 0xe6;ADMUX = channel & 0x07; //===================AD 转换==========]
void ADC_Convect(unsigned char channel)
{
ADMUX = channel & 0x07;
ADCSRA = 0xe6;
AD_value =((int)( ADCL+ADCH*256)) * 500.0 / 1023.0;
put_char(AD_value/100 +0x30); put_char('.');put_char(AD_value/10%10+0x30);put_char(AD_value%10+0x30);put_char('V');
put_char('\n');
_delay_ms(500);
}
感觉应该这样 .titrwh 发表于 2013-7-10 09:26 static/image/common/back.gif
//===================AD 转换==========]
void ADC_Convect(unsigned char channel)
ADCSRA = 0xe6;加到转换里面,不顶用的 孤独将一 发表于 2013-7-10 09:37 static/image/common/back.gif
ADCSRA = 0xe6;加到转换里面,不顶用的
那就不太清楚了,好多年没用AVR了,记得大概流程就是IO设置输入悬空,设置转换模式一般为单次转换,左对齐右对齐,然后选择通道,启动一次转换,等待转换结束,读取的时候好像是先低位还是先高位忘了。看看相关几个寄存器就行了,认真就好,如果还不行估计就是硬件问题了。 .titrwh 发表于 2013-7-10 09:44 static/image/common/back.gif
那就不太清楚了,好多年没用AVR了,记得大概流程就是IO设置输入悬空,设置转换模式一般为单次转换,左对 ...
谢谢。硬件不会错的,换做以前的板子也是这问题,估计哪个点没注意 本帖最后由 machao 于 2013-7-10 12:53 编辑
先把这条语句的错误找到。
AD_value =((int)( ADCL+ADCH*256)) * 500.0 / 1023.0;
先把数据类型搞清楚,模拟个ADC的值,比如4.5V的二进制值,看显示是否对,如果送显示不对,先把后面的调好。最后再去读真正ADC寄存器的值
我的书上有ADC的例子,你看我的书,应该真正的去看懂和理解? machao 发表于 2013-7-10 12:16 static/image/common/back.gif
先把这条语句的错误找到。
AD_value =((int)( ADCL+ADCH*256)) * 500.0 / 1023.0;
哪错了,不清楚啊。 AD_value =(unsigned long)ADC * 500.0 / 1023.0;=====================================================AD_value =(( int)( ADCL+ADCH*256)) * 500.0 / 1023.0;==========================================================AD_value =(int) ADCW* 500.0 / 1023.0; 孤独将一 发表于 2013-7-10 12:53 static/image/common/back.gif
哪错了,不清楚啊。================================================================================ ...
C语言如何学的? ADCH*256 就出问题了
ADCH是8位的,乘上255是多少位?
本帖最后由 孤独将一 于 2013-7-10 13:09 编辑
machao 发表于 2013-7-10 12:56 static/image/common/back.gif
ADCH*256 就出问题了
ADCH是8位的,乘上255是多少位?
我的C基础不好。
AD_value =(int) ADC* 500.0 / 1023.0;这个没问题吧,但是不对//===================AD 转换==========]
void ADC_Convect(unsigned char channel)
{
ADMUX = channel & 0x07;
_delay_ms(500);
AD_value =(unsigned long)ADCW * 500.0 / 1023.0;
put_char(AD_value/100 +0x30); put_char('.');put_char(AD_value/10%10+0x30);put_char(AD_value%10+0x30);put_char('V');
put_char('\n');
}
int main()
{
DDRA = 0x00;
usart_init();
ADCSRA = 0xe6; //启动转换,64分频
sei();
while(1)
{
ADC_Convect(0);
_delay_ms(100);
ADC_Convect(1);
_delay_ms(100);
}
return 0;
} // ADC 转换完成中断服务
interrupt void adc_isr(void)
{
unsigned int adc_data,adc_v;
adc_data=ADCW; //读取ADC置换结果
adc_v=(unsigned long)adc_data*5000/1024; //换算成电压值
adc_to_disbuffer(adc_v);
}
这是我书上的例子,能明白吗? put_char(AD_value/100 +0x30);put_char('.');put_char(AD_value/10%10+0x30);put_char(AD_value%10+0x30);put_char('V');
这段也是问题多多。先把C弄好吧 你手上真的有我的书?还是把它烧掉吧。免得害了你。因为我是一个“坑人”的教授。 machao 发表于 2013-7-10 13:19 static/image/common/back.gif
你手上真的有我的书?还是把它烧掉吧。免得害了你。因为我是一个“坑人”的教授。 ...
呃,马老师怒了。
莫生气、莫生气。 machao 发表于 2013-7-10 13:19 static/image/common/back.gif
你手上真的有我的书?还是把它烧掉吧。免得害了你。因为我是一个“坑人”的教授。 ...
你牛。。。。。。。。。 这代码的写的不敢直视啊。 孤独将一 发表于 2013-7-10 12:53 static/image/common/back.gif
哪错了,不清楚啊。================================================================================ ...
AD_value =(unsigned long)ADC * 500.0 / 1023.0;
ADC long型*500.0 浮点型这个是干嘛?通过仿真自己找找,不然别人告诉你,你下次也不会记得。 machao 发表于 2013-7-10 13:19 static/image/common/back.gif
你手上真的有我的书?还是把它烧掉吧。免得害了你。因为我是一个“坑人”的教授。 ...
。。。。。找见根本原因了,根本不是代码的问题。最近一直气头,加上你一激,我更气了。
之前对不起,网上深鞠一躬。 guew 发表于 2013-7-10 13:38 static/image/common/back.gif
这代码的写的不敢直视啊。
你的代码可以直视?亮出来嗮下,我们学习下 孤独将一 发表于 2013-7-10 15:29 static/image/common/back.gif
。。。。。找见根本原因了,根本不是代码的问题。最近一直气头,加上你一激,我更气了。
之前对不起,网 ...
解决了就把问题和解决方法写出来,这是基本规矩,不要有问题的时候就不停问,解决了就不管了,要写出来让其他人以后不要犯类似错误。 孤独将一 发表于 2013-7-10 15:31 static/image/common/back.gif
你的代码可以直视?亮出来嗮下,我们学习下
就是比你写的好,就是不给你看。 楼上不地道,你直接把马老师的代码移植过去,然后自己理解再加上自己想要加的,马老师那个代码我用过很多次,你也可以试着用共用体速度上会快点 本帖最后由 guew 于 2013-7-10 16:04 编辑
hyghyg1234 发表于 2013-7-10 15:57 static/image/common/back.gif
楼上不地道,你直接把马老师的代码移植过去,然后自己理解再加上自己想要加的,马老师那个代码我用过很多次 ...
有的时候做烂好人反而会纵容一些坏风气,长远来看,对人,对己,都不好。 AD_value =(unsigned long)ADCW * 500.0 / 1023.0;
===============
改成下面:AD_value要定义成无符号INT型
//AD_value = ADCW; //1
AD_value = 900; //2假定ADCW寄存器的值为900, 900*500/1023 = 4.51v,相当4.51V
AD_value =(unsigned long)AD_value * 500 / 1023;
如果显示不对,先查输出显示。
如显示为4.51,则问题出在ADC转换。把2注释掉,用1。另外注意,ADC的输入脚要定义成高阻输入,不能定义上拉有效,更不能定义成输出。
这些在我的教程中都有说明的,不过你还是烧了它吧。
本帖最后由 machao 于 2013-7-10 16:28 编辑
首先要看是什么问题,代码的问题要先解决,保证转换显示正确,然后再查ADC设置和使用是否对。混在一起不容易找到问题。
LZ位的代码中的:AD_value =((int)( ADCL+ADCH*256)) * 500.0 / 1023.0;
有2个可能的问题:
1、ADCH*256 可能就出问题了,因为ADCH是8位的,乘上256,两个8位乘,超限是肯定的(当然ADCH为1或0是可以的)。
2、(int)( ADCL+ADCH*256)) 这里把结果转换成INT,但乘上500,也超限,尽管后面写的是500.0实数,这个看编译器如何处理了。所以我喜欢直接强制转换成长整型,作整数的运算,比浮点运算也快,也保险。 LZ说解决了:
解决,不是代码问题,是硬件AVCC接了5v,导致ADMUX=0时通道采集到的可定时5V
==========================================
这个解释让人怀疑。
AVR有2个电源脚,VCC和AVCC。AVCC是提供A口的工作电压的,总是要接5V的。只是用ADC的话,AVCC的5V最好稳定些。如果AVCC不接5V,A口工作根本就不正常(不管是否使用ADC)。是ADC寄存器的设置问题还是其它的?ADC的参考电压可以设置成AVCC或内部2.56V或引脚REF电压 hyghyg1234 发表于 2013-7-10 15:57 static/image/common/back.gif
楼上不地道,你直接把马老师的代码移植过去,然后自己理解再加上自己想要加的,马老师那个代码我用过很多次 ...
我没移植他的代码,我看过他的中断处理。我这个不是中断处理。
machao 发表于 2013-7-10 16:26 static/image/common/back.gif
首先要看是什么问题,代码的问题要先解决,保证转换显示正确,然后再查ADC设置和使用是否对。混在一起不容 ...
我用的avr studio。
AD_value = (int)((ADCL + ADCH <<8) *500.0 /1023.0).
page 127.彭伟的书,你们学校的。
这个ADCH << 8 和ADCH * 256有区别吗,我的C确实不太好 本帖最后由 孤独将一 于 2013-7-11 10:33 编辑
machao 发表于 2013-7-10 16:41 static/image/common/back.gif
LZ说解决了:
解决,不是代码问题,
搞错,1楼没有编辑选项了。
是AREF没接参考电压。我的错误,抱歉 楼主太扣了,悬赏莫元太少 starli 发表于 2013-7-11 10:16 static/image/common/back.gif
楼主太扣了,悬赏莫元太少
lz发的几乎都是悬赏贴,基本都是5莫元以下。 不抠门。感觉像个漏洞。莫元又不能变钱。攒那么多不如干实事,发帖吸引眼球。
今天搞GPS,http://www.amobbs.com/thread-5541898-1-1.html
页:
[1]