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

wyjście z nieskończonej pętli while c++ avr atmega8

pawel26021995 21 Gru 2014 10:27 1908 8
REKLAMA
  • #1 14241753
    pawel26021995
    Poziom 12  
    Witam, mam problem z wyjściem z pętli while w żądanym czasie, program zawiesza się lub po prostu nie reaguje na odebrane dane, próbowałem na różne sposoby:
    Kod: text
    Zaloguj się, aby zobaczyć kod

    i nic nie pomogło, nie wiem jaki jest tu błąd. arvstudio nie wykazuje żadnych błędów podczas kompilacji.
    cały program wygląda następująco:
    Kod: text
    Zaloguj się, aby zobaczyć kod


    Z góry dzięki za pomoc.
  • REKLAMA
  • #2 14241789
    tmf
    VIP Zasłużony dla elektroda
    Zmienna data ma być zadeklarowana z modyfikatorem volatile. I to co stworzyłeś jest raczej w C a nie w C++. Wbrew pozorom różnice pomiędzy tymi językami są istotne.
  • REKLAMA
  • #3 14241806
    tehaceole

    Poziom 28  
    Co ja widzę?
    Ty Cały kod programu z dziesiątkami pętli nieskończonych i delay'i wrzuciłeś w kod obsługi przerwania?? Gratuluję pomysłowości... :)

    Po co stosując przerwanie od zakończenia transmisji używasz jeszcze jakiegoś USART_vReceiveByte(void) które miałoby sens gdybyś stosował polling. Nie prościej w
    Kod: text
    Zaloguj się, aby zobaczyć kod

    Przemyśl jeszcze raz całą koncepcję programu bo w tej chwili jest to skrajny przykład tego jak NIE NALEŻY PISAĆ. :)


    tmf czy zmienna ta musi być volatile? W tej chwili "data" nie jest używana poza przerwaniami. Imho - zwykła zmienna globalna z którą nie będzie (nie powinno być) problemu skoro nigdzie indziej jej nie używa.
  • #4 14241814
    witoldwitoldowicz
    Poziom 28  
    Tragedia! Sformatuj wcięcia, usuń goto, zmień pętle na np.
    Kod: C / C++
    Zaloguj się, aby zobaczyć kod
  • REKLAMA
  • #5 14241829
    666w
    Poziom 11  
    Dzień dobry

    Zgadzam się z poprzednikami i dodatkowo zalecam wrzucić to na symulator, podejrzeć wartość zmiennych i wyciągnąć wnioski. AvrStudio - w tym problem - nie zawsze wykazuje oczywiste błędy.
  • #6 14241852
    excray
    Poziom 41  
    Witam. Kolego pawel26021995 do wyjścia z pętli while() {..} powinieneś zastosować rozkaz break a nie continue.
  • #7 14241876
    pawel26021995
    Poziom 12  
    jeżeli napisze
    while(data==w1w)
    {
    PORTB = 0x00;
    PORTD = 0x00;
    PORTB = 0x04; //b1
    _delay_ms(d);
    PORTB = 0x00;
    PORTD = 0x00;
    _delay_ms(e);
    break
    }
    to pętla się wykonuje tylko raz, bez break pętla powinna wykonywać się do czasu gdy jest spełniony warunek a wykonuje się cały czas
  • REKLAMA
  • #8 14241882
    tmf
    VIP Zasłużony dla elektroda
    tehaceole napisał:
    WTF??????
    tmf czy zmienna ta musi być volatile? W tej chwili "data" nie jest używana poza przerwaniami. Imho - zwykła zmienna globalna z którą nie będzie (nie powinno być) problemu skoro nigdzie indziej jej nie używa.


    Masz rację, jakoś mi się uwidziało, że ISR się kończy zaraz po pobraniu danych, a dalej jest main. Oczywiście tak jak piszesz - najlepiej by było cały ten kod skasować i o nim zapomnieć i zabrać się za to jeszcze raz - tym razem porządnie.

    Dodano po 3 [minuty]:

    pawel26021995 napisał:
    jeżeli napisze
    while(data==w1w)
    {
    PORTB = 0x00;
    PORTD = 0x00;
    PORTB = 0x04; //b1
    _delay_ms(d);
    PORTB = 0x00;
    PORTD = 0x00;
    _delay_ms(e);
    break
    }
    to pętla się wykonuje tylko raz, bez break pętla powinna wykonywać się do czasu gdy jest spełniony warunek a wykonuje się cały czas


    Nie wiem co cię dziwi - po natrafieniu na break pętla jest przerywana. Natomiast ponieważ data w obrębie pętli się nie zmienia, to jeśli warunek data==w1w jest prawdziwy to jest prawdziwy zawsze, stąd nieskończona pętla.
    Swoją drogą jeśli stosujesz w programie stałe, to dobrą praktyką jest je zapisywać wielkimi literami, np. W1W, dzięki temu można łatwo je odróżnić od zmiennych.
  • #9 14244688
    tehaceole

    Poziom 28  
    pawel26021995 napisał:
    jeżeli napisze
    while(data==w1w)
    {
    PORTB = 0x00;
    PORTD = 0x00;
    PORTB = 0x04; //b1
    _delay_ms(d);
    PORTB = 0x00;
    PORTD = 0x00;
    _delay_ms(e);
    break
    }
    to pętla się wykonuje tylko raz, bez break pętla powinna wykonywać się do czasu gdy jest spełniony warunek a wykonuje się cały czas

    Pomyśl: co ma doprowadzić do zmiany warunku skoro nie robisz tego wewnątrz tej pętli? Co innego gdyby ten kod był umieszczony w głównej pętli programu a warunek zmieniałbyś w przerwaniu - wtedy jest szansa że mogłoby to zadziałać poprawnie. Ale tylko dla niektórych typów przerwań, których wystąpienie jest deterministyczne i pewne. Bo inaczej uzyskasz dokładnie to samo: CAŁKOWITE ZABLOKOWANIE PROGRAMU.

    Zainteresuj się takimi tematami jak programowanie "pseudowielowątkowe" czy też timery programowe.

    Co do Twojego kodu: to, że stosujesz co najmniej dziwne podejście do programowania to jedno. Ale znacznie gorsze jest to, że pchasz w przerwanie mnóstwo kodu. Każde przerwanie powinno wykonywać się najszybciej jak to jest tylko możliwe. Natomiast właściwa obsługa programu powinna znajdować się w pętli głównej. Oczywiście w pewnych specyficznych realizacjach zdarzyć się może, że pętla główna jako taka - nie występuje bo wszystko oparte jest o przerwania. Ale na pewno nie są w nich stosowane takie "potworki" jak u Ciebie.
REKLAMA