logo elektroda
logo elektroda
X
logo elektroda
REKLAMA
REKLAMA
Adblock/uBlockOrigin/AdGuard mogą powodować znikanie niektórych postów z powodu nowej reguły.

[Atmega32][C] ADC - Problem :)

kozikowski11 21 Lis 2009 09:15 2385 12
REKLAMA
  • #1 7288690
    kozikowski11
    Poziom 17  
    Teraz sie zastanawiam dlaczego oba wyniki wzraca mi takie same, czyli: "4" i nie zmieniaja sie.

    volatile float result; 
    volatile uint8_t counter; 
    volatile int measure_sensor1, measure_sensor2; 
    char str[9];
    char str2[9];
    
    SIGNAL(SIG_ADC){
        result=(float)(ADCL | (ADCH<<8))/1024*VREF;    
    	counter++;       
    	
    	if(counter==50){
           if(bit_is_set(ADMUX, MUX0)){
              measure_sensor1=result;
              ADMUX&=~_BV(MUX0);
            }else{
              measure_sensor2=result;
              ADMUX=_BV(MUX0);
            }             
    		
    		counter=0;
        } 
    }
    
    void init_adc(void){
    	ADCSRA = _BV(ADEN)|_BV(ADIE)|_BV(ADATE)|_BV(ADSC)|_BV(ADPS0)|_BV(ADPS1)|_BV(ADPS2);
    } 
     
    int main(){
    
    LcdInit(); //init LCD
    
          init_adc();    
    	  sei();         
    	
    	while(1){
    	//measure_sensor1 = 2;
    	itoa(measure_sensor1, str, 10);
    	itoa(measure_sensor2, str2, 10);
    
    	LcdClear();
    	LcdGotoXY(1,1);
    	LcdStr(1, "SENS1: ");
    	LcdStr(1, str);
    		LcdGotoXY(1,4);
    
    	LcdStr(1, "SENS2: ");
    	LcdStr(1, str2);
    	
    	LcdUpdate();
    
        }
        
    	return 0; 
    	 
    	 
    }
    


    Podlaczone mam pod PA0 i PA1, wyniki powinny byc "zmienne"...
  • REKLAMA
  • #2 7288712
    Circuit Chaos
    Poziom 13  
    Na początek spróbuj tymczasowo:

    result=(float)(ADCL | (ADCH<<8))/1024*VREF;


    zamienić na:



    a w main daj na początku np:

    measure_sensor1=123;


    to pokaże dwie rzeczy:

    - czy błąd nie tkwi w obliczaniu result
    - czy przerwanie w ogóle jest wywoływane (jak sensor1 będzie ciągle na 123 to znaczy że nie)
  • #3 7288750
    Mergot
    Poziom 11  
    Ustawiłeś ADC na próbkowanie ciągłe wywoływane (ADATE) przez impuls (trigger).
    Ale jednocześnie rejestr SFIOR jest w postaci domyślnej czyli Free running mode, co powoduje, że nie jest generowany sygnał rozpoczęcia kolejnego próbkowania.

    Obsługa ADC jest w datasheet dość dobrze opisana, warto przeczytać.
  • REKLAMA
  • #5 7290434
    Circuit Chaos
    Poziom 13  
    Czyli problem jest z odczytem z ADC a przerwanie jest wywoływane (przynajmniej raz). Zrób tak jak napisał Mergot.
  • #6 7291441
    kozikowski11
    Poziom 17  
    Tylko ze ja nie wiem zbytnio jak to programowo zrobic... Do tej pory siedzialem w datasheet i nic nie udalo mi sie zrobic...

    Moglby ktos mi poprawic kod? Z gory dzieki :)
  • REKLAMA
  • #7 7291949
    Circuit Chaos
    Poziom 13  
    Nie bawiłem się ADC w ATmega32 - jedynie w ATmega8, tam jest ADFR. Więc z ADATE nie pomogę. Ale możesz spróbować zrobić inaczej.

     ADCSRA = _BV(ADEN)|_BV(ADIE)|_BV(ADATE)|_BV(ADSC)|_BV(ADPS0)|_BV(ADPS1)|_BV(ADPS2);

    zamień na:

     ADCSRA = _BV(ADEN)|_BV(ADIE)|_BV(ADSC)|_BV(ADPS0)|_BV(ADPS1)|_BV(ADPS2);

    i na końcu funkcji obsługi SIG_ADC:

     ADCSRA |= _BV(ADSC);

    Oprócz tego sei() daj przed init_adc(); a nie po.
  • #9 7296702
    kordirko
    Poziom 22  
    kozikowski11 napisał:
    Teraz sie zastanawiam dlaczego oba wyniki wzraca mi takie same, czyli: "4" i nie zmieniaja sie.

    Miałem niedawno podobny problem, pomogło jak tę linijkę:
    ADCSRA = _BV(ADEN)|_BV(ADIE)|_BV(ADATE)|_BV(ADSC)|_BV(ADPS0)|_BV(ADPS1)|_BV(ADPS2)


    zamieniłem na:
    ADCSRA = _BV(ADEN);
    ADCSRA |=_BV(ADIE)|_BV(ADATE)|_BV(ADSC)|_BV(ADPS0)|_BV(ADPS1)|_BV(ADPS2)
  • REKLAMA
  • #10 7395739
    wladziu22
    Poziom 17  
    kordirko przecież to co Ty napisałeś to jest to samo co wcześniej było.

    gophi
    Cytat:
    Oprócz tego sei() daj przed init_adc(); a nie po.

    Jak tak zrobi to niewiele zmieni. Kilka milisekund później zaczną działać przerwania a przetwornik tak czy inaczej działa od chwili _BV(ADEN).
    A zmiana kanału jest możliwa jedynie w przypadku zakończenia konwersji czyli gdy (ADIF=1 w ADCSR).
  • #11 8812094
    grandcapucin
    Poziom 10  
    @wladziu22, nie wiem o co chodzi, ale próbowałem wszystkiego i jak ostatecznie zmieniłem w swoim kodzie dla [Atmega32] linię podobnie tak jak to zmienił kordirko, czyli cała deklaracja rejestru w jednej linii to ADC od razu zaczął działać. Wcześniej miałem deklarację jedna po drugiej, tzn.
    ADCSRA |= _BV(ADEN);
    ADCSRA |=_BV(ADIE);
    ...
    ADCSRA |=_BV(ADPS2);

    i nie działało. Niesamowite, ktoś wie dlaczego?
  • #12 8813715
    gaskoin
    Poziom 38  
    Co masz podpięte do pinu AREF ?


    -----------------------

    właśnie zauważyłem, że ktoś zrobił wykopalisko :)
  • #13 8813813
    grandcapucin
    Poziom 10  
    Kondensator 100nF do GND i kolejny w szeregu do AVCC.
REKLAMA