Documentos de Académico
Documentos de Profesional
Documentos de Cultura
El Modulo de Conversión Analógica A Digital
El Modulo de Conversión Analógica A Digital
Analgica a Digital.
Para los Microcontroladores PIC16F y PIC18F
08/09/2010
http://www.micros-designs.com.ar
Autor: Alejandro Casanova.
Alias: Suky.
Edito: Armando Prez. (M@NDO31)
Algunos PICs de la familia PIC16F y todos los de las familias PIC18F tienen incorporado el mdulo
de conversin analgica/digital de 10 bits (Exceptuando algunos de la familia PIC18F que son mdulos
de 12 bits).
Este modulo comprende de varias entradas analgicas multiplexadas (El nmero depende del PIC), un
capacitor de muestreo y retencin, y un convertidor analgico/digital de aproximaciones sucesivas.
Todo convertidor ADC requiere voltajes de referencia que determina el valor de mnima escala (Vref-)
y el de plena escala (Vref+), de manera que la conversin de un va lor de voltaje analgico Vin en el
rango de Vref- a Vref+ producir un valor equivalente binario en el rango de 0 a 2n donde n e s la
resolucin del convertidor (n= 10). Estas tensiones de referencias pueden seleccionarse por software,
entre VDD y VSS o entradas positivas colocadas en los pines RA2/Vref- y RA3/Vref+ en donde se
deben de cumplir ciertos requisitos contemplados en las caractersticas elctricas del convertidor ADC
del PIC utilizado, por ejemplo para un 16F877A:
El modulo ADC est controlado por medio de los registros ADCONx en donde se puede seleccionar
que pines sern usados como entradas analgicas, determinar el reloj para la conversin, seleccionar
canal de conversin, poner en funcionamiento la conversin, etc. Luego tenemos 2 r egistros ms
ADRESH y ADRESL en donde se guarda el resultado de la conversin. El convertidor A/D tiene la
caracterstica de poder funcionar mientras que el dispositivo est en modo sleep. Al funcionar en sleep,
el reloj de conversin A/D debe derivar del oscilador interno RC A/D.
Registros ADCONx.
16F87XA:
ADCON0:
PIC18F2455/2550/4450/4550:
ADCON0:
ADCON2:
El clculo detallado puede observarse en el datasheet del PIC utilizado, a modo de ejemplo vemos que
en un 16F87XA el mnimo tiempo de adquisicin es de 19.72us el cual debe ser generado por software
cada vez que se seleccione un canal (Cambiando). En cambio para los PIC18F2455/2550/4455/4550 el
tiempo mnimo de adquisicin se reduce a 2.45us, los cuales podemos configurarlo por hardware
dependiendo del reloj de conversin seleccionado. Cuando se selecciona ACQT2:ACQT0: 00 la demora
se debe generar por software.
Seleccin del Reloj de Conversin A/D.
El tiempo por bit de la conversin A/D se define como TAD. La conversin A/D necesita un mnimo
de 12TAD para la serie 16F o 11TAD para la serie 18F por 10 bits de conversin.
La fuente de reloj A/D de la conversin es s eleccionable por software. Hay siete opciones posibles
para el TAD:
2 TOSC
4 TOSC
8 TOSC
16 TOSC
32 TOSC
64 TOSC
Oscilador interno RC
Para las conversiones A/D correctas, el reloj de conversin A/D (TAD) debe ser tan corto como sea
posible pero mayor que un mnimo TAD (para ms informacin vase el datasheet del PIC utilizado)
dado por ejemplo para la serie 16F en 1.6us y para la serie 18F en 0.7us.
Proceso de Conversin Analgico/Digital.
Pasos a seguir:
1. Configurar el mdulo A/D.
a. Configurar los pines analgicos y tensiones de referencia.
b. Seleccionar el reloj de conversin.
c. Serie 18F: Seleccionar el tiempo de adquisicin.
d. Habilitar mdulo de conversin A/D.
; NOTA:
; Oscilador utilizado 4MHz.; ************************************************
ByteAlto
equ 0x20
; Registro para guardar Byte alto de la conversion.ByteBajo
equ 0x21
; Registro para guardar Byte bajo de la conversin.Contador
equ 0x22
; registro utilizado en demora.; ************************************************
org
bsf
movlw
movwf
0x00
STATUS,RP0 ; Banco 1
0x8E
; Justificado a la derecha, Fosc/8, RA0 analgico, VDD, VSS.ADCON1
bcf
movlw
movwf
call
bsf
Espera
btfsc
goto
movf
movwf
bsf
movf
movwf
bcf
bsf
Bucle
goto
STATUS,RP0
0x41
ADCON0
Demora_20us
ADCON0,GO
; Banco 0
; Fosc/8, Canal 0, mdulo habilitado.-
ADCON0,GO
Espera
ADRESH,W
ByteAlto
STATUS,RP0
ADRESL,W
ByteBajo
STATUS,RP0
ADCON0,ADON
; Demora de adquisicin.-
Bucle
CCS:
#include <16F877A.h>
/* ********************* Conversor A/D de 8 bits *************************** */
#device adc=10
#FUSES NOWDT, XT, PUT, NOPROTECT, NODEBUG, NOBROWNOUT, NOLVP, NOCPD, NOWRT
#use delay(clock=4000000)
void main()
{
int16 Conversion;
/* 16F877A.h
#define NO_ANALOGS
#define ALL_ANALOG
#define AN0_AN1_AN2_AN4_AN5_AN6_AN7_VSS_VREF
VRefh=A3
#define AN0_AN1_AN2_AN3_AN4
#define AN0_AN1_AN2_AN4_VSS_VREF
#define AN0_AN1_AN3
#define AN0_AN1_VSS_VREF
7
0
1
// None
// A0 A1 A2 A3 A5 E0 E1 E2
// A0 A1 A2 A5 E0 E1 E2
2
3
4
5
//
//
//
//
A0
A0
A0
A0
A1
A1
A1
A1
A2 A3 A5
A2 A4 VRefh=A3
A3
VRefh=A3
#define AN0_AN1_AN4_AN5_AN6_AN7_VREF_VREF
VRefl=A2
#define AN0_AN1_AN2_AN3_AN4_AN5
#define AN0_AN1_AN2_AN4_AN5_VSS_VREF
#define AN0_AN1_AN4_AN5_VREF_VREF
VRefl=A2
#define AN0_AN1_AN4_VREF_VREF
#define AN0_AN1_VREF_VREF
#define AN0
#define AN0_VREF_VREF
*/
0x08
// A0 A1 A5 E0 E1 E2 VRefh=A3
0x09
0x0A
0x0B
// A0 A1 A2 A3 A5 E0
// A0 A1 A2 A5 E0 VRefh=A3
// A0 A1 A5 E0 VRefh=A3
0x0C
0x0D
0x0E
0x0F
//
//
//
//
A0 A1 A4 VRefh=A3 VRefl=A2
A0 A1 VRefh=A3 VRefl=A2
A0
A0 VRefh=A3 VRefl=A2
setup_adc_ports(AN0);
/* 16F877A.h
#define ADC_OFF
0
#define ADC_CLOCK_DIV_2
0x10000
#define ADC_CLOCK_DIV_4
0x4000
#define ADC_CLOCK_DIV_8
0x0040
#define ADC_CLOCK_DIV_16
0x4040
#define ADC_CLOCK_DIV_32
0x0080
#define ADC_CLOCK_DIV_64
0x4080
#define ADC_CLOCK_INTERNAL 0x00c0
*/
// ADC Off
// Internal 2-6us
setup_adc(ADC_CLOCK_DIV_8);
set_adc_channel(0);
delay_us(20);
Conversion=read_adc();
setup_adc(ADC_OFF);
while(1){ }
}
C18:
#include <p18f2550.h>
#include <adc.h>
#pragma config FOSC = XT_XT, CPUDIV = OSC1_PLL2
void main(void){
unsigned int Conversion;
TRISA=0xFF;
ADCON0=0x01;
//Canal 0, Modulo habilitado.ADCON1=0x0E;
// AN0, Vdd, Vss.ADCON2=0x94;
// Justificado a la derecha, 4Tad, Fosc/4
SetChanADC(0);
// Selecciono canal a convertir.ConvertADC();
// Comienza conversin.while(BusyADC()==1){}
// Hasta que se finalice conversin.Conversion= ReadADC(); // Realizo lectura.CloseADC();
while(1){ }
}