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

[Atmega8][C]Pierwsze próby z adc

solar1 11 Wrz 2008 10:42 1768 4
REKLAMA
  • #1 5524856
    solar1
    Poziom 15  
    Witam zrobilem schemat ze strony http://avr.elektroda.eu/?q=node/30
    z tym ze na atmega8 z wew rc ustawionym na 8mhz

    do obslugi adc uzywam takiej oto procedurki :
    
    void ADCO(void)
     {
      int x = 0; 
      ADCSRA = _BV(ADEN)|_BV(ADPS2); // ORGINAL 
         // Select pin ADC0 using MUX
         ADMUX = 0;   
         //Start conversion
    	ADCSRA |= _BV(ADSC);
    	// wait until converstion completed
    	while (ADCSRA & _BV(ADSC) ) {}    
        x = ADCW;  
        pomiar2H=ADCH;
    	pomiar2L=ADCL;
        uart_putc(pomiar2H);
        uart_putc(pomiar2L);	
    	//uart_putc(x);
     }
    

    Wydaje mi sie ze wszysko robie poprawnie z tym ze pomiaru moge dokonac tylko raz ... ponowne wywolanie tej procedury daje mi bledny odczyt napiecia...
    wysylane na urat wartosci sa takie same jak za pierwszym pomiarem
    uart_putc(pomiar2H);
    uart_putc(pomiar2L);
    po resecie i po przekreceniu potencjometru mam juz inne wartosci napiecia ale znowu takie same jak wywolane z procedury zapierwszym razem

    Prosze o pomoc
  • REKLAMA
  • #2 5524930
    Tomcio7
    Poziom 17  
    Wydaje mi się że źle ustawiłeś preskaler częstotliwości
    Spróbuj
    ADCSRA = _BV(ADEN)|_BV(ADPS2)|_BV(ADPS1);
  • REKLAMA
  • #3 5524974
    solar1
    Poziom 15  
    Nie to nie jest niestety to ;/ napewno zastanawia mnie czy nie powinem wpierw czyscic ADCW,ADCH i ADCL ?bo wyglada jak by tu "utknely" pierwsze pomierzone wartosci
    mam teraz jeszcze jedno pytanie - czy odczyt z rejestrow ma znaczenie ?
    zamieniajac miejscami
    odczyt
    pomiar2L=ADCL;
    pomiar2H=ADCH;

    udalo mi sie odczytac zmiany - za kazdym razem jak odwoluje sie do tej funkcji
  • REKLAMA
  • #4 5525055
    bobbyAIR
    Poziom 20  
    
    #define HI(a) ((unsigned char)(a>>8))
    #define LO(a) ((unsigned char)(a&0xff))
    
    void ADCO(void)
     {
     unsigned short x = 0; // int nie ma stalej dlugosci - zly nawyk
      ADCSRA = _BV(ADEN)|_BV(ADPS2); // czysci flage przerwania
      ADMUX = 0x00;  // 0 jest typu int i operacja będzie 16 bitowa 
         //Start conversion
       ADCSRA |= _BV(ADSC);
       // wait until converstion completed
       //while (ADCSRA & _BV(ADSC) ) {}   // blad - to wskazuje koniec pomiaru a nie zatrzasniecia wartosci w rejestrze ADC
        while(!(ADCSRA& _BV(ADIF))); // dokumentacja str. 204
        x = ADCW;
        //pomiar2H=ADCH; // Najpierw czyta się dolny bajt !!
        //pomiar2L=ADCL; // dokumentacja str 205 i ogólniej str 77 
        uart_putc(HI(x));
        uart_putc(LO(x));   
       //uart_putc(x);
     } 
    
  • #5 5525069
    Dr.Vee
    VIP Zasłużony dla elektroda
    Witam,

    Atmega 8 datasheet napisał:
    When ADCL is read, the ADC Data Register is not updated until ADCH is read. Consequently, if
    the result is left adjusted and no more than 8-bit precision is required, it is sufficient to read
    ADCH. Otherwise, ADCL must be read first, then ADCH.

    To chyba jest odpowiedź na Twoje pytanie?

    A na przyszłość jeśli potrzebujesz rozdzielczości 10-bitowej, to odczytuj dane korzystając z ADCW (albo ADC, to jest to samo) - wtedy nie pomylisz kolejności rejestrów :)
    uint16_t wynik = ADCW;

    Pozdrawiam,
    Dr.Vee
REKLAMA