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: Przetwornik A/C nie działa, kod w AVRGCC, diody LED na porcie D

marcin_g 14 Mar 2005 15:51 5825 7
REKLAMA
  • #1 1315001
    marcin_g
    Poziom 12  
    Posty: 55
    Pomógł: 3
    Ocena: 7
    Mam problem, poniewaz przetwornik A/C w atmega8 nie chce działać. Program napisałem w AVRGCC i nie wiem czy czegoś nie pominalem?
    Wszystkie rejestry ustawiam wg dokumentacji procesora i nic. Opis i kod programu jest w zalaczniku. Program ma wyswietlac wynik na 8 diodach LED podlaczonych do portu D. Prosze o pomoc osoby programujace AVR.

    #include <avr/io.h> //przetwornik a/c, wejscie analogowe
    //to ADC1=PC1, procesor - ATMEGA8
    int main(void){ //wyjscie cyfrowe - linijka 8 LED na porcie D
    ADCSRA=1<<ADEN; //włączenie przetwornika
    ADCSRA=1<<ADPS0;//uP bez kwarcu, czyli fosc=1MHz
    ADCSRA=1<<ADPS1;//preskaler ustawiony na fosc/8, czyli fadc=125kHz
    ADMUX=1<<REFS0; //napiecie referencyjne to AVCC, kondensator podlaczony do AREF
    ADMUX=1<<MUX0; //wejscie analogowe ADC1
    DDRD=0xff; //ustawienie całego portu D jako wyjscia
    DDRC=0x00; //ustawienie całego portu C jako wejścia
    while(1){
    ADCSRA=1<<ADSC; //start pojedynczej konwersji
    while(bit_is_set(ADCSRA,ADSC)){};//czekanie az konwersja zakonczona, wtedy ADSC=0;
    PORTD=ADCH; //przepisanie na portd wyniku 8-bitowego
    } //niestety nie działa!!!
    return(0);
    }
  • REKLAMA
  • #2 1315338
    tajwoj
    Poziom 26  
    Posty: 559
    Pomógł: 106
    Ocena: 102
    Hej,
    Spróbuj w ten sposób (u mnie działa). -
    
    
    #include <avr/io.h> //przetwornik a/c, wejscie analogowe
    //to ADC1=PC1, procesor - ATMEGA8
    int main(void){ //wyjscie cyfrowe - linijka 8 LED na porcie D
    ADCSRA=ADCSRA | 1<<ADEN; //włączenie przetwornika
    ADCSRA=ADCSRA | 1<<ADPS0;//uP bez kwarcu, czyli fosc=1MHz
    ADCSRA=ADCSRA | 1<<ADPS1;//preskaler ustawiony na fosc/8, czyli fadc=125kHz
    ADMUX=ADMUX | 1<<REFS0; //napiecie referencyjne to AVCC, kondensator podlaczony do AREF
    ADMUX=ADMUX | 1<<MUX0; //wejscie analogowe ADC1
    DDRD=0xff; //ustawienie całego portu D jako wyjscia
    DDRC=0x00; //ustawienie całego portu C jako wejścia
    while(1){
    ADCSRA=ADCSRA | 1<<ADSC; //start pojedynczej konwersji
    while(bit_is_set(ADCSRA,ADSC)){};//czekanie az konwersja zakonczona, wtedy ADSC=0;
    PORTD=ADCH; //przepisanie na portd wyniku 8-bitowego
    } //niestety nie działa!!!
    return(0);
    }
    

    Pozdrawiam i powodzenia
  • REKLAMA
  • #3 1316007
    marcin_g
    Poziom 12  
    Posty: 55
    Pomógł: 3
    Ocena: 7
    Wielkie dzieki tajwoj, moj uklad wreszcie ruszyl. Moim bledem bylo stosowanie instrukcji np. ADMUX=1<<MUX0; zamiast: ADMUX=ADMUX | 1<<MUX0; Dodatkowo zmodyfikowalem moj prog w ten sposob, ze ustawilem bit ADLAR - 8-bitowy wynik jest w ADCH. Jesli ten bit nie bedzie ustawiony, to najpierw trzeba czytac ADCL a dopiero pozniej ADCH - w przeciwnym razie nie zadziała!!! Druga modyfikacja polega na tym, ze ustawiony zostal bit ADFR - przetwornik działa cały czas, przedtem nie chciał. Oto kod programu:
    int main(void){ //wyjscie cyfrowe - linijka 8 LED na porcie D
    ADCSRA=ADCSRA | 1<<ADEN; //włączenie przetwornika
    ADCSRA=ADCSRA | 1<<ADPS0;//uP bez kwarcu, czyli fosc=1MHz
    ADCSRA=ADCSRA | 1<<ADPS1;//preskaler ustawiony na fosc/8, czyli fadc=125kHz
    ADMUX=ADMUX | 1<<REFS0; //napiecie referencyjne to AVCC, kondensator podlaczony do AREF
    ADMUX=ADMUX | 1<<MUX0; //wejscie analogowe ADC1
    ADMUX=ADMUX | 1<<ADLAR; //wynik "left adjusted"
    DDRD=0xff; //ustawienie całego portu D jako wyjscia
    DDRC=0x00; //ustawienie całego portu C jako wejścia
    ADCSRA=ADCSRA | 1<<ADSC; //start pojedynczej konwersji
    ADCSRA=ADCSRA | 1<<ADFR; //free running mode
    while(1){
    PORTD=ADCH;
    }
    return(0);
    Mysle, ze na tym powinnismy zakonczyc ten temat, jeszcze raz wielkie dzieki dla tajwoja.
  • Pomocny post
    #4 1316029
    tajwoj
    Poziom 26  
    Posty: 559
    Pomógł: 106
    Ocena: 102
    Hej,
    Przedtem sprawdziłem tylko czy działa przetwornik. Dla pełni szczęścia ustaw jeszcze bit ADLAR w ADMUX (strona 205 pedeefa dla ATmega8). W przeciwnym wypadku bedą Ci migać co najwyżej dwie najmłodsze diody portu D.
    Jeżeli diody masz podłączone do VDD to mozesz zanegować ADCH (PORTD = ~ADCH) aby mieć zgodność świecenia diód z wartością ADCH.
    Pozdrawiam
  • REKLAMA
  • #5 1360526
    pit_com
    Poziom 15  
    Posty: 189
    Pomógł: 3
    Ocena: 6
    Sorry, ale jestem mały i głupi :-) W jakim języku to jest napisane? Jak zmienić napięcie ref na 1/5 Vcc ??
  • #6 1360615
    xbaj
    Poziom 20  
    Posty: 415
    Pomógł: 17
    Ocena: 16
    Cytat:
    ...Program napisałem w AVRGCC
    - czyli programowanie w C. To co znajduje się powyżej to konfiguracja przetwornika (ustawianie konkretych bitow w słowach sterujących). W pdf ATEGA8L jest opisane jak skonfigurować A/C dla zewnętrzego napięcia odniesienia. Z tego co pamiętam odpowiedzialne były dwa najbardziej znaczące bity w ADMUX (należy je ustawić na "1").[/quote]
  • REKLAMA
  • #7 1401633
    LuznyTomasz
    Poziom 15  
    Posty: 204
    Pomógł: 13
    Ocena: 1
    Jaką pojemność powinien mieć kondensator między AREF a AVCC jeśli napięciem odniesienia jest AVCC? W jaki sposób należy go podpiąć? Czy nie chodzi tutaj o filtr LC poprzez który zasilany jest przetwornik.
    Jeśli więc chce żeby napięciem odniesienia było napięcie zasilania to czy muszę podłączać cokolwiek pod pin AREF czy może on wisieć w powietrzu?

    I jeszcze jedno - w jakim celu ustawia się bity ADPS...co uzyskujemy dzięki podzieleniu częśtotliwości oscylatora? Większą dokładność? I cóż do jest za dziwny bit ADFR zapewnee chodzi o ADATE
  • #8 1979600
    marcin_g
    Poziom 12  
    Posty: 55
    Pomógł: 3
    Ocena: 7
    Temat zakończony :)

Podsumowanie tematu

LABEL_AI_GENERATED
Problem dotyczył nieprawidłowego działania przetwornika analogowo-cyfrowego (A/C) w mikrokontrolerze ATmega8, programowanego w AVRGCC. Główną przyczyną błędu było nadpisywanie rejestrów ADCSRA i ADMUX zamiast ustawiania poszczególnych bitów poprzez operację OR (|=). Konieczne było także ustawienie bitu ADLAR w rejestrze ADMUX, co powoduje lewostronne wyrównanie wyniku i umożliwia odczyt 8-bitowego wyniku bezpośrednio z rejestru ADCH. Dodatkowo, aby przetwornik działał ciągle, należało ustawić bit ADFR (w nowszych dokumentacjach ADATE) w ADCSRA. Wskazano, że odczyt wyniku ADC wymaga uwzględnienia kolejności czytania rejestrów ADCL i ADCH, jeśli ADLAR nie jest ustawiony. W dyskusji poruszono także kwestie napięcia odniesienia (AVCC z kondensatorem na pinie AREF) oraz znaczenia preskalera ADPS w celu dostosowania częstotliwości zegara ADC do wymagań dokładności i stabilności pomiaru. Przykładowy poprawny kod inicjalizacji i odczytu ADC został przedstawiony, a także sugestia negacji wyniku przy podłączeniu diod LED do VDD, aby uzyskać zgodność wizualizacji. Temat został zakończony po uzyskaniu działającego rozwiązania.
Podsumowanie AI na podstawie dyskusji. Może zawierać błędy.
REKLAMA