您当前的位置:五五电子网电子知识单片机-工控设备AVR单片机ATMEGA16 ADC模数转换示例程序 正文
ATMEGA16 ADC模数转换示例程序

ATMEGA16 ADC模数转换示例程序

点击数:7399 次   录入时间:03-04 11:35:38   整理:http://www.55dianzi.com   AVR单片机
      volatile unsigned char ADC_OK; //ADC状态,会在中断服务程序中被修改,须加volatile限定
      unsigned int LED_Volt; //变换后的电压mV
      int LED_Curr; //变换后的电流100uA
      //仿真时在watch窗口,监控这些全局变量。
      unsigned int read_adc(unsigned char adc_input)//查询方式读取ADC单端通道
      {
      ADMUX=(0xc0|adc_input); //adc_input:单端通道 0x00~0x07,0x1E,0x1F
      //0xc0:选择内部2.56V参考电压
      ADCSRA|=(1<<ADSC); //启动AD转换
      loop_until_bit_is_set(ADCSRA,ADIF); //方法1 等待AD转换结束
      // while ((ADCSRA&(1<<ADIF))==0); //写法2 这种写法优化不好
      // loop_until_bit_is_clear(ADCSRA,ADSC); //方法2 检测ADSC=0也行
      ADCSRA|=(1<<ADIF); //写1清除标志位
      return ADC; //ADC=ADCH:ADCL
      }
      int read_adc_diff(unsigned char adc_input)//查询方式读取ADC差分通道
      {
      unsigned int ADC_FIX;
      ADMUX=(0xc0|adc_input); //adc_input:差分通道 0x08~0x1D
      _delay_ms(1); //等待差分增益稳定>125uS
      ADCSRA|=(1<<ADSC);
      loop_until_bit_is_set(ADCSRA,ADIF);
      ADCSRA|=(1<<ADIF);
      //当切换到差分增益通道,由于自动偏移抵消电路需要沉积时间,第一次转换结果准确率很低。用户最好舍弃第一次转换结果。
      ADCSRA|=(1<<ADSC);
      loop_until_bit_is_set(ADCSRA,ADIF);
      ADCSRA|=(1<<ADIF);
      ADC_FIX=ADC;
      //输出结果用2的补码形式表示
      //可正可负 +/-9bit -512~+511
      //即M16差分通道的ADC+输入端的电压可以大于ADC-,也可以小于ADC-。
      //Tiny26就不行,ADC+输入端的电压必须大于或等于ADC-,为+10bit
      if (ADC_FIX>=0x0200) //负数要变换,正数不用
      {
      ADC_FIX|=0xFC00; //变换成16位无符号整数
      }
      return (int)ADC_FIX;
      }
      SIGNAL(SIG_ADC) //ADC中断服务程序
      {
      //硬件自动清除ADIF标志位
      ADC_INT_SE=ADC; //读取结果
      ADC_OK=1;
      }

      int main(void)
      {
      long teMP32;
      ADC_SingleEnded =0;
      ADC_Diff=0;
      ADC_INT_SE=0; 
      //上电默认DDRx=0x00,PORTx=0x00 输入,无上拉电阻
      PORTB=0xFF; //不用的管脚使能内部上拉电阻。
      PORTC=0xFF;
      PORTD=0xFF;
      PORTA=~((1<<in_Single)|(1<<in_Diff_P)|(1<<in_Diff_N)); 
      //作ADC输入时,不可使能内部上拉电阻。
      ADCSRA=(1<<ADEN)|0x06; //使能ADC,时钟64分频 125KHz@8MHz system cLOCk
      sei(); //使能全局中断
      while (1)
      {
      //实测的Vref引脚电压 =2556mV
      ADC_SingleEnded=read_adc(AD_SE_ADC0);
      //查询方式读取ADC0
      temp32=(long)ADC_SingleEnded*Vref;
      LED_Volt=(unsigned int)(temp32/1024);
      ADC_Diff =read_adc_diff(AD_Diff3_2_10x);
      ADC_Diff-=read_adc_diff(AD_Diff2_2_10x);//校准OFFSET
      temp32=(long)ADC_Diff*Vref;
      LED_Curr=(unsigned int)(temp32/(512*10)); //[单位为100uA]
      //查询方式读取ADC3+,ADC2- 10倍放大 max +/-255.6mV
      //10欧姆 1mA=10mV max +/-25.56mA
      //分辨率约0.5mV=50uA,显示取整为100uA单位
      ADCSRA|=(1<<ADIE); //使能ADC中断
      ADMUX=0xC0|AD_SE_ADC0; //单端输入ADC0
      ADC_OK=0; //软件标志清零
      ADCSRA|=(1<<ADSC); //启动AD转换
      while(ADC_OK==0); //等待ADC完成,实际程序中可以运行其它任务
      ADCSRA&=~(1<<ADIE); //禁止ADC中断
      //查询方式和中断方式要注意 ADIF标志位的处理。
      }
      }



上一页  [1] [2] 


本文关键字:程序  AVR单片机单片机-工控设备 - AVR单片机