ADC AVR's

#1
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

Última edición:
#2
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:
#3
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:
#4
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;
}
 

Temas similares

Arriba