AVR单片机_实验5:AD转换实验

曾巧文 发布于:2012-4-29 17:54 分类:AVR单片机 标签: 实验 单片机 AVR

AVR单片机_实验5:AD转换实验1 实验目的

通过实验,了解AVR单片机模数转换器的初始化、工作原理,以及AD按键的检测方法和工作原理。

2 实验内容

1、通过AD转换采集PA7(ADC7)引脚上的模拟电压,并将转换值在数码管上显示。参照教材315页的ADC应用实例;

2、将转换结果通过串口发送到PC机,熟悉串口的使用。

3 实验预习要求

仔细阅读ATmega16单片机的数据手册,了解模数转换寄存器的设置P191;参考教材第6章节。

  1. 实验步骤

1、启动ICCAVR,新建工程文件"ADkey.PRJ",新建Adkey.c文件,并将Adkey文件添加到Adkey工程中,并设置project->option->target 下的device configuration 选择ATMega16;

2、 本实验的ADC初始化代码请独立完成,Application Builder直接生成的ADC初始化代码不正确, 本实验板ADC的参考电源请选择AVCCPrescale请选择64,AD键盘所用的AD输入为ADC7通道;参考Mega16 数据手册中203页的ADC相关寄存器介绍和教材315页的范例

 

关于ADC的启动方式一般可选:用定时器触发启动,也可以使用软件启动的方法。

  1. 如果采用定时器触发AD转换,一般选择定时器比较匹配时触发AD转换的方法。例如选用Timer0比较匹配来触发启动AD转化,即当Timer0比较匹配发生时,自动启动AD转换,不需要程序干预,如果Timer0的比较匹配时间为5ms,那么ADC将5ms自动启动一次。此时SFIOR寄存器的ADTS[2:0]需要设为011

 

  1. 采用软件启动AD转换的方式:又称单次转换模式,即每次AD转换的启动都需要程序触发.方法是:程序中置位ADCSRA寄存器中的第六位(ADSC位),便会立即启动一次AD转化; 例如:ADCSRA |= (1 << ADSC); //开始AD转换

 

  1. 关于转换结果的读取,可以用查询方式读取也可以用AD转换完成中断方式读取;
  2. 查询方式读取实例:(注:AD转换结果为左对齐方式)

    unsigned int AD_GetData()

    {

                         //开始AD转换

             //等待转换完成

                     //清零ADC中断标志位    

        return ADC;     //返回ADCH值,只取高8位

    }

然后通过以下方法将ADC转换结果换算为电压值;

adc_v=(unsigned long)ADC*3300/1024;

通过以下方法将电压值刷新到display buffer中

adc_to_disbuffer(adc_v);

 

数码管显示方法采用前几次实验的现实方法,Display函数会自动将display buffer中的内容显示在数码管上。

 

  1. 中断方式读取实例:当ADC转换结束后自动产生中断,在中断中将转换结果保存起来

3、参考提供的实例代码实现如下功能:1、将AD转换结果在4位数码管上显示;2、通过AD转换结果反过来判断哪个键按下。最后选择【Project】->【Rebuild All】编译工程,通过PROGISP程序下载程序到单片机,观察实验现象。

 

 

实验五 AD转换应用试验

1 实验目的

通过实验,了解AVR单片机模数转换器的初始化、工作原理,以及AD按键的检测方法和工作原理,了解串口的使用方法。

2 实验内容

  1. 通过AD转换采集PA7(ADC7)引脚上的模拟电压,并将转换值在数码管上显示。
  2. 将转换结果通过串口发送到PC机,熟悉串口的使用。

3 首先按照如下要求初始化ADC模块,完成ADC初始化函数,并采用查询方式每隔10ms采集一次PA7上的AD值,设计AD_GetData()函数,获取ADC的转换结果。注:通过定时中断设计10ms的时标,在主循环中每10ms调用一次AD_GetData()获取ADC转换结果;

void adc_init(void){

ADMUX = ; //1、参考电压采用Avcc;2、转换结果右对齐;3采集PA7的电压

ADCSR = ; //1、使能ADC;2、ADC时钟选128分频

 

void adc_init(void)
{
        ADMUX &=~(1 << 7);//选择VCC参考电源
		ADMUX |=(1 << 6);
		ADMUX &= ~31; //选择第七条通道
		ADMUX |= 0x07; 
		ADCSRA |= (1 << 7); //使能ADC
		ADCSRA &= ~7;//	选择64分频
		ADCSRA |= 6;
		 
}	 

 

  1. 实现如下功能:将ADC转换结果换算为电压值(以mv为单位,见实验说明),并显示在数码管上,例如检测到的电压为2.5V则数码管上显示2500,表示2500mv。

     

    unsigned int AD_GetData()
    {
    	   
    		 ADC_START(); 				//开始AD转换
    		// ADCSRA |= (1 << 6);
    		 while(!(ADCSRA & (1 << 4)))    //等待转换完成
    		
    		 ADCSRA &= ~(1 << 4);
    		         //清零ADC中断标志位	
    		AD_result = (ADCH <<8)|ADCL;
    	    ADC = AD_result;
    		 
    		return ADC;        	//返回ADCH值,只取高8位
    }

    5     思考题:实验板的AD按键电路的如何实现? 写出核心代码或说明设计思路。

     

    //ICC-AVR application builder : 2012-4-26 13:07:08
    // Target : M16
    // Crystal: 4.0000Mhz
    
    #include <iom16v.h>
    #include <macros.h>
    
    unsigned char led_7[14]={0xc0,0xF9,0xA4,0xB0,0x99,0x92,0x82,0xF8,
    		 	  			0x80, 0x90};
    unsigned char n[4]={0x00, 0x00, 0x00, 0x00};
    unsigned char flag_10ms= 0,j=4,i = 0;
    void port_init(void)
    {
     PORTA = 0x01;
     DDRA  = 0x01;
     PORTB = 0x00;
     DDRB  = 0x03;
     PORTC = 0x00; //m103 output only
     DDRC  = 0x00;
     PORTD = 0x00;
     DDRD  = 0xF0;
    }
    
    //TIMER0 initialize - prescale:64
    // WGM: CTC
    // desired value: 1KHz
    // actual value:  0.992KHz (-0.8%)
    void timer0_init(void)
    {
     TCCR0 = 0x00; //stop
     TCNT0 = 0xC2; //set count
     OCR0  = 0x3E;  //set compare
     TCCR0 = 0x0B; //start timer
    }
    
    #pragma interrupt_handler timer0_comp_isr:iv_TIM0_COMP
    void timer0_comp_isr(void)
    {
     //compare occured TCNT0=OCR0
        PORTD |= 0xF0;
        HC595_Send(led_7[n[j-4]]);
        PORTD &= ~(1 << j);
        if(++j>7){j = 4;}
        i++;
        if(i >= 10){ 
           flag_10ms = 1;
    	   i = 0;
        }
    }
    
    //call this routine to initialize all peripherals
    void init_devices(void)
    {
     //stop errant interrupts until set up
     CLI(); //disable all interrupts
     port_init();
     timer0_init();
    
     MCUCR = 0x00;
     GICR  = 0x00;
     TIMSK = 0x02; //timer interrupt sources
     SEI(); //re-enable interrupts
     //all peripherals are now initialized
    }
    void HC595_Send(unsigned char data)
    {
       unsigned char i;
       for(i=0;i<8;i++)
       {
    	  if(data & (1<<(7-i)))
    	  {PORTA |= (1<<0);}
    	  else
    	  {PORTA &= ~(1<<0);}
    	  
    	  PORTB &= ~(1<<1);
    	  PORTB |= (1<<1);	
       }
    	PORTB &= ~(1<<0);
    	PORTB |= (1<<0);
    }
    #define ADC_START() ADCSRA |= (1 << 6)
    #define ADC (*(volatile unsigned int*)0x24)
    //#define ADCL (*(volatile unsigned int*)0x24)
    //#define ADCH (*(volatile unsigned int*)0x25)
    unsigned int AD_result;
    unsigned int AD_GetData()
    {
    	   
    		 ADC_START(); 				//开始AD转换
    		// ADCSRA |= (1 << 6);
    		 while(!(ADCSRA & (1 << 4)))    //等待转换完成
    		
    		 ADCSRA &= ~(1 << 4);
    		         //清零ADC中断标志位	
    		AD_result = (ADCH <<8)|ADCL;
    	    ADC = AD_result;
    		 
    		return ADC;        	//返回ADCH值,只取高8位
    }
      
    
    void adc_init(void)
    {
            ADMUX &=~(1 << 7);//选择VCC参考电源
    		ADMUX |=(1 << 6);
    		ADMUX &= ~31; //选择第七条通道
    		ADMUX |= 0x07; 
    		ADCSRA |= (1 << 7); //使能ADC
    		ADCSRA &= ~7;//	选择64分频
    		ADCSRA |= 6;
    		 
    }	 
    	 
    void adc_to_disbuffer(unsigned int adc)
    {
        unsigned char i;
    	for(i = 0; i <= 3; i++)
    	{
    	     n[i] = adc %10;
    		 adc /= 10;
    	}
    }
    	 
    void main()
    {
         unsigned int adc_v;
    	 unsigned int adc;
         adc_init();
    	 init_devices();
    
         while(1)
    	 {
              //然后通过以下方法将ADC转换结果换算为电压值;
    	     if(flag_10ms == 1){
    	           flag_10ms = 0;
    		       adc = AD_GetData();
    	       }
             adc_v=(unsigned long)adc*3300/1024;    
       // 通过以下方法将电压值刷新到display buffer中
             adc_to_disbuffer(adc_v);
        }
        
    		
    }

版权所有:《曾巧文博客-关注互联网IT技术,记录生活点滴》 => 《AVR单片机_实验5:AD转换实验
本文地址://qiaowen.net/post-1187.html
除非注明,文章均为 《曾巧文博客-关注互联网IT技术,记录生活点滴》 原创,欢迎转载!转载请注明本文地址,谢谢。

有 6236 人浏览,获得评论 0 条

发表评论:

Powered by emlog 粤ICP备12040901号

>>本作品采用-知识共享署名-非商业-禁止演绎-协议-进行许可 |站点地图 | | | | 开放分类目录 |