Banner publicitario de PCBWay

ADC AVR's

Saludos foro!

De antemano gracias, mi duda es como hacer que el ADC funcione, encontre varios ejemplos pero sin ningun resultado, este se queda en ceros y no convierte nada, lo que quiero lograr es ver en el puerto B del ATMEGA8 ver la conversion cortada por que son 10 pero solo eso, asi fue como conecte el circuito, agnd a tierra, avcc a vcc y aref a tierra por medio de un capacitor de 100nF, no se si este mal esto.

Ver el archivo adjunto 63189

He calado estos codigos

Código:
/*
 * ADC.c
 *
 * Created: 16/11/2011 12:50:06 p.m.
 *  Author: Jaime
 */ 
/*
#include <avr/io.h>

int main(void)
{
	unsigned int ADC_counts=0x55;
	
	DDRB=0xFF;
	ADCSRA=0x84;
    while(1)
    {
    ADMUX=0x02;
	ADCSRA|=0x40;
	while(ADCSRA|=0x40);
	ADC_counts=ADCW;
	PORTB=ADC_counts>>2;	
    }
}*/
#include <avr/io.h>
#include "retardo.h"
int main(void)
{
DDRB = 0xFF;
DDRD = 0b11111111;
int ADC_Val = 0;
ADCSRA = 0x84;
while(1) {
ADMUX = 0xC2;
ADCSRA|=0x40;
PORTD=0;
PORTB=0x55;
while (ADCSRA&0x40==0x40);
PORTD=1;
ADC_Val = ADCL;
PORTB = ADC_Val;
Tambien cale lo que viene en los pdf's de hecho ahi me base y tampoco de hecho no se que pueda ser :S si tienen ya una solucion hecha se les agadaceria mucho ;)

HETPRO manual (incluye ejemplos para el avr)

Incluí el proyecto en AVR Studio 5.0
 

Adjuntos

  • Capitulo 7 Convertidor analógico digital.pdf
    560.3 KB · Visitas: 1
  • ADC.rar
    13.7 KB · Visitas: 2
Última edición:
Yo uso este código y funciona bien:

- Rutina de interrupción y configuración:

Código:
void configura_interrupciones(u8 externa_config)
{
	//Mueve el vector de interrupcion al sector del Boot Loader
	/* Enable change of Interrupt Vectors - [B]Estas pueden ser optativas[/B] */ 
	GICR |= (1<<IVCE);
	/* Move interrupts to boot Flash section - [B]Estas pueden ser optativas[/B]*/
	GICR |= (1<<IVSEL);
	//Mueve el vector de interrupcion al sector del Boot Loader
	GICR|=externa_config;		// Configuro IE0 e IE1 - Las habilito o no
	[B]SREG |=0x80;[/B]	// Habilito las interrupciones
}

ISR(ADC_vect)
{
	flag_adc=1; //Variable Global, no podés usar punteros		
}

- Configuración del ADC:

Código:
void configura_adc()
{
	ADMUX=(1<<REFS0);  //Vref=Vcc con un capacitor como Vref
	ADCSRA=(1<<ADEN)|(1<<ADIE);  //INT habilitada, Prescaler x2
}

- Comienzo de conversión:

Código:
void adc_empieza(u8 canal)
{
	ADMUX  &=0xf0;
	ADMUX  |=canal;
	ADCSRA |=(1<<ADSC);
}

Entonces en tu código deberías hacer algo así:

Código:
#define u8 unsigned char
#define u16 unsigned int

u8 flag_adc=0;
....

int main(void)
{
  ...
  configura_interrupciones((1<<INT0)); //Habilito interrupciones generales y la externa0 por ejemplo
  ....
  configura_adc();
  ....
  adc_empieza(0); // uso el canal 0 para convertir
  while(!flag_adc); // espero a que termine la conversión, para mayor seguridad podés usar un Time-out con un timmer
  flag_adc=0;
  valor_adc=(u16)((ADCH<<8)|ADCL);
  ....  	
}

Y una cosa que se me paso... el puerto usalo como entrada de alta impedancia.
 
Última edición:
Te dejo un ejemplo de como usar el adc
Código:
/* http://unelectronica.260mb.com
   ejemplo del uso del ADC de los avr*/
#ifndef F_CPU
#define F_CPU 8000000UL 
#endif
#include <util/delay.h>
#include <stdlib.h>
void sleep(int milisegundos){
  while(milisegundos){
    _delay_ms(1);
    milisegundos--;}
}

uint16_t ReadChannel(uint8_t mux)
{
  uint16_t result = 0;
  ADCSRA = (1<<ADEN) | (1<<ADPS1) | (1<<ADPS0); // divior de frecuencia
  ADMUX = mux; // seleccion del canal
  ADMUX |= (1<<REFS0);//referencia vcc
  ADCSRA |= (1<<ADSC); //ADC transformacion final
  while ( ADCSRA & (1<<ADSC) ) {
    ; // espera a que termine la transformacion del ADC
}
  result = ADCW; // resultado
  ADCSRA &= ~(1<<ADEN); // ADC desactivacion
  return result;
}
int main()
{
  
  float f=0.0;
  
  while(1){
    f = 0.0049*ReadChannel(7);//convierto a voltios (5/1024)*result
    sleep(1000);
  }

return 0;
}
en este ejemplo se toma una muestra cada segundo (aproximadamente)

para leer el adc se definió la función ReadChannel(canal)
 
Última edición:
Muchas gracias por los aportes ambos me funcionaron termine haciendo algo como esto que tambien funciono fue con una interrupcion

Código:
/*
 * ADC.c
 *
 * Created: 16/11/2011 12:50:06 p.m.
 *  Author: Jaime
 */ 
//*****************************************************************************
#include <avr/io.h>
#include <avr/interrupt.h>
#include <util/delay.h>
#define  F_CPU 8000000

void adc_init(void);
void adc_start_conversion(uint8_t);



uint8_t ch;

void adc_init(void)
{
//select reference voltage
//AVCC with external capacitor at AREF pin
ADMUX|=(0<<REFS1)|(1<<REFS0);
//set prescaller and enable ADC
ADCSRA|=(1<<ADEN)|(1<<ADIE);//enable ADC with dummy conversion

}

void adc_start_conversion(uint8_t channel)
{
ADMUX=(ADMUX&0xF0)|channel;
ADMUX|=(1<<ADLAR);//moves the conversion low to ADCH register
//Start conversion with Interrupt after conversion
//enable global interrupts
sei();
ADCSRA |= (1<<ADSC)|(1<<ADIE);
}


ISR(ADC_vect)
{
	PORTB=~ADCH;
}


int main(void)
{
	DDRB=0xFF;
	adc_init();
	while(1)
	{
	adc_start_conversion(2);
	_delay_ms(30);
	//read potentiometer ch2
	}
	return 0;
}
 
Atrás
Arriba