搜索
bottom↓
回复: 3

求助:ATtiny13A的ADC通道切换问题

[复制链接]

出0入0汤圆

发表于 2015-3-2 15:20:19 | 显示全部楼层 |阅读模式
需要用两个ADC通道采样不同的电压,使用了16倍过采样来得到12位的数据。现在出的状况是不管先采样哪个通道,开始的通道正确,再采样另一个通道的数据总是错的,值会受到前一个通道的影响。
用AVR比较少,对比数据手册和示例代码没找到原因。代码如下求指教:
  1. typedef enum {
  2.     ADC_CH_TEMP,
  3.     ADC_CH_LIGHT
  4. } ADC_Channel_t;

  5. // Read ADC with oversampling to get 12bits result
  6. static uint16_t ADC_Read(ADC_Channel_t ch)
  7. {
  8.     uint8_t i;
  9.     uint8_t ADC_tempL;
  10.     uint16_t ADC_var;

  11.     if (ch == ADC_CH_TEMP) {
  12.         // ADC2, VCC as reference
  13.         ADMUX = (0 << REFS0) | (1 << MUX1) | (0 << MUX0);
  14.     } else {
  15.         // ADC3, Internal reference (1.1V)
  16.         ADMUX = (1 << REFS0) | (1 << MUX1) | (1 << MUX0);
  17.     }

  18.     // Enable the ADC, 1.2MHz / 8 = 150kHz (Conversion time: 86uS)
  19.     ADCSRA = (1 << ADEN) | (1 << ADPS1) | (1 << ADPS0);
  20.     ADCSRB = 0x00;

  21.     // do a dummy readout first
  22.     ADCSRA |= (1 << ADSC);      // do single conversion
  23.     while (!(ADCSRA & (1 << ADIF)));   // wait for conversion done, ADIF flag active
  24.     ADCSRA &= ~(1 << ADIF);     // clear ADIF flag

  25.     ADC_var = 2;
  26.     // do the ADC conversion 16 times for oversampling
  27.     for (i = 16; i != 0; i--) {
  28.         ADCSRA |= (1 << ADSC);      // do single conversion
  29.         while (!(ADCSRA & (1 << ADIF)));    // wait for conversion done, ADIF flag active
  30.         ADCSRA &= ~(1 << ADIF);     // clear ADIF flag
  31.         ADC_tempL = ADCL;           // read out ADCL register
  32.         ADC_var += (ADCH << 8) | ADC_tempL; // accumulate result
  33.     }
  34.     ADC_var >>= 2;   // shift right to get extra 2 bits

  35.     ADCSRA &= ~(1 << ADEN);     // disable the ADC

  36.     return ADC_var;
  37. }
复制代码

阿莫论坛20周年了!感谢大家的支持与爱护!!

曾经有一段真挚的爱情摆在我的面前,我没有珍惜,现在想起来,还好我没有珍惜……

出0入0汤圆

发表于 2015-3-2 16:52:54 | 显示全部楼层
本帖最后由 qq729101414 于 2015-3-2 17:04 编辑

呃。。。这个不了解  不过以前飞思卡尔的一款单片机对于AD转换   内部电容放电 有一个开关的。
就是下次采样之前 可以选择先让电容放电。

这个是数据手册关于 Free Running mode 的解释

编辑原因:补充回复。

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有帐号?注册

x

出0入0汤圆

发表于 2015-3-2 17:11:41 | 显示全部楼层
30. ADC_var = 2;       初值为什么不是0 ?

28. 35.   ADIF 不是写0清零,应该是写1清零,看手册。

ADC初始化放在别处,做一次就可以吧,没必要频繁开启、关闭。

出0入0汤圆

 楼主| 发表于 2015-3-2 19:06:00 | 显示全部楼层
zhanan 发表于 2015-3-2 17:11
30. ADC_var = 2;       初值为什么不是0 ?

28. 35.   ADIF 不是写0清零,应该是写1清零,看手册。

问题解决了,非常感谢!是清标志位的地方疏忽了,改为写1解决问题。
另外2是用来“四舍五入”,因为后面除以了4。程序只是偶尔用到ADC,考虑到功耗用完就关了。
回帖提示: 反政府言论将被立即封锁ID 在按“提交”前,请自问一下:我这样表达会给举报吗,会给自己惹麻烦吗? 另外:尽量不要使用Mark、顶等没有意义的回复。不得大量使用大字体和彩色字。【本论坛不允许直接上传手机拍摄图片,浪费大家下载带宽和论坛服务器空间,请压缩后(图片小于1兆)才上传。压缩方法可以在微信里面发给自己(不要勾选“原图),然后下载,就能得到压缩后的图片。注意:要连续压缩2次才能满足要求!!】。另外,手机版只能上传图片,要上传附件需要切换到电脑版(不需要使用电脑,手机上切换到电脑版就行,页面底部)。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

手机版|Archiver|amobbs.com 阿莫电子技术论坛 ( 粤ICP备2022115958号, 版权所有:东莞阿莫电子贸易商行 创办于2004年 (公安交互式论坛备案:44190002001997 ) )

GMT+8, 2024-8-26 03:51

© Since 2004 www.amobbs.com, 原www.ourdev.cn, 原www.ouravr.com

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