Elektroda.pl
Elektroda.pl
X
Please add exception to AdBlock for elektroda.pl.
If you watch the ads, you support portal and users.

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

INTOUCH 05 Jul 2011 11:40 2874 29
phoenixcontact
  • #1
    INTOUCH
    Level 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.

    Code: c
    Log in, to see the code
  • phoenixcontact
  • #2
    dondu
    Moderator on vacation ...
    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ć :)
  • phoenixcontact
  • #3
    drzasiek
    CNC specialists
    To nie drgania styków, bo w pętli głównej nie widzę żadnego odwołania do funkcji
    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
    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
    dondu
    Moderator on vacation ...
    drzasiek wrote:
    To nie drgania styków, bo w pętli głównej 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
    drzasiek
    CNC specialists
    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
    dondu
    Moderator on vacation ...
    drzasiek wrote:
    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.

    Quote:
    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:
    if(PORF){
       komunikat Hello World
       PORF=0; //zgaś flagę
    }else{
       komunikat Reset nieznany
    }
    
    
  • #7
    INTOUCH
    Level 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

    Code: c
    Log in, to see the code
  • #8
    dondu
    Moderator on vacation ...
    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
    INTOUCH
    Level 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
    drzasiek
    CNC specialists
    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
    INTOUCH
    Level 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
    drzasiek
    CNC specialists
    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
    INTOUCH
    Level 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
    dondu
    Moderator on vacation ...
    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 wrote:
    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
    INTOUCH
    Level 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
    dondu
    Moderator on vacation ...
    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 wrote:
    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
    janbernat
    Level 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
    INTOUCH
    Level 30  
    Program bez przetwornika ADC.
    Program działa prawidłowo



    Code: c
    Log in, to see the code


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

    Code: c
    Log in, to see the code


    Dodano po 42 [minuty]:

    janbernat wrote:
    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
    janbernat
    Level 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
    nsvinc
    Level 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 :] )
    Code: text
    Log in, to see the code
  • #22
    michalko12
    MCUs specialist
    nsvinc wrote:
    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
    janbernat
    Level 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
    nsvinc
    Level 35  
    michalko12 wrote:
    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
    michalko12
    MCUs specialist
    nsvinc wrote:
    michalko12 wrote:
    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
    Code: c
    Log in, to see the code

    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:
    Code: c
    Log in, to see the code


    Code: c
    Log in, to see the code
  • #26
    nsvinc
    Level 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
    gaskoin
    Level 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
    nsvinc
    Level 35  
    gaskoin wrote:
    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 wrote:
    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
    gaskoin
    Level 38  
    Trochę się źle zrozumieliśmy z dzieleniem, mniejsza o to. :)
  • #30
    INTOUCH
    Level 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.