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

[Rozwiązano] [Atmega8] Odczyt wilgotności gleby - Czujnik, układ ADC i dioda na PD7

marcins1234 26 Lis 2022 21:34 522 5
REKLAMA
  • #1 20304915
    marcins1234
    Poziom 4  
    Dzień dobry
    Mam zbudowany taki magiczny układ:

    [Atmega8] Odczyt wilgotności gleby - Czujnik, układ ADC i dioda na PD7

    Próbuję nim odczytać wilgotność gleby za pomocą takiego oto czujnika:

    https://botland.com.pl/czujniki-wilgotnosci/1...MInrP75MvM-wIV7RJ7Ch2yRwb2EAQYAyABEgIq1vD_BwE

    Chińszczyzna, ale dotąd działało;) W każdym razie mam w nim podpięte VCC i GND, a wyjście analogowe do PC0 (ADC0). Dodatkowo w tym momencie mam podpiętą diodę pod PD7. Układ miałem złożony na atmega328 i działał poprawnie. Mam do tego płytkę, podmieniłem procesor w gnieździe, wgrałem program i działać przestało:( Możliwe, że coś zmieniałem jeszcze w programie, ale nie w obszarze odczytu z ADC.

    Program który przedstawię ma zapalić diodę na PD7, gdy nastąpi poprawny (jakikolwiek) odczyt z ADC. wygląda tak (uproszczony oczywiście, tylko żeby przybliżyć ideę i wskazać co nie działa):
    Kod: C / C++
    Zaloguj się, aby zobaczyć kod


    Funkcje do odczytu i inicjacji ADC zerżnięte z internetu oczywiście.

    Problem polega na tym, że w funkcji ReadADC jest linia z pętlą oczekującą na koniec pomiaru:

    while(!(ADCSRA & (1<<ADIF)));

    i ta pętla jest pętlą nieskończoną - co oznacza, że ADIF nie jest ustawiany na 1, według mojej skromnej wiedzy w tym zakresie.
    Środowisko którego używam to Microchip Studio (wcześniej Atmel Studio to było).

    Oczywiście gdy wywalę tą linię, to coś tam jest zwracane, ale nie jest to poprawna wartość

    Bardzo proszę o pomoc w tym zakresie, i odpowiedź na pytanie co zrobiłem źle i co mógłbym zrobić, aby to działało.

    Dodam jeszcze, że pomiar wykazał, że na wyjściu analogowym z czujnika pojawia się napięcie coś około 2.7V, i jest zależne od tego czy umieszczę go w ziemi mniej czy bardziej, więc czujnik jest sprawny. Wynik pomiaru po usunięciu pętli jest taki sam niezależnie od tego, czy czujnik jest podpięty czy nie.
  • REKLAMA
  • Pomocny post
    #2 20305143
    jarekgol
    Poziom 38  
    Wydaje mi się że wybieranie kanałów w ten sposób nie zadziała. Jak raz wpiszesz tam 7 (0b111) to już nie wrócisz na cokolwiek mniej, ale to nie nie tłumaczy twojego problemu. Spróbuj do ADCSRA wpisać stałą w ramach startu konwersji, a nie |=
    Zobacz czy numery bitów są dobrze tłumaczone, zgodnie z dokumentacją mega8.
    Jeśli faktyczne próby robisz na bardziej skomplikowanym programie, to stwórz nowy projekt i sprawdź na tym co tu faktycznie wkleiłeś.
    W ostateczności naskrob tylko to w czystym assemblerze i sprawdź.
    A i ja jeszcze w nich zawsze JTAG wyłączałem, ale teoretycznie to inne piny.
  • REKLAMA
  • #3 20305300
    bart-projects
    Poziom 29  
    Z dokumentacji:
    Cytat:
    A single conversion is started by writing a logical one to the ADC Start Conversion bit, ADSC. This bit
    stays high as long as the conversion is in progress and will be cleared by hardware when the conversion
    is completed.


    Zamień w tym While bit ADIF na ADSC

    Bit ADIF to bit przerwania po skończonej konwersji. Musi być albo skasowany "ręcznie" albo jest kasowny automatycznie, ale dopiero w obsłudze przerwania.

    Nie używasz przerwań to korzystasz z bitu ADSC który ma wartość 1 tak długo jak nie skonczy sie konwersja.

    U Ciebie to takie niezrozumienie zagadnienia. Jeśli włączyłes przerwania bitem ADEN to gdzie jest obsługa tego przerwania i globalne ich włączenie? Jak nie korzystasz z przerwań tylko czekasz to ADEN niepotrzebny.
  • REKLAMA
  • #4 20305662
    jarekgol
    Poziom 38  
    @bart-projects niby tak, ale nie do końca.
    1) ADEN to jest enable przetwornika, a nie przerwań. Uruchamia zegar przez preskaler itd.
    2) w tej samej dokumentacji jest napisane że flaga przerwania jest ustawiana na koniec konwersji - więc powinien mógł ją testować.
    3) gdyby autor miał problem z nieskasowaną flagą, to by mu program nie wisiał na tej pętli, tylko szedł dalej i najwyżej odbierał śmieci.
    4) w przytoczonym kodzie flaga jest kasowana ręcznie po wykryciu (z którym to wykryciem jest problem)

    Natomiast w przypadku takiego problemu, warto potestować flagę startu zamiast przerwania i zobaczyć co będzie.
  • REKLAMA
  • #6 20305789
    marcins1234
    Poziom 4  
    Dziękuję Panowie za odpowiedzi.
    jarekgol: Spróbowałem na tym programie który zamieściłem, żeby nie wyjść na debila potem, że błąd jest gdzie indziej;) Natomiast jeśli chodzi o asm, to zajmowałem się tym z 15 lat temu, jak dostałem jakiś program w turbo pascalu do przerobienia i okazało się, że tam są wstawki asseblerowe, ale to było raczej na zasadzie takiej, że cieszyłem się, że się udało;) W każdym razie Twoja odpowiedź o numerach bitów natchnęła mnie, o czym później;)
    bart-projects: To już wiemy co zmieniałem w tym programie, już byłem w takim stanie umysłu, że próbowałem wszystkie sposoby znalezione w internecie. Oryginalnie rzeczywiście był tam bit ADSC zamiast ADIF.

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


    Natomiast wracając do tematu wypowiedzi jarekgol o numerach bitów i dokumentacji atmega8. Okazało się, że wszystko fajnie, zmieniłem mikrokontroler na płytce, ale nie zmieniłem go w opcjach projektu:| W związku czym środowisko kompilowało nadal jakieś biblioteki dla Atmega328, który był w tym projekcie wcześniej, i w efekcie program pewnie korzystał z adresów dla tego mikroprocesora. Po zmianie w opcjach projektu na Atmega8 wszystko działa poprawnie.

    Jeszcze raz dziękuję Panowie za odpowiedzi:)
REKLAMA