collapse

* Posts Recentes

+ LASERs por dropes
[03 de Julho de 2025, 19:35]


Cerca eléctrica por SerraCabo
[14 de Junho de 2025, 23:26]


Alguém arranja motores? por almamater
[10 de Junho de 2025, 22:34]


Condensador 4.7uF 0603 por brunus
[09 de Junho de 2025, 15:52]


Lenovo IdeaPad 3 Não liga por jm_araujo
[07 de Maio de 2025, 19:10]


Identificar Diodo Zenner por filjoa
[01 de Maio de 2025, 23:07]


Meu novo robô por dropes
[18 de Março de 2025, 14:51]


JBL partybox On-The-Go por almamater
[21 de Fevereiro de 2025, 23:32]


Talking Reverse Engineering with an Absolute Legend! por SerraCabo
[13 de Fevereiro de 2025, 09:56]


Motoserra Stihl 120C por brunus
[11 de Fevereiro de 2025, 16:29]

Autor Tópico: [Ajuda] Atmega8 - Erro código ADC  (Lida 4736 vezes)

0 Membros e 1 Visitante estão a ver este tópico.

Offline metRo_

  • Administrator
  • Mini Robot
  • *****
  • Mensagens: 3.753
[Ajuda] Atmega8 - Erro código ADC
« em: 06 de Março de 2011, 03:57 »
Olá, estou com um erro no código que estou a desenvolver e tudo indica que tenha a ver com as interrupções do ADC, se ao código que acrescentei em baixo acrescentar a rotina de inicialização da porta série, ente funciona tudo direitinho mas se tirar o adc parece-me que está sempre a 0. Conclusão algo não está muito certo ao iniciar o ADC.
Alguma sugestão?


Código: [Seleccione]
#include <avr/io.h>
#include <avr/interrupt.h>

#define F_CPU 8000000UL
#include <util/delay.h>

#include "bit_tools.h"

uint16_t adcread=0;

void adc_init(void){
  ADMUX |= (1 << REFS0) | (0<<ADLAR);
  ADCSRA = (1 << ADEN) | (1<<ADSC) | (1<<ADFR) | (1 << ADIE)| (1 << ADPS2) | (1 << ADPS1) | (1 << ADPS0);     
}

ISR(ADC_vect){
  adcread=ADCL;
  adcread|=ADCH<<8;
}

int map(int x, int in_min, int in_max, int out_min, int out_max)
{
  return (x - in_min) * (out_max - out_min) / (in_max - in_min) + out_min;
}

int main(void) { 
  float adcGravadoDez=0,adcGravadoVinte=0,adcGravadoTrinta=0;
  int adcGravado=0,adcDif=0,nivel=0;
  uint8_t estado=0,btn=0,i=0;
 
  adcGravado=1020;
  adcGravadoDez=adcGravado*0.1;
  adcGravadoVinte=adcGravado*0.2;
  adcGravadoTrinta=adcGravado*0.3;
 
  DDRB=0xff;
  DDRD=0xff;
  DDRC|=(0<<PC3);
  DDRC|=(1<<PC2);
 
  PORTB=0xff;
  PORTD=0xff;
  bit_clear(PORTC,2);
 
  adc_init();
  sei();
 
  while(1){
 
    btn = (PINC & (1<<PC3))>>PC3;
    if (btn == 1) {
      adcGravado=adcread;
      adcGravadoDez=adcGravado*0.1;
      adcGravadoVinte=adcGravado*0.2;
      adcGravadoTrinta=adcGravado*0.3;
      estado=1;
    }
   
    if(estado==1){
      adcDif=adcread-adcGravado;
      if(adcDif<0)
adcDif=adcGravado-adcread;
     
      if((adcDif>adcGravadoDez)||(adcDif<(-adcGravadoDez))){
if((adcDif>adcGravadoVinte)||(adcDif<(-adcGravadoVinte))){
  nivel=map(adcDif,adcGravadoVinte,adcGravadoTrinta,12,15);
  if(nivel>15){
      nivel=15;
  }
}else{
  nivel=map(adcDif,adcGravadoDez,adcGravadoVinte,8,12);
}
      }else{
nivel=map(adcDif,0,adcGravadoDez,0,7);
      }

      for(i=0;i<16;i++){
if(i<8 && i<=nivel){
  bit_set(PORTD,i);
}else if(i<8){
  bit_clear(PORTD,i);
}else if(i<=nivel){
  bit_set(PORTB,i-8);
}else{
  bit_clear(PORTB,i-8);
}
      }
     
      _delay_ms(100); 
    }
  }
  return 0;
}

Offline senso

  • Global Moderator
  • Mini Robot
  • *****
  • Mensagens: 9.733
  • Helpdesk do sitio
Re: [Ajuda] Atmega8 - Erro código ADC
« Responder #1 em: 06 de Março de 2011, 20:35 »
Variáveis partilhadas por funções/main e interrupções tem de ser declaradas como volatile, no teu caso:
volatile uint16_t adcread=0;

E para leres o adc de 10 bits basta fazeres ADCW que o compilador trata do resto ;)

E como estas a fazer a inicializaçao, isto:
  ADMUX |= (1 << REFS0) | (0<<ADLAR);

Devia ser:
  ADMUX = (1 << REFS0);

Porque o 0 nao faz nada junto com o OR.
Avr fanboy