孤独将一 发表于 2013-7-9 22:05:44

在线等,看看这个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

millwood0 发表于 2013-7-10 01:43:42

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.

lcw_swust 发表于 2013-7-10 09:04:12

((int)( ADCL+ADCH*256))
换成
((unsigned int) ADCL+(unsigned int)ADCH*256))
试试

孤独将一 发表于 2013-7-10 09:09:55

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:12:31

本帖最后由 孤独将一 于 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:03

怎么没有看到启动转换的代码呢。                                                                                                                  

孤独将一 发表于 2013-7-10 09:21:09

.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;

.titrwh 发表于 2013-7-10 09:26:05

//===================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);

}
感觉应该这样

孤独将一 发表于 2013-7-10 09:37:22

.titrwh 发表于 2013-7-10 09:26 static/image/common/back.gif
//===================AD 转换==========]

void ADC_Convect(unsigned char channel)


ADCSRA = 0xe6;加到转换里面,不顶用的

.titrwh 发表于 2013-7-10 09:44:16

孤独将一 发表于 2013-7-10 09:37 static/image/common/back.gif
ADCSRA = 0xe6;加到转换里面,不顶用的

那就不太清楚了,好多年没用AVR了,记得大概流程就是IO设置输入悬空,设置转换模式一般为单次转换,左对齐右对齐,然后选择通道,启动一次转换,等待转换结束,读取的时候好像是先低位还是先高位忘了。看看相关几个寄存器就行了,认真就好,如果还不行估计就是硬件问题了。

孤独将一 发表于 2013-7-10 10:57:16

.titrwh 发表于 2013-7-10 09:44 static/image/common/back.gif
那就不太清楚了,好多年没用AVR了,记得大概流程就是IO设置输入悬空,设置转换模式一般为单次转换,左对 ...

谢谢。硬件不会错的,换做以前的板子也是这问题,估计哪个点没注意

machao 发表于 2013-7-10 12:16:18

本帖最后由 machao 于 2013-7-10 12:53 编辑

先把这条语句的错误找到。
       AD_value =((int)( ADCL+ADCH*256)) * 500.0 / 1023.0;

先把数据类型搞清楚,模拟个ADC的值,比如4.5V的二进制值,看显示是否对,如果送显示不对,先把后面的调好。最后再去读真正ADC寄存器的值

我的书上有ADC的例子,你看我的书,应该真正的去看懂和理解?

孤独将一 发表于 2013-7-10 12:53:08

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;

machao 发表于 2013-7-10 12:54:42

孤独将一 发表于 2013-7-10 12:53 static/image/common/back.gif
哪错了,不清楚啊。================================================================================ ...

C语言如何学的?

machao 发表于 2013-7-10 12:56:22

ADCH*256 就出问题了
ADCH是8位的,乘上255是多少位?

孤独将一 发表于 2013-7-10 13:06:45

本帖最后由 孤独将一 于 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;
}

machao 发表于 2013-7-10 13:13:58

// 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);
}

这是我书上的例子,能明白吗?

machao 发表于 2013-7-10 13:16:36

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:47

你手上真的有我的书?还是把它烧掉吧。免得害了你。因为我是一个“坑人”的教授。

eduhf_123 发表于 2013-7-10 13:25:01

machao 发表于 2013-7-10 13:19 static/image/common/back.gif
你手上真的有我的书?还是把它烧掉吧。免得害了你。因为我是一个“坑人”的教授。 ...

呃,马老师怒了。

莫生气、莫生气。

孤独将一 发表于 2013-7-10 13:27:00

machao 发表于 2013-7-10 13:19 static/image/common/back.gif
你手上真的有我的书?还是把它烧掉吧。免得害了你。因为我是一个“坑人”的教授。 ...

你牛。。。。。。。。。

guew 发表于 2013-7-10 13:38:29

这代码的写的不敢直视啊。

hyghyg1234 发表于 2013-7-10 15:06:23

孤独将一 发表于 2013-7-10 12:53 static/image/common/back.gif
哪错了,不清楚啊。================================================================================ ...

AD_value =(unsigned long)ADC * 500.0 / 1023.0;
ADC long型*500.0 浮点型这个是干嘛?通过仿真自己找找,不然别人告诉你,你下次也不会记得。

孤独将一 发表于 2013-7-10 15:29:13

machao 发表于 2013-7-10 13:19 static/image/common/back.gif
你手上真的有我的书?还是把它烧掉吧。免得害了你。因为我是一个“坑人”的教授。 ...

。。。。。找见根本原因了,根本不是代码的问题。最近一直气头,加上你一激,我更气了。
之前对不起,网上深鞠一躬。

孤独将一 发表于 2013-7-10 15:31:10

guew 发表于 2013-7-10 13:38 static/image/common/back.gif
这代码的写的不敢直视啊。

你的代码可以直视?亮出来嗮下,我们学习下

.titrwh 发表于 2013-7-10 15:31:39

孤独将一 发表于 2013-7-10 15:29 static/image/common/back.gif
。。。。。找见根本原因了,根本不是代码的问题。最近一直气头,加上你一激,我更气了。
之前对不起,网 ...

解决了就把问题和解决方法写出来,这是基本规矩,不要有问题的时候就不停问,解决了就不管了,要写出来让其他人以后不要犯类似错误。

guew 发表于 2013-7-10 15:44:02

孤独将一 发表于 2013-7-10 15:31 static/image/common/back.gif
你的代码可以直视?亮出来嗮下,我们学习下

就是比你写的好,就是不给你看。

hyghyg1234 发表于 2013-7-10 15:57:01

楼上不地道,你直接把马老师的代码移植过去,然后自己理解再加上自己想要加的,马老师那个代码我用过很多次,你也可以试着用共用体速度上会快点

guew 发表于 2013-7-10 16:02:50

本帖最后由 guew 于 2013-7-10 16:04 编辑

hyghyg1234 发表于 2013-7-10 15:57 static/image/common/back.gif
楼上不地道,你直接把马老师的代码移植过去,然后自己理解再加上自己想要加的,马老师那个代码我用过很多次 ...

有的时候做烂好人反而会纵容一些坏风气,长远来看,对人,对己,都不好。

machao 发表于 2013-7-10 16:09:39

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:26:34

本帖最后由 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实数,这个看编译器如何处理了。所以我喜欢直接强制转换成长整型,作整数的运算,比浮点运算也快,也保险。

machao 发表于 2013-7-9 22:05:45

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电压

孤独将一 发表于 2013-7-10 17:42:32

hyghyg1234 发表于 2013-7-10 15:57 static/image/common/back.gif
楼上不地道,你直接把马老师的代码移植过去,然后自己理解再加上自己想要加的,马老师那个代码我用过很多次 ...

我没移植他的代码,我看过他的中断处理。我这个不是中断处理。

孤独将一 发表于 2013-7-10 17:45:51

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:14:06

本帖最后由 孤独将一 于 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:33

楼主太扣了,悬赏莫元太少

.titrwh 发表于 2013-7-11 10:20:03

starli 发表于 2013-7-11 10:16 static/image/common/back.gif
楼主太扣了,悬赏莫元太少

lz发的几乎都是悬赏贴,基本都是5莫元以下。

孤独将一 发表于 2013-7-11 10:36:08

不抠门。感觉像个漏洞。莫元又不能变钱。攒那么多不如干实事,发帖吸引眼球。

今天搞GPS,http://www.amobbs.com/thread-5541898-1-1.html
页: [1]
查看完整版本: 在线等,看看这个AD采集为何不正确