佳礼资讯网

 找回密码
 注册

ADVERTISEMENT

查看: 1993|回复: 18

请教ADC的问题

[复制链接]
发表于 20-11-2008 01:01 PM | 显示全部楼层 |阅读模式
大家好!我是PIC的新手,目前正为final project ADC setting的问题烦恼着(因为不是很熟悉ADC)……
想请教各位,如何正确地去setting ADC?例如我给个1.5v analogue input signal去channel 2,C language要如何写才能拿到ADC之后的result?注意!我想要的是AD conversion之后的result,并不想把这result给show在任何一个port,因为这result是要用来call去做其他的condition的,我refer去micro c的sample program,它的result是有show出来的……

还有我使用的是PIC16F877,用C language写……
所以想请教各位高手的帮忙,我的project已经hang在这边了,拜托……
回复

使用道具 举报


ADVERTISEMENT

发表于 20-11-2008 01:51 PM | 显示全部楼层
原帖由 于 20-11-2008 01:01 PM 发表
大家好!我是PIC的新手,目前正为final project ADC setting的问题烦恼着(因为不是很熟悉ADC)……
想请教各位,如何正确地去setting ADC?例如我给个1.5v analogue input signal去channel 2,C language要如何写才 ...


你能告诉说你用的是什么 C 语言吗?

爬下这个贴看下是否有帮助 :http://cforum4.cari.com.my/viewthread.php?tid=1009693&extra=page%3D6
回复

使用道具 举报

 楼主| 发表于 20-11-2008 05:35 PM | 显示全部楼层

回复 2# rothmans 的帖子

我是用“microC compiler for PIC"这个sofware来写的,所以应该是micro C……

谢谢这位仁兄提供的link,已经看过了,不过不是很清楚,可能需要时间去研究……

想请教,ADCON1 = 0x80这样的setting代表什么意思呢?refer PIC的datasheet是说“right justified",并不是很了解……
回复

使用道具 举报

发表于 20-11-2008 10:01 PM | 显示全部楼层
原帖由 于 20-11-2008 01:01 PM 发表
大家好!我是PIC的新手,目前正为final project ADC setting的问题烦恼着(因为不是很熟悉ADC)……
想请教各位,如何正确地去setting ADC?例如我给个1.5v analogue input signal去channel 2,C language要如何写才 ...

MicroC 我不会, 但我不认为MicroC要去管什么ADCON1 = 0x80之类的。。。

下面是CCS C compiler的示范, 就是这么简单。
  1. // Compiler:  CCS C (any Version)
  2. // By pIc@cArI, 20 Nov 08
  3. #include <16F877A.h>
  4. #device ADC=10
  5. #fuses   HS, NoPROTECT,NoWDT,put,brownout,nolvp
  6. #use delay(clock=20000000)

  7. void main()
  8. {
  9. int16 value;

  10.    setup_adc_ports( ALL_ANALOG );
  11.    setup_adc(adc_clock_internal);
  12.    set_adc_channel(2); // set Channel 2
  13.    while(true)
  14.    {
  15.       value = read_adc(); // ADC result in value
  16.    }
  17. }
复制代码
回复

使用道具 举报

 楼主| 发表于 20-11-2008 10:48 PM | 显示全部楼层

回复 4# pic 的帖子

Erm..大概有一点点idea了,先去尝试看看才知道……
无论如何,多谢给位高手们的提点……
回复

使用道具 举报

 楼主| 发表于 25-11-2008 05:24 PM | 显示全部楼层
unsigned int result;

void main()
{
ADCON1 = 0x80;         //configure analog inputs and vref
TRISA = 0xff;          //porta is input
TRISD = 0;          //portd is output

while(1)
{
  result = Adc_Read(2);       //get results of AD conversion
  
  if(result==0b0000000000)
  {
   portd = 0x01;
  }
  else if(0b0100101001<=result<=0b0100110011)    //1.45v <= result <= 1.5v
  {
   portd = 0x05;                     //ph5
  }
  else if(0b1101001000<=result<=0b1101010010)    //4.1v <= result <= 4.15v
  {
   portd = 0x0d;                     //ph13
  }
  else if(0b1101111011<=result<=0b1110000100)    //4.35v <= result <= 4.39v
  {
   portd = 0x02;                     //ph2
  }
}
}

===================================================================================
以上是我用microC 写出来的program……
想请教各位高手,这样的写法是否正确?为何我read不到最后两个else if 的condition??
ADC的setting是否正确?是不是还缺少了什么?
compiler出来没有问题,但result并不是我想要的,为何~~~~
回复

使用道具 举报

Follow Us
发表于 25-11-2008 09:18 PM | 显示全部楼层
在 C 里面是不可以写 if (a < b < c) 的。正确方法应该是 if ((a < b) && (b < c))。
回复

使用道具 举报

 楼主| 发表于 25-11-2008 11:34 PM | 显示全部楼层

回复 7# waiweng83 的帖子

多写这位仁兄的提点,刚刚照着你说的改了一下,已经可以work了,呵呵……
感激!感激!
回复

使用道具 举报


ADVERTISEMENT

发表于 3-3-2009 11:02 AM | 显示全部楼层
Vref+ 和 Vref- 可以用来提高 ADC 的灵敏度。比如说 Vref+ = VDD, Vref- = VSS,那你的 ADC 最小可以探测到 5V / 1024 = 4.88mV。

但是如果你的 sensor output full range 只是 0 - 3V,那你可以把 Vref+ 接去 3V reference voltage,Vref- = VSS。这样,ADC 最小就可以探测到 3V / 1024 = 2.93mV 了。

评分

参与人数 1积分 +10 收起 理由
fritlizt + 10

查看全部评分

回复

使用道具 举报

发表于 23-2-2009 05:21 PM | 显示全部楼层
原帖由 crazybear 于 23-2-2009 02:38 PM 发表
#device ADC=10                        
为什么要放10?

告诉compiler 我们的PIC MCU 的ADC 是用10bit的模式。
                        



int16 value;                             
这是不是指那ADC的output是16bit?

ADC 的输出是10bit, 但是用16bit 的variable 来装。


   setup_adc(adc_clock_internal);        
什么是adc_clock_internal?有什么做用?
  
ADC 是需要时钟Clock 来跑的, 他可以用Crystal, 或它内建的RC Clock。
这里告诉compiler 我们用内建的Clock 来做ADC。


      value = read_adc(); // ADC result in value  那个value是in decimal, binary or hex?
     
value 是 0-1024。
看你怎么读取, 没有什么所谓的decimal, binary 或 hex。
回复

使用道具 举报

发表于 23-2-2009 02:38 PM | 显示全部楼层
PIC老大,小弟有些问题不明白,希望你能解答小弟愚蠢的问题。

// Compiler:  CCS C (any Version)
// By pIc@cArI, 20 Nov 08
#include <16F877A.h>
#device ADC=10                         为什么要放10?
#fuses   HS, NoPROTECT,NoWDT,put,brownout,nolvp
#use delay(clock=20000000)

void main()
{
int16 value;                             这是不是指那ADC的output是16bit?

   setup_adc_ports( ALL_ANALOG );     
   setup_adc(adc_clock_internal);        什么是adc_clock_internal?有什么做用?
   set_adc_channel(2); // set Channel 2  
   while(true)
   {
      value = read_adc(); // ADC result in value  那个value是in decimal, binary or hex?
   }
}
回复

使用道具 举报

发表于 26-2-2009 05:37 PM | 显示全部楼层
原帖由 pic 于 23-2-2009 05:21 PM 发表

value 是 0-1024。


0-1023
更正一点
回复

使用道具 举报

发表于 26-2-2009 10:35 PM | 显示全部楼层
原帖由 fritlizt 于 26-2-2009 05:37 PM 发表


0-1023
更正一点

对, 没有错, 是0~1023.
谢谢 ~
回复

使用道具 举报

发表于 2-3-2009 04:06 PM | 显示全部楼层
不好意思。。。我也要来参与。。
我的FYPproject已经完成了(对我来说),但是我还是觉得代源码方面还是有点问题。。。希望大家能够提供一些意见。。!!

首先,我的project是用三个analogue sensor 来sense 光度,温度以及温湿度。这些sensor会detect周围的环境,然后通过PIC16F877去LCD 以及控制其他的电路。。
我用的C软件是Hitech C. 这个软件是需要配合maplab一起启动的。

会用ADC的玩家都会知道,pic16f877 是可以支持10bit ADC 的。只要我们在 <ADCON1:0B10000001> 最左手边的bit放1,那么我们的pic就会启动1024 resolution。

现在我的问题就在于sensor 的ADC计算。。
-------------------------------------------------------------------------------
比方说:Humidity Sensor name:&#160;&#160;HSM-20g
&#160; &#160;&#160; &#160;&#160; &#160;&#160; &#160;&#160; &#160;Humidity sensor operating range :&#160;&#160;0% Rh -- 95%RH
&#160; &#160;&#160; &#160;&#160; &#160;&#160; &#160;&#160; &#160;Output Sensor is : 0v&#160;&#160;to&#160;&#160;3v
&#160; &#160;&#160; &#160;&#160; &#160;&#160; &#160;&#160; &#160;humidity sensor 必须用supply 5V来启动。。
--------------------------------------------------------------------------------
&#160; &#160;&#160; &#160;&#160; &#160;&#160; &#160;&#160; &#160;在pic 877, 我用port RA0, RA1以及RA3连接 温湿,
&#160; &#160;&#160; &#160;&#160; &#160;&#160; &#160;&#160; &#160;温度,亮度。所以我的ADCON1 = 0B10000100.
&#160; &#160;&#160; &#160;&#160; &#160;&#160; &#160;&#160; &#160;vref + = Vdd = 5V.
--------------------------------------------------------------------------------
&#160; &#160;&#160; &#160;&#160; &#160;&#160; &#160;&#160;&#160;如果没有加进任何公式的话。。
&#160; &#160;&#160; &#160;&#160; &#160;&#160; &#160;&#160;&#160;当sensor 3V 在 RA0 ,&#160;&#160;LCD = 1024
&#160; &#160;&#160; &#160;&#160; &#160;&#160; &#160;&#160;&#160;当sensor 0V在&#160;&#160;RA0,&#160;&#160;LCD =&#160;&#160;0
&#160; &#160;&#160; &#160;
&#160; &#160;&#160; &#160;&#160; &#160;&#160; &#160;&#160;&#160rogramme code:
&#160; &#160;&#160; &#160;&#160; &#160;&#160; &#160; //////////////////////////////
&#160; &#160;&#160; &#160;&#160; &#160;&#160; &#160;&#160;&#160;ADGO=1;
&#160; &#160;&#160; &#160;&#160; &#160;&#160; &#160; while(ADGO);
&#160; &#160;&#160; &#160;&#160; &#160;&#160; &#160; result= ADRESH;
&#160; &#160;&#160; &#160;&#160; &#160;&#160; &#160;/////////////////////////////
&#160; &#160;
&#160; &#160;&#160; &#160;&#160; &#160;&#160; &#160; 现在我要 3V, LCD = 95%RH
&#160; &#160;&#160; &#160;&#160; &#160;&#160; &#160;&#160; &#160;&#160; &#160;&#160; &#160;&#160; &#160;&#160; &#160;&#160; &#160; 0V, LCD =&#160;&#160;0%RH&#160; &#160;&#160; &#160;&#160; &#160;&#160; &#160;

&#160; &#160;&#160; &#160;&#160; &#160;&#160; &#160; 因为我的sensor output在 0 到 3的范围,所以:
&#160; &#160;&#160; &#160;&#160; &#160;&#160; &#160; 3V = 1024 bit
&#160; &#160;&#160; &#160;&#160; &#160;&#160; &#160;(1V = 341.33 或者 1bit = 0.002929&#160;&#160;= 2.929mV)
&#160; &#160;&#160; &#160;&#160; &#160;&#160; &#160;
&#160; &#160;&#160; &#160;&#160; &#160;&#160; &#160;3V = 95%RH
&#160; &#160;&#160; &#160;&#160; &#160;&#160;&#160;(1V = 31.67%RH 或者 1%RH = 0.03157V
&#160; &#160;
&#160; &#160;&#160; &#160;&#160; &#160;&#160; &#160;假设 我们的ADC result是1024。
&#160; &#160;&#160; &#160;&#160; &#160;&#160; &#160;我们用这个公式:
&#160; &#160;&#160; &#160;&#160; &#160;&#160; &#160;(1024 * 2.929mV * 31.67) = 94.9877
&#160; &#160;&#160; &#160;&#160; &#160;&#160;&#160;
&#160; &#160;&#160; &#160;&#160; &#160;&#160; &#160;那么在LCD我们将会看到 94.98

&#160; &#160;&#160; &#160;&#160; &#160;&#160; &#160;////////////////////////
&#160; &#160;&#160; &#160;&#160; &#160;&#160; &#160;programme;
&#160; &#160;&#160; &#160;&#160; &#160;&#160; &#160; ADGO=1;
&#160; &#160;&#160; &#160;&#160; &#160;&#160; &#160; while(ADGO);
&#160; &#160;&#160; &#160;&#160; &#160;&#160; &#160; resultA= ADRESH;
&#160; &#160;&#160; &#160;&#160; &#160;&#160; &#160; resultB= resultA * 0.002929 * 31.67;&#160; &#160;&#160; &#160;&#160; &#160;&#160; &#160;
&#160; &#160;&#160; &#160;&#160; &#160;&#160; &#160;/////////////////////////////
&#160; &#160;&#160; &#160;&#160; &#160;&#160; &#160;&#160;&#160;
&#160; &#160;&#160; &#160;&#160; &#160;&#160; &#160;请问这样的算法对吗???
&#160; &#160;&#160; &#160;&#160; &#160;&#160; &#160;究竟我应该放sensor的output range (0V -3V)在我的公式
&#160; &#160;&#160; &#160;&#160; &#160;&#160; &#160;还是应该放 voltage reference 5 V 在公式上呢?
&#160; &#160;&#160; &#160;&#160; &#160;&#160; &#160;因为看了“pic大大”关于 LM35 的算法后,发觉他用
&#160; &#160;&#160; &#160;&#160; &#160;&#160; &#160;5V来除1024。但是,根据我的讲师,他说我们因该拿
&#160; &#160;&#160; &#160;&#160; &#160;&#160; &#160;sensor 的output votlage range 除 1024。

&#160; &#160;&#160; &#160;&#160; &#160;&#160; &#160;所以希望大家可以提供些意见或者例子让我或者其他不明
&#160; &#160;&#160; &#160;&#160; &#160;&#160; &#160;的朋友们参考。。

[ 本帖最后由 yeh85 于 2-3-2009 04:12 PM 编辑 ]

评分

参与人数 1积分 +15 收起 理由
pic + 15 有清楚交代来龙去脉。

查看全部评分

回复

使用道具 举报

发表于 2-3-2009 06:01 PM | 显示全部楼层
原帖由 yeh85 于 2-3-2009 04:06 PM 发表
  请问这样的算法对吗???
            究竟我应该放sensor的output range (0V -3V)在我的公式
            还是应该放 voltage reference 5 V 在公式上呢?
            因为看了“pic大大”关于 LM35 的算法后,发觉他用
            5V来除1024。但是,根据我的讲师,他说我们因该拿
            sensor 的output votlage range 除 1024。

很抱歉, 你的讲师恐怕有错。是用5v。
除非你有接3V的参考电压在RA3 Vref, 程序里有开启 External Vref, 那么你才可以用3V = 1024。
回复

使用道具 举报

发表于 2-3-2009 06:10 PM | 显示全部楼层
补充一下。应该是 (Vref+   -   Vref-)/ 1024 吧。当你的程序设置 Vref+ = VDD, Vref- = VSS 时,那就是 5V / 1024 了。
回复

使用道具 举报


ADVERTISEMENT

发表于 2-3-2009 06:57 PM | 显示全部楼层
原帖由 waiweng83 于 2-3-2009 06:10 PM 发表
补充一下。应该是 (Vref+   -   Vref-)/ 1024 吧。当你的程序设置 Vref+ = VDD, Vref- = VSS 时,那就是 5V / 1024 了。


对。
不过很多时候没用到vref.
0-1023是0-5v而已。也就是pic大大多讲的case
回复

使用道具 举报

发表于 2-3-2009 10:46 PM | 显示全部楼层
噢....原来如此。。。。!
酱我明白了
就是我应该拿 5V/1024 才对。。幸好及时发现错误。。谢谢大家。。!!

还有一个关于Vref+的问题想要问清楚。!究竟Vref+是用在什么情况的呢??
因为很少有电路会接去Vref+,通常我所见就只有温度感应电路,他的功能是在于讯号加强还是调整温度呢??
回复

使用道具 举报

发表于 3-3-2009 04:08 PM | 显示全部楼层
明白了。。!!!

但是我应该不会接3V去Vref..
因为会影响其他的sensor。!
唯一能做的就只是在程序上写出公式来计算。。。!!
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 注册

本版积分规则

 

ADVERTISEMENT



ADVERTISEMENT



ADVERTISEMENT

ADVERTISEMENT


版权所有 © 1996-2023 Cari Internet Sdn Bhd (483575-W)|IPSERVERONE 提供云主机|广告刊登|关于我们|私隐权|免控|投诉|联络|脸书|佳礼资讯网

GMT+8, 5-1-2025 11:12 AM , Processed in 0.152343 second(s), 29 queries , Gzip On.

Powered by Discuz! X3.4

Copyright © 2001-2021, Tencent Cloud.

快速回复 返回顶部 返回列表