搜索
bottom↓
回复: 11

adc實驗!

[复制链接]

出0入0汤圆

发表于 2005-4-19 12:31:02 | 显示全部楼层 |阅读模式
// icc 6.31a , atmage16, 4m osc

#include <iom16v.h>

#include <macros.h>

#include <stdio.h>



#define uchar unsigned char

#define uint unsigned int



const uchar disp_table[16] = {0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71};

uchar led_data[4];

uint Adc_data;



void disp_led(void);

void delay_1ms(void);

void delay_nms(uint n);





void main(void)

{   

    uint j;

       

          DDRB = 0x03;   

        PORTB = 0x03;

       

          DDRC = 0xff;  

          PORTC = 0xff;

         

        DDRD = 0xff;

          PORTD = 0xff;

               

        DDRA = 0x00;

       

    CLI();

   

        WDR(); // 使用看門狗      

    WDTCR = 0x0F;

    ADCSRA = 0x00;   

    ADMUX = (1<<REFS0)|(1<<MUX1)|(1<<MUX0); // 用avcc為參考電壓, 使用pa3,即adc3為ad輸入,

    ADCSRA = (1<<ADEN)|(1<<ADSC)|(1<<ADIE)|(1<<ADPS2)|(1<<ADPS1); // adc中斷許可,連續方式, 64分頻

        SEI();      



          PORTB = 0B00000000;

    delay_nms(100);

          while(1)

     {      

                 PORTB = 0B00000010;

                           delay_1ms();



                         Adc_data = 49*(ADCH*256+ADCL); // 計算adc的值, 其中49是用vcc 5.02/1023得出來

                         

                         j = Adc_data/1000; // 過壓檢查

                          

                         if(j>48)

                         {

                           PORTB = ~BIT(0)|~BIT(1);

                         }

                         

                         disp_led(); // 顯示adc數值

                         WDR();         

                         PORTB = 0B00000011;

    }

}





void disp_led(void)

{

    uchar i;



        led_data[0] = Adc_data/10000;

        led_data[1] = Adc_data/1000%10;

        led_data[2] = Adc_data/100%10;

        led_data[3] = Adc_data/10%10;



        for (i=0;i<4;i++)

        {

      PORTC = disp_table[led_data];

          PORTD = ~BIT(i);

          delay_nms(5);

          PORTD = 0xff;

        }

}



void delay_1ms(void)

{

  uint i;

  for (i=0;i<550;i++);

  WDR();

}



void delay_nms(uint n)

{

  uint i;

  for (i=0;i<n;i++)

  delay_1ms();

}



#pragma interrupt_handler adc_isr:iv_ADC   

void adc_isr(void)

{

ADMUX = (1<<REFS0)|(1<<MUX1)|(1<<MUX0);

ADCSRA |= (1<<ADSC);

}



實驗板接線:

JU7的AREF短接

PC0-PC7 ---------> JC1.a-JC1.p

PD0-PD3 ---------> JC2.1-JC2.4

PA3     ---------> JD1

PB0-PB1 ---------> JA.1-JA.2



調整 wd1 可觀察到數碼管的數值的變化

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

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

出0入0汤圆

发表于 2005-5-23 20:20:22 | 显示全部楼层
正想做这方面的试验,谢谢.
头像被屏蔽

出0入0汤圆

发表于 2005-5-27 02:38:08 | 显示全部楼层
提示: 作者被禁止或删除 内容自动屏蔽

出0入0汤圆

发表于 2005-6-2 21:30:07 | 显示全部楼层
谢谢!



有一个问题请教一下:   JU7的AVcc是否也需要短接?



在马老师的M128手册的P177上是这样讲的:   "AVcc,AREF外部并接电容"

出0入0汤圆

 楼主| 发表于 2005-6-3 12:37:19 | 显示全部楼层
JU7的AVcc是否也需要短接?

不要的!!

出0入0汤圆

发表于 2005-6-3 14:14:32 | 显示全部楼层
这样理解可不可以



ADC参考电源有3种选择:



1. 选择内部参考源AVcc, M16内部把AVcc引脚和AREF引脚短接, 再把AREF引脚接电容抗干扰

2. 选择内部参考源2.56v, M16内部把2.56v和AREF引脚短接, 再把AREF引脚接电容抗干扰

3. 选择外部参考电源, 直接在AREF引脚接外部电源

出0入0汤圆

 楼主| 发表于 2005-6-3 14:48:49 | 显示全部楼层
完全正確!

出0入0汤圆

发表于 2005-7-29 09:18:54 | 显示全部楼层
请教能否给出6个通道循环检测?

出0入0汤圆

发表于 2005-8-1 05:03:18 | 显示全部楼层
注意:理解不完全对。



AVcc不是参考电源!它是提供给A/D口I/O的工作电源。为了提高AVR A/D的稳定,AVR有两个工作电压的引脚,Vcc和AVcc。Vcc为数字供电,提供芯片内大部分电路的电源。而AVcc为模拟供电,仅提供A/D口的I/O部分电源。



如果不使用A/D转换功能,AVcc和Vcc可同时接在系统电源上。



使用A/D转换功能,电源经过一个电感(或小电阻)后到AVcc,AVcc引脚(越近越好)接电容对地,这样构成LC滤波电路,滤掉一些数字高频噪声,使模拟电源AVcc“干净”,提高A/D的稳定性。因此,只要使用A/D,AVcc引脚就应该并接电容对地(不使用A/D,并接电容对地也没有坏处)。



下面是对的:

ADC参考电源有3种选择:



1. 选择内部参考源AVcc, M16内部把AVcc引脚和AREF引脚短接, 再把AREF引脚接电容抗干扰。(这是指,使用模拟电源AVcc作为A/D的参考电源。)

2. 选择内部参考源2.56v, M16内部把2.56v和AREF引脚短接, 再把AREF引脚接电容抗干扰

3. 选择外部参考电源, 直接在AREF引脚接外部(参考)电源。( 再把AREF引脚接电容抗干扰也没坏处)。

出0入0汤圆

发表于 2005-8-3 10:05:21 | 显示全部楼层
谢谢马老师讲解

出0入0汤圆

发表于 2005-8-12 21:53:32 | 显示全部楼层
DMUX = (1<<REFS0)|(1<<MUX1)|(1<<MUX0); // 用avcc為參考電壓, 使用pa3,即adc3為ad輸入,  

    ADCSRA = (1<<ADEN)|(1<<ADSC)|(1<<ADIE)|(1<<ADPS2)|(1<<ADPS1); // adc中斷許可,連續方式, 64分頻

   SEI();        



     PORTB = 0B00000000;

    delay_nms(100);  

     



我想问一下的就是这儿为什么要加一个delay_nms(100);什么理由

另外,我在书上看到这样一种表示方法,

void main ()

{

  PORTA=0;   //设置PA口为输入,无上拉

  DDRA=0;

  PORTB=0xff;

  DDRB=0xff;

  ADMUX=0x00;  //选择0通道

  ADCSR=0x86;  //采用单次转换模式,和64分频

  ADCSR|=BIT(ADSC);  //启动一次哑转换

  SREG=0x80;         //开中断

  ADCSR|=BIT(ADSC);    //启动一次转换

  while(1)             //等待中断

{

    ;

  }

}

void ad_handler(void)  //中断程序

{

  addata=ADCH*256+ADCL;

   ......

  ADCSR|=BIT(ADSC);

}



我想问的是在ADC转换的时候有没有必要用一次空的转换,即该书说的哑转换

有的地方没用,但强调了说转换要的时间是较长的,需要先写好转换的条件后,

在开中断,这样,在中断一打开的时候,就可以进行ADC转换了。

他们谁更有道理?

出0入0汤圆

发表于 2007-11-29 16:36:56 | 显示全部楼层
收一下
回帖提示: 反政府言论将被立即封锁ID 在按“提交”前,请自问一下:我这样表达会给举报吗,会给自己惹麻烦吗? 另外:尽量不要使用Mark、顶等没有意义的回复。不得大量使用大字体和彩色字。【本论坛不允许直接上传手机拍摄图片,浪费大家下载带宽和论坛服务器空间,请压缩后(图片小于1兆)才上传。压缩方法可以在微信里面发给自己(不要勾选“原图),然后下载,就能得到压缩后的图片。注意:要连续压缩2次才能满足要求!!】。另外,手机版只能上传图片,要上传附件需要切换到电脑版(不需要使用电脑,手机上切换到电脑版就行,页面底部)。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

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

GMT+8, 2024-8-25 11:27

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

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