Haz una pregunta
  Foros de Electrónica » Diseño digital » Microcontroladores y sistemas embebidos
Foros Registrarse ¿Olvidaste tu contraseña?

Temas similares

19/11/2011 #1

Avatar de jaimepsantos

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.



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
19/11/2011 #2

Avatar de cosmefulanito04

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 - Estas pueden ser optativas */ 
	GICR |= (1<<IVCE);
	/* Move interrupts to boot Flash section - Estas pueden ser optativas*/
	GICR |= (1<<IVSEL);
	//Mueve el vector de interrupcion al sector del Boot Loader
	GICR|=externa_config;		// Configuro IE0 e IE1 - Las habilito o no
	SREG |=0x80;	// 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.
19/11/2011 #3

Avatar de mdchaparror

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)
21/11/2011 #4

Avatar de jaimepsantos

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;
}
Respuesta
¿Tienes una mejor respuesta a este tema? ¿Quieres hacerle una pregunta a nuestra comunidad y sus expertos? Registrate

Foros de Electrónica » Diseño digital » Microcontroladores y sistemas embebidos

Powered by vBulletin® Version 3.8.4
Copyright ©2000 - 2017, Jelsoft Enterprises Ltd.
Search Engine Optimization by vBSEO ©2011, Crawlability, Inc.