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] [Atmega8][C][AS6] - ADC nie działa, LED1 i LED2 zapalają się po naciśnięciu przycisku

Malin2000 31 Lip 2014 19:08 1359 9
REKLAMA
  • #1 13840927
    Malin2000
    Poziom 9  
    Posty: 20
    Ocena: 3
    Witam!

    Uczę się programowania i dotarłem do ADC. Problem polega na tym, że program jakby w ogóle nie był wykonywany. Po włączeniu uC jedyne, co obserwuje to po naciśnięciu przycisku LED1 i LED2 zapalają się.

    Kod: C / C++
    Zaloguj się, aby zobaczyć kod


    Krótko o kodzie:
    Inicjalizacja wejść i wyjść, ustalanie Pull-up'ów.
    potem set-up INT0 i ADC.
    pętla główna z migającym ledem.
    funkcja przerwania na przycisk - start konwersji.
    przerwanie od ADC - spisanie wyniku i ogarnięcie ledów wskazujących wynik.

    w kodzie są umieszczone podczas inicjalizacji delay i zapalanie ledów (oznaczone jako //check x), by sprawdzić gdzie kod się sypie. Ale nie widzę ani jednej zmiany w świeceniu lampek.

    Schemat poniżej:
    Potencjometr (R5) też do 10k.
    [Atmega8] [Atmega8][C][AS6] - ADC nie działa, LED1 i LED2 zapalają się po naciśnięciu przycisku

    Przewertowałem DataSheet i tutejsze forum, ale wszystkie poprawki (już naniesione) nie dały rezultatu.
    testowałem z ustawienie MUX3..0 na 1110 (1.3V) (pozostałości jeszcze są w kodzie wykomentowane) ale i tutaj efekt był ten sam.
    Testowałem kod dosłownie zerżnięty z tego Tutoriala i też nie działał.

    Sprzęt:
    ATMega8A
    USBasp
    Atmel Studio 6.1

    Wszystko podłączone na płytce stykowej.
    Zasilane z programatora.
    Wszystkie inne programy, które do tej pory robiłem działały bez zarzutu.

    P.S. Tak wiem, że nie definiuje się F_CPU w kodzie, ale nie mogę wygrać z AS6 jeszcze w kwestii ustawień kompilacji. Ale walczę:)
  • REKLAMA
  • Pomocny post
    #2 13840993
    szczywronek
    Poziom 28  
    Posty: 678
    Pomógł: 142
    Ocena: 217
    Pierwsze co się rzuca w oczy to użycie złego operatora. Przy konfiguracji rejestrów używasz operatora negacji logicznej (!) a powinna być negacja bitowa (~).
  • REKLAMA
  • #3 13841084
    Malin2000
    Poziom 9  
    Posty: 20
    Ocena: 3
    poprawiłem wszystkie (!) na (~).

    Program ruszył. Z tym, że niezależnie od nastawień potencjometru cały czas jest tylko jedna dioda zapalona (środkowy zakres). Pewnie nie dowiem się więcej dopóki nie podłącze wyświetlacza.. :)

    przy okazji.. jaka jest różnica w działaniu negacji logicznej (!) a bitowej (~). wcześniej korzystałem z wykrzyknika i wszystko działało dobrze...
  • #4 13841165
    szczywronek
    Poziom 28  
    Posty: 678
    Pomógł: 142
    Ocena: 217
    Negacja bitowa powoduje zanegowanie każdego, pojedynczego bitu negowanej wartości. Np.:

    x = 0b1010
    ~x = 0b0101

    Wersja logiczna działa inaczej. W C każda wartość różna od 0 jest z logicznego punktu widzenia PRAWDĄ. Tylko 0 jest traktowane jako FAŁSZ. Negacja logiczna powoduje zmianę logicznej wartości wyrażenia. Jeżeli weźmiesz wartość jak w poprzednim przykładzie:

    x = 0b10101

    to logicznie jest ona prawdą, bo jest różna od zera. Po "logicznym zanegowaniu" musi być fałszem -> czyli będzie wynosić 0.

    Tyle teorii. Praktyka: na tym blogu klik masz kompilator C online (CManiak). Wklej tam kod i sprawdź czy wszystko się zgadza:

    Kod: C / C++
    Zaloguj się, aby zobaczyć kod


    Myślę, że jest on dosyć intuicyjny. Polecam różne eksperymenty ;)
  • #5 13841249
    Malin2000
    Poziom 9  
    Posty: 20
    Ocena: 3
    Właśnie machnąłem sobie szybki program na PC, który porównuje te dwie rzeczy. i widzę różnicę. Ciekawe, że tego nie ma nigdzie napisane wprost (przynajmniej było ukryte dla moich oczu...)

    Anyway, problem nie rozwiązany jeszcze. Ale wrócę do niego jak kupie i podłącze wyświetlacz. zatem temat otwarty.

    BTW dzięki za pomoc:)
  • REKLAMA
  • #6 13841758
    pbuhne
    Poziom 15  
    Posty: 51
    Pomógł: 17
    Cześć,

    w przerwaniu:

    zamiast
    Kod: C / C++
    Zaloguj się, aby zobaczyć kod


    możesz:
    Kod: C / C++
    Zaloguj się, aby zobaczyć kod



    Warunki ADCres < 300 oraz ADCres < 700 częściowo się pokrywają. Oba są spełnione dla <300.

    O negacjach już Ci pisano.

    Ile razy w trakcie jednego naciśnięcia przycisku wykona się przerwanie INT0?

    Na razie to tyle co zauważyłem, powodzenia :)

    A i jeszcze:
    nie:
    Kod: C / C++
    Zaloguj się, aby zobaczyć kod


    tylko:
    Kod: C / C++
    Zaloguj się, aby zobaczyć kod

    zresztą nie trzeba zerować jeśli wcześniej nie ustawiało się jedynek.
  • REKLAMA
  • #7 13841897
    szczywronek
    Poziom 28  
    Posty: 678
    Pomógł: 142
    Ocena: 217
    @pbuhne w dwóch miejscach się mylisz:
    1. Warunki nie będą się zazębiać. Jeśli będzie spełniony warunek "<300" to kolejny już nie będzie sprawdzany ("else if").
    2. Ze składnią przy ADMUX (pomijając zasadność zerowania wyzerowanych bitów i zamieniony operator) też jest wszystko ok.
  • #8 13841978
    pbuhne
    Poziom 15  
    Posty: 51
    Pomógł: 17
    No cóż, czas iść spać, skoro else nie widzę :) Sorry za wprowadzenie w błąd :)
  • #10 13842877
    Malin2000
    Poziom 9  
    Posty: 20
    Ocena: 3
    pbuhne:
    co do odczytu z ADC, to chciałem zrobić najpierw wszystko dokładnie z Datasheet'em by wiedzieć:) te inne tricki przyjdą z czasem.

    Jeżeli chodzi o ilość przerwań INT0 przy wciśnięciu przycisku to wykonuje się raz. Przerwanie ustawione jest by reagowało na zbocze opadające. Zatem, o ile nie będzie drgań styków, po naciśnięciu przycisku wykonywane jest raz. Żadnych zabezpieczeń przed drganiami styków nie robiłem, bo w sumie nie wiem jeszcze jak, a uruchomienie przerwania drugi raz nie będzie krytycznym błędem w programie testowym.

    A zeruje już wyzerowane rejestry, bo wtedy jestem absolutnie pewnym co tam jest i też w ramach nauki, by wiedzieć gdzie się ustawia np kanał odczytu. Te kilka taktów zegara nie są wielką stratą:)

    szczywronek
    tak, na schemacie jest błąd. tak to jest jak się szybko go robi:) tam przy diodach powinno być Vcc oczywiście zamiast GND :)

Podsumowanie tematu

✨ Użytkownik napotkał problem z działaniem ADC w mikrokontrolerze Atmega8, gdzie po włączeniu urządzenia jedynie diody LED1 i LED2 zapalają się po naciśnięciu przycisku. Po wskazaniu błędu w użyciu operatora negacji, użytkownik poprawił kod, co pozwoliło na uruchomienie programu, jednak nadal występowały problemy z odczytem wartości z potencjometru. Dyskusja dotyczyła różnic między negacją logiczną a bitową, a także poprawności odczytu z ADC oraz konfiguracji rejestrów. Użytkownicy zauważyli również błąd w schemacie podłączenia diod LED. Użytkownik planuje dalsze testy po podłączeniu wyświetlacza.
Podsumowanie AI na podstawie dyskusji. Może zawierać błędy.
REKLAMA