原创 AVR学习日志(四十九)—学习使用单片机自带的ADC

2010-11-4 16:38 4463 7 9 分类: MCU/ 嵌入式

        


        由于ATmega8515没有自带的ADC所以就换块单片机—Atmega16,这款单片机拥有8路10位的ADC,10位的精度应该可以满足日常的需求了。设计ADC硬件电路时一定要注意参考电压的设计,如果参考系都不准确,坐标怎么能准确。涉及到ADC的寄存器主要有ADC多工选择寄存器—ADMUX,它主要设置参考电压,转换结果对齐方式及通道选择;ADC控制和状态寄存器A—ADCSRA,它主要是设置ADC转换开始,ADC中断标志及预分频器的选择等等;ADC数据寄存器—ADCL及ADCH主要是存放转换结果的,因为它是10位的ADC所以一定要注意转换结果的对齐方式;还有一个寄存器就是特殊功能IO寄存器—SFIOR,它主要是设置ADC自动触发源的,懒猫用的是连续转换模式,所以就是不用管它了。


         懒猫比较懒今天就搭建一个简单的电路来学一下单片机内部的ADC了,说一下这个测试电路,主要用到两路ADC0与ADC1,然后把两路转换的结果用数码管显示出来,本来在B口还接了两个灯,想着哪个通道转换就哪个灯亮,可以转换速度太快了(数据手册上说的是转换时间为65-260us),所以看起来两个灯一直都在亮,而懒猫也没有写什么控制条件,最后懒猫干脆就把两个灯阉割掉了。下面是整体电路图:(参看附件)


        硬件说完了,说一下软件,软件不是太难,主要就是寄存器的配置,还有就是数码显示,用的是八位共阳极数码管,显示精度是两位。如果你好是刚学单片机,建议你一定要好好看看数据手册,不然再简单的东东也容易出错哦。好了,还是把源程序贴出来吧:


/**************************************************************************


//文件名称:ADC_TEST.c


//功    能:学习使用单片机自带的ADC


//作    者:懒猫爱飞


//建立日期:2010.11.03


//备    注:MCU-ATmega16 开发环境-winavr100110  Crystal-8MHz


**************************************************************************/


#include <avr/io.h>


#include <inttypes.h> //关于数据类型的一些定义


#include <stdint.h>    //同样是一些数据类型的定义


#include <avr/interrupt.h>


#include <util/delay.h>


 


//#difine LED_ON(N) PORTB &= ~_BV(N)


 


//共阴极数码管显示码0-9黑屏


const uint8_t Neg_Code[] =


{


0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0x00


};


 


//共阳极数码管显示码0-9黑屏


const uint8_t Pos_Code[] =


{


0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90,0xff 


};


 


//显示缓存,显示两位小数,每路有效数字三位 即X.XX X.XX


uint8_t Dis_Buf[] = {0,0,0,10,0,0,0,10};


/**************************************************************************


//函数名称:void port_init(void)


//功    能:端口初始化


//入口参数:NULL


//出口参数:NULL


//备    注:NULL


**************************************************************************/


void port_init(void)


{


DDRA  = 0xfc; //ADC输入


PORTA = 0x00; //


 


DDRB  = 0x03; //接两个LED灯


PORTB = 0x03; //初始化时关掉灯


 


DDRC  = 0xff;  //C口作输出口,向数码管中送数据


PORTC = 0x00;



DDRD  = 0xff;  //D口作输出口,控制数码管位数


PORTD = 0x00; 


}


 


/**************************************************************************


//函数名称:void adc_convert(int8_t N)


//功    能:对N通道进行ADC转换


//入口参数:N


//出口参数:NULL


//备    注:NULL


**************************************************************************/


void adc_convert(uint8_t N)


{


uint16_t Result = 0;



//一定要在ADSC置位后,再选择通道,否则会出错的


ADCSRA = _BV(ADEN)|_BV(ADSC)|_BV(ADATE)|_BV(ADPS2)|_BV(ADPS1);


ADMUX = N;    //ADC通道选择


 


//PORTB &= ~_BV(N);转换时间太快,通道切换时肉眼是分辨不出来,所以灯一直亮


 


//读取转换结果,并转换为电压值


Result = (uint16_t)((ADCL+(ADCH<<8))*500.0/1023.0);


 


//Result = (uint16_t)(ADC*500.0/1023.0);  //这个表达式具有同样的效果



//ADC0结果放入数组0.1.2单元 ADC1的结果放入数组4.5.6中


Dis_Buf[N * 4]   = Result/100;


Dis_Buf[N * 4+1] = Result/10%10;


Dis_Buf[N * 4+2] = Result%10;


 


ADCSRA = 0; //转换完完毕,关闭ADC


 


}


 


/**************************************************************************


//函数名称:int main(void)


//功    能:主程序


//入口参数:NULL


//出口参数:NULL


//备    注:NULL


**************************************************************************/


int main(void)


{


uint8_t i = 0;


port_init();


ADCSRA = _BV(ADEN)|_BV(ADSC)|_BV(ADATE)|_BV(ADPS2)|_BV(ADPS1);


 


//_delay_ms(1000); //这个可以不用要的


 


while(1)


{



     ADCSRA = 0xe6;


 


     adc_convert(0);  //转换第一通道的数据


 


     //ADCSRA = 0;


     //ADCSRA = 0xe6;


 


     adc_convert(1);  //转换第二通道的数据


 


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


     {


          PORTC = 0xff;   //先关闭一下


          PORTD = _BV(i); //点亮某位数码管


 


          PORTC = Pos_Code[Dis_Buf]; //发送段码


 


          if((i==0)||(i==4))


          {


               PORTC &= 0x7f; //添加小数点


          }


 


          _delay_ms(5);


 


     }


    


     //adc_convert(1);  //转换第二通道的数据


 


     //ADCSRA = 0;


 


}


 


return 0;


}


        程序不是太难,就是简单的测试一下内部自带的ADC转换器,当然ADC转换还有其它模式,如果你也是单片机初学者不妨试一下其它方式,比如中断方式,还有差分输入,可选增益差分输入等。实践出真知,只有多写多练多思考才会有更多的收获^_^


         所有源代码与电路图在附件中,可以自己查看.


 再喊一下口号,鼓励一下自己:


 


每天进步一点点,开心多一点^_^

PARTNER CONTENT

文章评论2条评论)

登录后参与讨论

用户431312 2012-12-18 22:15

好的

用户1588142 2011-4-27 18:49

学习了!!
相关推荐阅读
xucun915_925777961 2013-04-28 11:31
毕业后的五年拉开大家差距的原因在哪里?【转】
  有人工作,有人继续上学,大家千万不要错过这篇文章,能看到这篇文章也是一种幸运,真的受益匪浅,对我有很大启迪,这篇文章将会改变我的一生,真的太好了,希望与有缘人分享,也希望对有缘人有所帮助!...
xucun915_925777961 2013-03-31 20:28
职场大牛精彩总结:职场上,如何做人做事做管理【转】(文/张子阳)
      大道至简,越是根源和基本的问题,道理实际上越简单。关于如何做人、做事、做管理的书很多,我看得不多,但是我觉得这些书更多是侧重技术和实现细节上的,而很少从人的思想和观念去讲。实际...
xucun915_925777961 2013-03-28 14:03
介绍几种优秀的UML工具
统一建模语言(UML是 Unified Modeling Language的缩写)是用来对软件密集系统进行可视化建模的一种语言。UML为面向对象开发系统的产品进行说明、可视化、和编制文档的一种标准语言...
xucun915_925777961 2013-03-27 18:05
IAR EW FOR 8051 修改工程名称的方法
        近段时间一直在搞蓝牙4.0的开发任务,所以用到了IAR编译器,话说IAR编译器用途蛮广,可以编译MSP430,ARM,还有TI的51核芯片,当然,这要不同的版本,我现在用的是for...
xucun915_925777961 2013-03-26 16:40
Cortex-M3学习日志(八)-- TFT实验Part(a)
    自己用的LPC1768的开板带有一块2.4寸的TFT彩色液晶屏,虽然自己工作中还用不过显示屏,但是晚上闲着也是闲着,于是继续玩咱的LPC1768吧。 我的开发板上的液晶屏的用的是SPI接口,当...
xucun915_925777961 2013-03-25 20:48
说说那几款查看源代码的工具
说说那几款查看代码的工具 今天给大家介绍几款单片机工程师所喜欢的几款查看源代码的工具,这几款工具在懒猫的日常工作中可是帮了不少忙。 一、 Source Insight     Source Insig...
EE直播间
更多
我要评论
2
7
关闭 站长推荐上一条 /1 下一条