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

Kod w C do jednorazowej konwersji AC na Atmega8 i zapis do zmiennej

tomgart 09 Lis 2006 10:26 3000 14
REKLAMA
  • #1 3204479
    tomgart
    Poziom 25  
    Posty: 864
    Pomógł: 49
    Ocena: 63
    Mógłbym poprosić o najprostrzy kawałek kodu w C aby wyzwolić jeden raz konwersję AC i zapisać wynik do zmiennej?
  • REKLAMA
  • Pomocny post
    #2 3204508
    aristot
    Poziom 14  
    Posty: 149
    Pomógł: 10
    Ocena: 4
    inicjowanie
    ldi R20, (1<<REFS0)|(1<<ADLAR)|(1<<MUX2)|(1<<MUX0)
    out ADMUX, R20

    ldi R20, (1<<ADEN)|(1<<ADPS1)|(1<<ADPS0)
    out ADCSRA, R20
    ldi R20, (1<<REFS0)|(1<<ADLAR)|(1<<MUX0)
    out ADMUX, R20

    przetw:
    sbi ADCSRA, ADSC
    przetw1:
    sbis ADCSRA, ADIF
    rjmp przetw1

    cbi ADCSRA, ADIF
    in R24, ADCH



    troche trzeba uporządkowac bo kopiowłem z kodu. Ten kod działał na Atmega8.

    Pozdrawiam
  • REKLAMA
  • Pomocny post
    #3 3204604
    pubus
    Poziom 30  
    Posty: 1289
    Pomógł: 139
    Ocena: 32
    
    #include...
    ...
    ...
    //kwarc 3,6864MHz
    ...
    ...
    volatile unsigned int koniec=0;
    volatile unsigned long int adc;
    ...
    ...
    int main(void)
    {
     sei();
     
     for(;;)
     {
      ADMUX = (1 << REFS1) | (1 << REFS0); //kanał ADC0, wew ref 2,56V 
      ADCSRA = (1 << ADEN) | (1 << ADSC) | (1 << ADIE) | (1 << ADPS2) | (1 << ADPS1); //pojedyncza konwersja, aktywne przerwanie, prescal 64, clock input 56,7kHz
      while(koniec!=1) {}
      koniec=0;
      adc = (adc * 2560) / 1024); //przeliczenie na wynik w mV
     }
    
    return 0;
    }
    
    SIGNAL (SIG_ADC)  //obsługa przerwania od A/C
    {
     adc = ADC;
     koniec=1;
    } 
    


    Radzę nie korzystać z tego na pałe tylko przeglądnąć w połączeniu z dokumentacją uC...
    Zresztą tak czy tak dokumentację przeczytać musisz jeśli chcesz uzyskać wiarygodny pomiar w przypadku zastosowania innego kwarcu i Vref...
  • #4 3204838
    tomgart
    Poziom 25  
    Posty: 864
    Pomógł: 49
    Ocena: 63
    pubus: można te wpisy do rejestrów ADMUX i ADCSRA umieścić przed pętlą i wpisywać ustawiać tylko bit ADSC? (po konwersji jest on automatycznie zerowany)
    Z tego to wyczytałem 10 bitowy wynik jest zapisywany w 2 rejestrach ADCL i ADCH, Czy w ADC automatycznie są już "połaczone" te dwie wartośći?
    Pubus, mógłbyś mi naświetlić jescze obsługę tego przerwania?


    Chyba już zaczaiłem to przerwania, mam tylko pytanie czy nie powinno ono być przed main()?
  • REKLAMA
  • Pomocny post
    #5 3205237
    pubus
    Poziom 30  
    Posty: 1289
    Pomógł: 139
    Ocena: 32
    Witam...
    Tak można...
    Ale pamiętaj o sumie przy ustawianiu inaczej wyzerujesz sobie cały rejestr...
    Tak w tym przypadku nie musisz (ale możesz) się martwić odczytem osobnych rejestrów (H i L) i ich kolejnością...
    Oczywiście zmienna do której wczytujesz musi mieścić 10-bitów...
    Zabawa w czytanie rejestrów ADCH lub ADCL ma sens jeżeli przesówasz wynik i odczytujesz tylko 8-bitów...
    Nie ma znaczenia gdzie umieścisz obsługę przerwania...
    Ja wolę tak ale można i przed...
    Po odpaleniu przetwornika program wchodzi w pętle i czeka na zakończenie konwersji i odczyt wyniku w przerwaniu i dopiero wtedy leci dalej...
    Nie sugeruj się tym bo to akurat taki mój wymysł wymuszony konstrukcją programu...
  • Pomocny post
    #6 3208784
    Ch.M.
    Poziom 27  
    Posty: 1009
    Pomógł: 62
    Ocena: 15
    airstot ADIF zeruje się wysoką wartością logiczną, kawałek mojego kodu (ASM):

    ldi R17, 0b11000100 ; ustawiamy preskaler ADC na 16 (1MHz/16=62,5 kHz) i startujemy
    out ADCSRA, R17
    ldi R16, 0b11100000 ; ustawiamy PA6 jako wejście przetwornika napięcia i wybieramy
    out ADMUX, R16 ; jako napięcie odniesienia 2,56V
    sbi ADCSRA, ADSC

    Konwersja_nap:
    sbis ADCSRA, ADIF ; czekamy na zakończenie konwersji (ADIF=1)
    rjmp Konwersja_nap

    sbi ADCSRA, ADIF ; zeruj znacznik zakończenia konwersji
    in R21, ADCH ; kopiuje 8bitowy wynik do rejestru R21

    Jak zauważyć można otrzymuję liczbę 8bitową (przetwornik i tak jest 8bitowy) co mi wystarcza w zupełności, a dodatkowo prostsze to jest do dalszego przetwarzania danych
    Kod sprawdzony na M8,16,32 (lekka modyfikacja pinów conajwyzej bedzie potrzebna)
  • REKLAMA
  • #7 10378273
    symfonia
    Poziom 10  
    Posty: 7
    Hmm..., nie bardzo rozumiem dlaczego ADIF zeruje się wysoką wartością logiczną. Skoro po zakończeniu przetwarzania jest ustawiany ADIF na "1" to nie powinno się go zerować? W Baranowskim jest też przykład, że się właśnie ustawia ale nie rozumiem jak można ustawić ustawiony bit? Bardzo proszę o wyjaśnienie mi tej zawiłości.
  • #8 10378413
    janbernat
    Poziom 38  
    Posty: 3954
    Pomógł: 468
    Ocena: 51
    Bo ten typ tak ma.
    A tak poważniej- to pewnie chodzi o to że wpisanie bitu do rejestru nie następuje bezpośrednio a przez jakiś przerzutnik.
    Zdaje się że chodzi o zwiększenie odporności na przypadkowe skasowanie bitu.
    Wększość rejestrów tak ma- ale nie wszystkie.
  • #9 10378448
    excray
    Poziom 41  
    Posty: 5502
    Pomógł: 739
    Ocena: 657
    Już tyle razy było pisane i mówione że nie sprawdza ani nie zeruje się bitu ADIF. ADIF to flaga do przerwania. Jeśli chcecie sprawdzić czy konwersja się zakończyła należy sprawdzać stan bitu ADSC który sam się zeruje po zakończonej konwersji:
    Kod: text
    Zaloguj się, aby zobaczyć kod

    A później się dziwicie że problemy, że nie działa tak jak powinno, a w manualu jak wół...
  • #10 10378487
    janbernat
    Poziom 38  
    Posty: 3954
    Pomógł: 468
    Ocena: 51
    To zależy:
    • Bit 4 – ADIF: ADC Interrupt Flag
    This bit is set when an ADC conversion completes and the Data Registers are updated.
    The ADC Conversion Complete Interrupt is executed if the ADIE bit and the I-bit in
    SREG are set. ADIF is cleared by hardware when executing the corresponding interrupt
    Handling Vector. Alternatively, ADIF is cleared by writing a logical one to the flag.
    Beware that if doing a Read-Modify-Write on ADCSRA, a pending interrupt can be disabled.
    This also applies if the SBI and CBI instructions are used.
    Jeśli w głownej pętli sprawdzasz czy konwersja się zakończyła to możesz sprawdzić czy ADIF jest ustawiony, odczytać rejestry, skasować ADIF wpisując 1 i sprawdzać w głównej pętli ponownie.
    Zresztą nie tylko przetwornik- ale inne przerwania sprzętowe też.
  • #11 10378500
    excray
    Poziom 41  
    Posty: 5502
    Pomógł: 739
    Ocena: 657
    janbernat napisał:
    Jeśli w głownej pętli sprawdzasz czy konwersja się zakończyła to możesz sprawdzić czy ADIF jest ustawiony, odczytać rejestry, skasować ADIF wpisując 1 i sprawdzać w głównej pętli ponownie.

    A nie lepiej wtedy skorzystać z przerwania od zakończonej konwersji? A ADSC to już nie można w głównej pętli sprawdzić? Jak już cytujemy:
    Cytat:
    • Bit 6 – ADSC: ADC Start Conversion
    In Single Conversion mode, write this bit to one to start each conversion. In Free Running mode,
    write this bit to one to start the first conversion. The first conversion after ADSC has been written
    after the ADC has been enabled, or if ADSC is written at the same time as the ADC is enabled,
    will take 25 ADC clock cycles instead of the normal 13. This first conversion performs initializa-
    tion of the ADC.
    ADSC will read as one as long as a conversion is in progress. When the conversion is complete,
    it returns to zero. Writing zero to this bit has no effect.
  • #12 10378507
    janbernat
    Poziom 38  
    Posty: 3954
    Pomógł: 468
    Ocena: 51
    Można.
    Każdy sposób ma swoje zady i walety.
  • #13 10378538
    excray
    Poziom 41  
    Posty: 5502
    Pomógł: 739
    Ocena: 657
    janbernat napisał:
    Można.
    Każdy sposób ma swoje zady i walety.

    W sumie masz rację. Jeśli ktoś pisze program w ten sposób że np. nie chce korzystać z przerwań a jedynie sprawdza w głównej pętli indywidualne flagi, a korzysta okazjonalnie z ADC to wtedy korzystanie z ADIF jest wygodniejsze niż z ADSC.
  • #14 10378585
    janbernat
    Poziom 38  
    Posty: 3954
    Pomógł: 468
    Ocena: 51
    To jest jak ustawienie flagi w przerwaniu- ale nie ma prologu i epilogu wejścia w przerwanie.
    Jest szybciej.
    Z tym że odczyt rejestrów w takim przypadku należy chyba robić w Atomic_block.
    A- ale to jest w asm.
    No to trzeba zablokować/odblokować przerwania.
  • #15 10378611
    symfonia
    Poziom 10  
    Posty: 7
    Dzięki Panowie, biorę się za mojego pierwszego avr, stąd nie wiedziałem, że ten "ten typ tak ma" i dlatego było to dla mnie niezrozumiałe. W manualu czytałem właśnie o tym, że trzeba zapisać ADIF logiczną jedynką ale nie bardzo wiedziałem dlaczego. Pewnie faktycznie jest to jakieś zabezpieczeni sprzętowe przed pomyłkowym wczytaniem nieodpowiedniej wartości.Pomysł z ADSC też wydaje sie dobry. Jeszcze raz dzięki!

Podsumowanie tematu

LABEL_AI_GENERATED
Dyskusja dotyczy najprostszego kodu w języku C do jednorazowej konwersji analogowo-cyfrowej (ADC) na mikrokontrolerze Atmega8 oraz zapisu wyniku do zmiennej. Przykłady obejmują inicjalizację rejestrów ADMUX i ADCSRA, uruchomienie konwersji przez ustawienie bitu ADSC, oczekiwanie na zakończenie konwersji poprzez sprawdzanie flagi ADIF lub bitu ADSC, a następnie odczyt wyniku z rejestrów ADCL i ADCH. Wskazano, że wynik 10-bitowy jest dostępny w dwóch rejestrach, które można odczytać bezpośrednio do zmiennej 16-bitowej. Omówiono także obsługę przerwania ADC (ADC interrupt), które pozwala na asynchroniczne odczytanie wyniku i ustawienie flagi zakończenia konwersji. Wyjaśniono mechanizm zerowania flagi ADIF przez zapis logicznej jedynki, co jest specyficzne dla sprzętowego zabezpieczenia przed przypadkowym skasowaniem. Poruszono różnice między sprawdzaniem flag ADIF i ADSC w pętli głównej oraz zalety stosowania przerwań. Przykłady kodu w asemblerze i C potwierdzają poprawność podejścia na Atmega8 oraz kompatybilność z modelami Atmega16 i Atmega32. Dyskusja podkreśla konieczność zapoznania się z dokumentacją mikrokontrolera dla uzyskania wiarygodnych pomiarów ADC.
Podsumowanie AI na podstawie dyskusji. Może zawierać błędy.
REKLAMA