Elektroda.pl
Elektroda.pl
X

Wyszukiwarki naszych partnerów

Wyszukaj w ofercie 200 tys. produktów TME
Europejski lider sprzedaży techniki i elektroniki.
Proszę, dodaj wyjątek elektroda.pl do Adblock.
Dzięki temu, że oglądasz reklamy, wspierasz portal i użytkowników.

Błędne wychodzenie z pętli do funkcji ATMEGA 32

INTOUCH 05 Lip 2011 11:40 2466 29
  • #1 05 Lip 2011 11:40
    INTOUCH
    Poziom 30  

    Wit mam.
    Piszę pewien program. Przed wejściem do pętli głównej programu napisałem funkcję w której użytkownik wstępnie nastawia parametry programu głównego.
    Problem polega na tym, że przy naciskaniu klawiszy program wychodzi mi z pętli głównej programu do funkcji w której nastawiane są parametry.
    Funkcja w której mają być nastawiane parametry okrojona jest do minimum. Wyświetla sam tekst na ekranie.
    Zastanawiam się czy błąd może wynikać z tego że pewne rejestry są nadpisywane.
    Przedstawię część kodu, więcej nie mogę.
    Piszę program w C pod ATMEGA 32 w AVRStudio.
    Watchdog wyłączony. W programie występują 3 przewiania:
    do timera , od timera 1 i od ADC.

    Kod: c
    Zaloguj się, aby zobaczyć kod

  • #2 05 Lip 2011 11:52
    dondu
    Moderator Mikrokontrolery Projektowanie

    Witaj

    1. stosuj tabulator bo kod jest mało czytelny.
    2. nie pokazałeś funkcji przerwań stąd zapytam: Drgania styków przycisków eliminujesz?:
    http://mikrokontrolery.blogspot.com/2011/04/przycisk-drgania-stykow-debouncing.html
    3. ode mnie masz 25 pkt za stosowanie C - boś biedny (2.88pkt), a mogą Ci się przydać :)

  • #3 05 Lip 2011 12:19
    drzasiek
    Specjalista - Mikrokontrolery

    To nie drgania styków, bo w pętli głównej

    Code:
    while(1)
    nie widzę żadnego odwołania do funkcji
    Code:
    NastawyParametrow( MAXWartoscSkutaczna);

    więc nawet jeśli drgania są, to przycisk będzie rozpoznawany jako naciśnięty kilkakrotnie ale to nie powinno powodować wywoływania ww funkcji??
    Widzę, że stosujesz w kodzie jakieś makra np
    Code:
    ISR_OUTTP_COMP2_DISABLED;
    itp a nie pokazałeś co one robią, czym je zastępujesz. Zobacz gdzie w kodzie masz jeszcze wywołanie tej funkcji? Może gdzieś przez przypadek skopiowałeś z czymś innym. Przeszukaj cały kod i zobacz, gdzie jeszcze ta funckcja się wywołuje. Jak znajdziesz, to szukaj powiązania z pętlą główną. Rozumiem, że nie chcesz pokazać całego kodu ale jeszcze trochę musisz pokazać, bo inaczej na ślepo kto ci pomoże.

  • #4 05 Lip 2011 12:30
    dondu
    Moderator Mikrokontrolery Projektowanie

    drzasiek napisał:
    To nie drgania styków, bo w pętli głównej
    Code:
    while(1)
    nie widzę żadnego odwołania do funkcji NastawyParametrow(MAXWartoscSkutaczna);[/code]
    więc nawet jeśli drgania są, to przycisk będzie rozpoznawany jako naciśnięty kilkakrotnie ale to nie powinno powodować wywoływania ww funkcji??

    Ponieważ jak napisałem wcześniej autor pokazuje tylko część programu nie pokazując ważnych funkcji przerwań, a program "jakby" zaczyna działać od początku (dodatkowy opis w kodzie), stąd wnioskuję, że właśnie drgania styków mogą być przyczyną wielokrotnych wywołań jakichś części programu których nie widzimy, i może np. dojść do przepełnienia stosu, albo innych nieprzewidzianych sytuacji,a w konsekwencji do resetu, czego autor może nawet nie zauważać z powodu zakomentowania LCD_WriteText("Hello!");

    Ale oczywiście to tylko hipoteza, więc czekam na odpowiedzi autora, choć napisał, że więcej kodu nie może pokazać :)

  • #5 05 Lip 2011 12:56
    drzasiek
    Specjalista - Mikrokontrolery

    To jest dobry pomysł. Na początku main(), zaraz po inicjalizacji LCD wrzuć funkcję wyświetlającą napis np "RESET" i będziesz wiedział, czy to funkcja się wywołuje czy uC się resetuje.

  • #6 05 Lip 2011 14:24
    dondu
    Moderator Mikrokontrolery Projektowanie

    drzasiek napisał:
    To jest dobry pomysł. Na początku main(), zaraz po inicjalizacji LCD wrzuć funkcję wyświetlającą napis np "RESET" i będziesz wiedział, czy to funkcja się wywołuje czy uC się resetuje.

    Można także wykorzystać flagi resetów z MCUCSR, a konkretnie bit PORF.

    Cytat:
    Bit 0 – PORF: Power-on Reset Flag
    This bit is set if a Power-on Reset occurs. The bit is reset only by writing a logic zero to the flag.
    To make use of the Reset Flags to identify a reset condition, the user should read and then reset
    the MCUCSR as early as possible in the program. If the register is cleared before another reset
    occurs, the source of the reset can be found by examining the Reset Flags.


    Pseudokod:
    Code:
    if(PORF){
    
       komunikat Hello World
       PORF=0; //zgaś flagę
    }else{
       komunikat Reset nieznany
    }

  • #7 05 Lip 2011 16:47
    INTOUCH
    Poziom 30  

    Witam.
    Po napisaniu poniższego kodu wyskakuje komunikat Reset nieznany
    Dalsza część kodu bez zmian.
    Eliminacja drgań przycisków jest przez opóźnienie: 60ms.
    Program mi się resetuje nadal nie znam przyczyny.
    Może wystąpić reset od przepełnienia stosu?


    ISR_OUTTP_COMP2_DISABLED //BLOKUJE PRZERWANIA OD CTC

    Kod: c
    Zaloguj się, aby zobaczyć kod

  • #8 05 Lip 2011 17:45
    dondu
    Moderator Mikrokontrolery Projektowanie

    Tak sądzę dlatego o tym pisałem, ale to może być błędne przypuszczenie.
    Musisz dokładniej przeanalizować program, może gdzieś w przerwaniu włączasz przerwania, albo jakaś pętla skoków do funkcji ... tysiąc powodów, lub jeden banalny :)

  • #10 05 Lip 2011 18:15
    INTOUCH
    Poziom 30  

    Całego ko du nie mogę bo to praca dypolowa.
    Zresztą szukam rozwiązania problemów a nie osoby która by mi pracę napisała.
    I tak część kodu szwęda się po elektrodzie.
    Poszczególne część programu (Obsługa przetw ADC, obsługa klawiszy, inne) działają bardzo dobrze jako osobne programy.
    Problem powstaje gdy na podstawie tych programów chcę zrobić jeden wielki.

    Takie problemy nie zdarzały mi się gdy pisałem większe programy pod WINOWS.

  • #11 05 Lip 2011 18:43
    drzasiek
    Specjalista - Mikrokontrolery

    Kiedy dokładnie wychodzi? Przy naciśnięciu któregokolwiek klawisza? Jeśli tylko jednego to którego? Przy szybkim? Wolnym naciskaniu? Powtarza się to za każdym razem identycznie czy różnie bywa?

  • #12 05 Lip 2011 18:53
    INTOUCH
    Poziom 30  

    Prz naciśnięciu dowolnego klawisza bywa różnie niezależnie czy naciskam szybko czy wolno.

    Podejrzewam, ze całym winowajcą może być nóżka PA7 na której jest napięcie około 3,6V.
    Na wszystkich pozostałych nóżkach portu PA jest napięcie około 0,6V.
    Cały port jest skonfigurowany jako przetwornik AC.

  • #13 05 Lip 2011 19:23
    drzasiek
    Specjalista - Mikrokontrolery

    A czym to zasilasz? Może masz "kiepskie" i nieodfiltrowane to zasilanie i jak zaczynasz klikać to się robią zakłócenia i się resetuje.

  • #14 05 Lip 2011 20:02
    INTOUCH
    Poziom 30  

    Układ PRO-Atmega32.
    Wątpię żeby był problem z zasilaniem.
    Szukam błędów i sprawdzam czy czasem procek nie uszkodzony.
    Jeżeli chodzi o o wersję programu z samymi klawiszami to żadne zakłócenia w programie nie występują.

    Dodano po 16 [minuty]:

    Wymieniłem mikrokontroler. Nadal te same błędy.

    Nie rozumiem też dla czego świeci mi się dioda na pinie PA7.
    Przecież cały port A jest wejściem

  • #15 05 Lip 2011 20:38
    dondu
    Moderator Mikrokontrolery Projektowanie

    1. Z całym szacunkiem dla Ciebie, ale gdybać i wróżyć z fusów nie będziemy (no chyba że ktoś ma wolny czas).
    Pytasz o napięcia, a schematu nie załączasz, a program tylko w częściach.
    Rozumie problem niemożliwości załączenia całości, ale Ty musisz zrozumieć, że my nie mamy materiałów do analizy.

    2. Gdzie konkretnie jest to opóźnienie?

    INTOUCH napisał:
    Eliminacja drgań przycisków jest przez opóźnienie: 60ms.

    Program wygląda na dość skomplikowany, a Ty używasz techniki wstrzymującej pracę mikrokontrolera tylko po to by walczyć z drganiami - nie tędy droga.
    Oczywiście nie twierdzą, że to jest przyczyną problemu.

  • #16 05 Lip 2011 20:50
    INTOUCH
    Poziom 30  

    Widzę, że uparliście się na te przyciski.
    Być może są jakieś przepięcia.
    60ms jest to opóźnienie w funkcji obsługującej klawisze.
    Może prześlę dwa osobne programy do analizy które działają prawidłowo.
    Jeżeli te dwa programy połączę ze sobą to wszystko zaczyna się sypać.
    Na podstawie tych dwóch programów chcę zrobić jeden. Jeżeli ktoś jest zainteresowany pomocą w rozwiązaniu problemu to wolę przez GG 5810320

  • #17 05 Lip 2011 21:01
    dondu
    Moderator Mikrokontrolery Projektowanie

    Kolego, chcesz pomoc czy masz zamiar długo bujać się z tym projektem?
    Owszem uparłem się i mam do tego podstawy, o których pisałem w postach powyżej.
    Jeżeli więc o coś proszę to odpowiedz dokładnie, bo taka odpowiedź jest mi do niczego nie potrzebna:

    INTOUCH napisał:
    Widzę, że uparliście się na te przyciski.
    60ms jest to opóźnienie w funkcji obsługującej klawisze.

    Sądzisz, że myślałem, iż to opóźnienie jest w funkcji odczytu ADC?

    Ja pomagam tylko na forum.

  • #18 05 Lip 2011 21:06
    janbernat
    Poziom 38  

    Od kiedy praca dyplomowa jest tajna?
    Pytam z ciekawości- kiedyś była jawna na całym etapie pisania.
    Dlaczego w pętli głównej blokujesz przerwania- potem wykonujesz sporo obliczeń- a potem odblokowujesz?
    A co będzie jak w tym czasie pojawią się dwa przerwania?
    Jedno pójdzie się kochać.
    Do tego wykorzystuje się ATOMIC_BLOCK jak naprawdę trzeba.
    Co kryje się pod LCD_Clear()?
    Bo jak prawdziwe clearLCD to ze 2ms zżera.
    Co kryje się pod ISR_OUTTP_COMP2_DISABLED?
    No i dlaczego korzystanie z elektrody masz traktować inaczej niż korzystanie z książki?
    W książkach jest czasem sporo błędów- a czasem nawet w DS.
    Tak jak i tu.
    Ale to chyba nie całkiem wyklucza książki, DS i forum.

  • #19 05 Lip 2011 21:57
    INTOUCH
    Poziom 30  

    Program bez przetwornika ADC.
    Program działa prawidłowo



    Kod: c
    Zaloguj się, aby zobaczyć kod


    Program tyko z przetwornikiem ADC Też działa prawidłowo

    Kod: c
    Zaloguj się, aby zobaczyć kod


    Dodano po 42 [minuty]:

    janbernat napisał:
    Od kiedy praca dyplomowa jest tajna?
    Pytam z ciekawości- kiedyś była jawna na całym etapie pisania.
    Dlaczego w pętli głównej blokujesz przerwania- potem wykonujesz sporo obliczeń- a potem odblokowujesz?
    A co będzie jak w tym czasie pojawią się dwa przerwania?
    Jedno pójdzie się kochać.
    Do tego wykorzystuje się ATOMIC_BLOCK jak naprawdę trzeba.
    Co kryje się pod LCD_Clear()?
    Bo jak prawdziwe clearLCD to ze 2ms zżera.
    Co kryje się pod ISR_OUTTP_COMP2_DISABLED?
    No i dlaczego korzystanie z elektrody masz traktować inaczej niż korzystanie z książki?
    W książkach jest czasem sporo błędów- a czasem nawet w DS.
    Tak jak i tu.
    Ale to chyba nie całkiem wyklucza książki, DS i forum.

    Praca dyplomowa jest tajna od kiedy za kopiuj wklej z forum można zostać posądzonym o plagiat.
    Nikomu na obronie i po obronie nie udowodnię że INTOUCH to mój pseudonim artystyczny.
    Jeżeli pojawią się w tym samym czasie dwa przerwania to zadziała to o najwyższym priorytecie. To o niższym priorytecie będzie czekać w kolejce.
    Książek do AVR mam z 10 W tym 4 do programowania mikrokontrolerów w języku C. Nawet z nich korzystam I co z tego skoro najwięcej praktycznych przykładów znalazłem na tym forum.

  • #20 05 Lip 2011 22:42
    janbernat
    Poziom 38  

    No dobrze- rozumiem że za moich czasów nie było kopiuj/wklej tylko znajdź w bibliotece/wypożycz/znajdź dziewczynę piszącą na maszynie/znajdź maszynę/dyktuj/sprawdź.
    Nie priorytet przerwań i nie dwa w tym samym czasie.
    Jakby tak się zdarzyło że dwa różne- to tak.
    Ale prawdopodobieństwo tego jest bardzo małe.
    Dlatego w AVR to chyba nikt nie próbuje tego uzywać.
    Chodzi o dwa- albo więcej przerwań przychodzących z jednego źródła.
    Jak przychodzi przerwanie to ustawia flagę przerwania.
    Jak jest ustawiona flaga zezwalająca na obsługę przerwania i globalne zezwolenie- to przerwanie jest obsłużone i flaga przerwania jest kasowana.
    Jak nie ma zezwolenia na obsługę przerwania- to ta flaga nie jest kasowana.
    Przychodzi następne przerwanie- z tego samego źródła i nic- bo poprzednie nie zostało obsłużone i flaga przerwania nie została skasowana.
    Dopiero odlokowanie globalnego przerwania pozwala na obsługę.
    Twój kod jest długi a ja w C jestem jeszcze krótki.
    Ale w rejestrach czuję się swobodniej niż w C.
    Może to?
    Pewnie się da to zmienić w sposobie deklaracji zmiennych albo w zakresie- ale choć spróbuję to na mojej znajomości C za bardzo nie polegaj.

  • #21 05 Lip 2011 23:02
    nsvinc
    Poziom 35  

    A pokaż może TEN kod, który NIE działa, zamiast załączać dwa kody które działają? I co my mamy sobie z tym zrobić? Nawet nie warto go zawijać do wlasnych projektow bo jest tragicznie napisany... Jak można tak pisać case'y w switch'u?...

    A zadam inne pytanie: co to za badziewny switch? Gdzie jest default:, gdzie jest zerowanie zmiennej k1? Dziwisz sie ze program idzie w krzaki?... Jak wciskasz przycisk, to zmienna k1 zostaje ustawiona na konkretny kod przycisku, i tak zostaje, wiec biedny procek wlazi w kółko w konkretnego case'a...
    Zeruj zmienną k1 pod switchem!!!

    Dostaw może tak nawiasy wokół case'ów? Czemu twoj kod jest...poplątany, i taki jakiś dziwny? Porównaj sobie może styl pisania, sprawdź co jest napisane poprawniej, twoje czy moje (a nie ukrywam, mam specyficzny styl pisania :] )

    Kod: C
    Zaloguj się, aby zobaczyć kod

  • #22 05 Lip 2011 23:22
    michalko12
    Specjalista - Mikrokontrolery

    nsvinc napisał:
    case LEDOPC_DELAYSH: //krutki delay


    Nie za krótko to ci działa ;)

    A tak poza tym to współczuję temu, kto miałby to po tobie przejąć. Masakra.

  • #23 05 Lip 2011 23:28
    janbernat
    Poziom 38  

    No i może:
    #define F_CPU 16000000UL //16MHz zegar procesora
    ustaw w opcjach projektu a nie w każdym pliku.
    I ten LCD_Clear() to jednak jest 2ms opóźnienia.
    Obsługa LCD jest od radzia.
    Działa- ale trzeba ostrożnie uzywać.
    Lepiej wpisać kilka pustych znaków.
    A skąd masz dziesięć książek o programowaniu AVR?
    W tym cztery w C?
    Bo mi się na półeczce nie zgadza.

  • #24 05 Lip 2011 23:37
    nsvinc
    Poziom 35  

    michalko12 napisał:
    A tak poza tym to współczuję temu, kto miałby to po tobie przejąć. Masakra.

    Nie rozumiem ;] Przecież jest napisane jasno i przejrzyście... A komentarze, cóż...są tu, gdzie ich potrzeba ;]

  • #25 05 Lip 2011 23:41
    michalko12
    Specjalista - Mikrokontrolery

    nsvinc napisał:
    michalko12 napisał:
    A tak poza tym to współczuję temu, kto miałby to po tobie przejąć. Masakra.

    Nie rozumiem ;] Przecież jest napisane jasno i przejrzyście... A komentarze, cóż...są tu, gdzie ich potrzeba ;]


    Co do ilości komentarzy nic nie mam, sam minimalizuje ich ilość, ich treść to styl indywidualny ;), ale takie tasiemce
    Kod: c
    Zaloguj się, aby zobaczyć kod

    to już masakra i do tego te wiele mówiące nazwy zmiennych.

    Szukanie błedów w czymś takim do przyjemności nie należy.

    Sam powiedz co lepiej wyglada:
    Kod: c
    Zaloguj się, aby zobaczyć kod


    Kod: c
    Zaloguj się, aby zobaczyć kod

  • #26 06 Lip 2011 11:22
    nsvinc
    Poziom 35  

    Oczywiście masz rację, drugi kod jest na pewno napisany bardziej zgodnie z zwinnym programowaniem ;] Aczkolwiek dla mnie jest mniej czytelny; z jakiegos powodu ja wolę czytać i pisać kod który jest "kompaktowy", a w drugim przykładzie mój pokładowy parser w mózgu musi pomijać masakryczną ilość spacji i crlf-ek... Dodatkowo, zauważ w jednej linijce zostala upakowana kompletna ewaluacja zmiennej ple9 - debuggując taki kod, wystarczy step-nąć przez jedną linijkę i zobaczyć ile ple9 wynosi, i od razu wiadomo czy dobrze, czy źle. Czytając taki kod, widać, że jedna konkretna linijka robi jedną konkretną rzecz - tutaj, oblicza ple9...

    Nie mówię tu, że mój styl jest jedyny wlasciwy, gorzej, wiem, ze jest nie do konca wlasciwy, ale po prostu tak jest dla mnie wygodniej i czytelniej... A nazwy zmiennych są dosyc dobrze opisane w miejscu ich deklaracji/definicji ;]
    A jak chce breakpointa w tasiemcu, to tasiemca rozwijam, sprawdzam czy dzieje sie to co powinno, a nastepnie zwijam z powrotem do czytelnej wersji :D
    Dodatkowa zaleta twojego przykladu to nabijanie linijek. Jakby rozwinąć mój kod który ma np. 2,5k linijek do "wlasciwego" stylu, to zrobi się z tego 10k linijek ;]

    Ale tak czy siak, kod przytoczony przez autora tematu i tak odrzuca - jest jakiś taki, nijaki. Swoj kod podalem jako przyklad "drugiego ekstremum".

  • #27 06 Lip 2011 11:53
    gaskoin
    Poziom 38  

    Tak wszystko ładnie pięknie, tylko masz potem milion linii kodu z nazwami typu khtok, sonq, zonq, duponq, kradsfj, adsnliaysg przeplatającymi się nawzajem. Co z tego, że są one świetnie udokumentowane przy deklaracji, skoro, jeżeli są to zmienne globalne to najprawdopodobniej ich deklaracja jest te 2500 linijek wyżej. Jakoś wygodniej się będzie czytało kod komuś z zewnątrz, jeżeli nie będzie musiał po nim skakać i tym bardziej nie będzie musiał czytać komentarzy i będzie rozumiał o co w nim chodzi. Nie przesadzajcie z tą kompaktowością, jeżeli kod staje się zbyt długi to jest to oznaka, że należy go podzielić na osobne pliki, tak samo jest z funkcjami, jak są za długie to trzeba je podzielić.

    Pokręcony kod autora wynika z tego, że za dużo on myśli i kombinuje pewnie :P

  • #28 06 Lip 2011 12:14
    nsvinc
    Poziom 35  

    gaskoin napisał:
    Tak wszystko ładnie pięknie, tylko masz potem milion linii kodu z nazwami typu khtok, sonq, zonq, duponq, kradsfj, adsnliaysg przeplatającymi się nawzajem.

    Przesadziłeś ;] Tak nazywam z reguły tylko i wyłącznie iteratory, bo samo 'i' jest zbyt nudne; lub zmienne lokalne zyjące tylko przez nastepne 10 linijek.

    gaskoin napisał:
    Nie przesadzajcie z tą kompaktowością, jeżeli kod staje się zbyt długi to jest to oznaka, że należy go podzielić na osobne pliki, tak samo jest z funkcjami, jak są za długie to trzeba je podzielić.

    Tak, trzeba. A potem masz 50 poplątanych ze sobą plików, milion deklaracji extern glownie licznikow i co gorsza struktur, i jak zmienisz taka strukture w jednym pliku, to potem trzeba ją zmienić w wszystkich innych plikach gdzie jest extern. Każdy plik ma swoj .h, w ktorym dodatkowo sa jakies typedefy, definy i inne badziewie, konczy sie tym, ze wszystko includuje wszystko i jest 10x wiekszy bajzel niz jakby caly kod byl w jednym pliku. Kiedyś próbowałem dzielić kod na siłę na kilka plików, powstał nieczytelny bełkot. Oczywiście można pisać interfejsy, ktore informacje z A przeniosą do B, ale po co dodatkowa funkcja kopiująca w pętli głównej, która zmarnuje czas i potencjalnie naruszy koherencję komunikacji A z B... Na pc można tak pisać, bo nikt nie zauwazy roznicy, ale mikrokontroler rozliczy cię z każdej zmarnowanej mikrosekundy.

    Zauwaz ze pliki dzieli się na konkretne zestawy funkcjonalnosci - skoro dany zestaw wymaga n linijek, to niech te n linijek bedzie juz w jednym pliku, i mniejsza o jego długość...

  • #29 06 Lip 2011 12:42
    gaskoin
    Poziom 38  

    Trochę się źle zrozumieliśmy z dzieleniem, mniejsza o to. :)

  • #30 12 Lip 2011 18:05
    INTOUCH
    Poziom 30  

    Szanowny kolego gaskoin.
    Poszedłem za twoją radą i zacząłem dzielić swój program na pliki.
    NA początek zrobiłem test.
    1. W jednym pliku zawarty jest cały kod wraz z obsługą wyświetlacza.
    Ten kod działa poprawnie.

    2. Ten kod podzieliłem na 3 pliki:
    main.c
    hd44780.c
    hd44780.h

    Przypadek pierwszy działa bezbłędnie.
    W przypadku drugim jakieś głupoty pojawiają mi się na ekranie.
    Wszystko sprawdzałem w AVRStudio4 oraz po małych przeróbkach w ścieżce dostępu do plików w Eclipse i AVRStudio5

    Dla porównania przesyłam dwie wersje tego samego programu dla AVRStudio4.
    Czy mógłby mi szanowny kolega wytłumaczyć dlaczego wersja wieloplikowa nie działa poprawnie?
    Układ PRO-ATMEGA32.
    Takie same błędy są gdy stosuję bibliotekę Pana Mirka

    Program po skompilowaniu projektu wieloplikowego zajmuje 8 bajtów mniej.
    Jakby zjadło gdzieś te 8 bajtów.

TME logo Szukaj w ofercie
Zamknij 
Wyszukaj w ofercie 200 tys. produktów TME
TME Logo