140 likes | 330 Views
第七章 AVR 单片机 A/D 接口及其应用. 1 、 A/D 转换器概述 2 、硬件设计 3 、程序设计. 1 、 A/D 转换器概述. 模数转换通常是指一个将模拟信号转变为数字信号的过程,完成该过程的元件称为模数转换器。通常的模数转换器是一个输入电压信号转换为一个对应的输出数字信号。按照工作原理不同,模数转换器可分为积分型、逐次比较型、并行比较 / 串行比较型、电容阵列逐次比较型及压频变换型等。.
E N D
第七章AVR单片机A/D接口及其应用 1、A/D转换器概述 2、硬件设计 3、程序设计
1、A/D转换器概述 • 模数转换通常是指一个将模拟信号转变为数字信号的过程,完成该过程的元件称为模数转换器。通常的模数转换器是一个输入电压信号转换为一个对应的输出数字信号。按照工作原理不同,模数转换器可分为积分型、逐次比较型、并行比较/串行比较型、电容阵列逐次比较型及压频变换型等。
积分型AD工作原理是将输入电压转换成时间或频率,然后由定时器/计数器获得数字值。其优点是用简单电路就能获得高分辩率,但缺点是由于转换精度依赖积分时间,因此转换速率极低。积分型AD工作原理是将输入电压转换成时间或频率,然后由定时器/计数器获得数字值。其优点是用简单电路就能获得高分辩率,但缺点是由于转换精度依赖积分时间,因此转换速率极低。 • 逐次比较型A/D转换器由控制逻辑电路、时序产生器、移位寄存器、数模转换器及电压比较器组成。器基本工作原理是将输入模拟信号与不同的参考电压作多次比较,使转换所得的数字量在数值上逐次逼近输入模拟量对应值,即:从最高位开始,顺序地对每一位将输入电压与内置D/A转换器输入进行比较,经n次比较而输出数字值。其优点是速度较高、功耗低。
并行比较型A/D采用 多个比较器,仅作一次比较而实行转换,又称FLash(快速)型。由于转换速率极高,n位的转换需要(2n-1)个比较器,因此电路规模极大,价格也高,只适用于视频A/D转换器等速度特别高的领域。 • 串行比较型A/D结构上介于并行型和逐次比较型之间,最典型的是由2个n/2位的并行型A/D转换器配合D/A转换器组成,用两次比较实行转换,所以称为Half Flash(半快速)型。
2、硬件设计 如图是可调电阻的原理图。用可调电阻实现AD模数转换功能。通过电阻的变化显示的数据不同。
程序设计 #include <iom16v.h>#include <macros.h>#include "led.h"#include "led.c"#include "GPio.c“ //定义参考电压 #define VREF 3.33
void port_init(void) { DDRA&= 0xEF; PORTA&=0XEF;} //ADC initialize // Conversion time: 112uS void adc_init(void) { ADCSR = 0x00; //disable adc
ADMUX = 0x04; //select adc input 4 ACSR = 0x80; ADCSR = 0xe0; } void init_devices(void){ port_init(); adc_init();} //AD转换,每调用一次函数就转换一次
unsignedint ADChange(void) { unsignedint ADCResult=0; ADCSRA|=(1<<ADSC); //开始转换while(!(ADCSRA&(1<<ADIF))); ADCSRA|=(1<<ADIF); //清除中断标志ADCResult=ADCL; ADCResult+=ADCH<<8; return ADCResult; }
unsignedlong CheckPower(void) { unsignedchar n=6; //需要转换的次数unsignedchar i; unsignedint max=0,min=0; //滤波用unsignedint temp[6]; //保存转换结果unsignedlong tempsum=0; double power; //AD转换得到的电源电压
for(i=0;i<n;i++) { temp[i]=ADChange(); if(i==0) { max=temp[i];min=temp[i]; } if(temp[i]>max) max=temp[i]; if(temp[i]<min) min=temp[i]; }
for(i=0;i<n;i++) { tempsum+=temp[i]; } tempsum=tempsum-max-min; //减轻最大值和最小值return (tempsum>>2);}
void main(void) { int vo=0; unsignedchar temp; init_devices(); Gpio_Init();while(1) { vo=ADChange(); // 37<=vo<=991
if (vo<37) { LED1_OFF; LED2_OFF; LED3_OFF; LED4_OFF; LED5_OFF; }elseif (37<vo&&vo<500) { LED1_ON; LED2_ON; LED3_ON; LED4_OFF; LED5_OFF; }elseif (500<vo&&vo<991) { LED1_ON; LED2_ON; LED3_ON; LED4_ON; LED5_ON; } } }