Elektroda.pl
Elektroda.pl
X
Proszę, dodaj wyjątek dla www.elektroda.pl do Adblock.
Dzięki temu, że oglądasz reklamy, wspierasz portal i użytkowników.

[ATtiny26] [ASM] uC wybiórczo wykonuje skoki. Dziwna praca.

26 Paź 2009 00:42 971 3
  • Użytkownik usunął konto  
  • Pomocny post
    Poziom 28  
    V541 napisał:


    Code:
    .INCLUDE "tn26def.inc" 
    
    CPI R18, 217 // Górny próg napięcia.
    BRSH JakasPetla1
    CPI R18, 217 // Jeśli poniżej, to wykonaj Petlę2 (która zgasi jedną, a zapali inną LED).
    BRLO JakasPetla2

    RJMP Petla_Glowna // Po tym program wykonuje się od początku (od samej góry, czyli "JakasInstrukcjaTestowa" będzie wykonana).
    .EXIT

    Co tu nie gra?


    Instrukcje BRSH i BRLO (równieź inne BRxx) nie są skokami ze śladem, tylko zwykłymi skokami warunkowymi. Nie mozna wracać z nich przez RET, bo się sypie stos.

    Pozdrawiam!
  • Użytkownik usunął konto  
  • Pomocny post
    Poziom 27  
    Wracać najlepiej skokiem bezwarunkowym, albo wywoływać je instrukcją call i wtedy z ret nie będzie problemów. Elegancko byłoby to mniej więcej tak:
    Code:

    .INCLUDE "tn26def.inc"
    .cseg
    .org 0x00
    LDI R20, RAMEND // Inicjalizacja Stosu (dla poprawnego działania skoków i pętli).
    OUT SP, R20
    RJMP Ustawienia // Program nie skacze do "Ustawienia", tylko wykonuje wszystko jak leci!

    JakasInstrukcjaTestowa //Ta instrukcja w tym miejscu programu nie powinna być nigdy wykonana, a jednak co by tu nie wstawić jest ciągle wykonywane (jakby było wewnątrz Petla_Glowna)!

    Czekaj: // Pętla tworząca opóźnienie w celu odczekania na koniec konwersji ADC.
    // Na pewno zrobiona dobrze (czeka ponad 100us, zwiększenie do 200us nic nie dało).
    RET

    JakasPetla1:
    // Gaszenie LED2, a zapalenie LED1.
    RET

    JakasPetla2:
    // Odwrotnie niż w pętli pierwszej (gasi LED1, a zapala LED2 i ona właśnie mruga po uruchomieniu uC).
    RET

    Ustawienia:
    // Ustawienie pinu 0 portu A jako wejścia. Pozostałe nóżki portu A, to wyjścia.
    LDI R16,0b11111110
    OUT DDRA,R16
    LDI R16, 0b01000000 // Wyłączenie wewnętrznych rezystorów "pull up" w portach.
    OUT MCUCR, R16
    SBI ADMUX, 5 // Wynik w rejestrze "ADC" (lewostronnie, czyli MSB w ADCH, reszta w ADCL).
    LDI R16, 0b00000011 // Dzielnik preskalera na 8, aby przetwornik działał dobrze.
    OUT ADCSR, R16      // Da to częstotliwość taktowania przetwornika 1MHz/8=125kHz.
    SBI ADCSR, 7 // Uaktywnienie przetwornika ADC.

    //==============================================================
    Petla_Glowna:

    SBI ADCSR, 6 // Start pojedynczej konwersji napięcia z pinu 20 (PA0, czyli ADC0).
    RCALL Czekaj // Czekanie na koniec konwersji, aby można było odczytać jej wynik.
    IN R18, ADCH // Tylko ADCH (czyli odczytanie 8-bitowego wyniku konwersji).

    CPI R18, 217 // Górny próg napięcia.
    BRLO mark1  //jeśli warunek jest spełniony to przeskakuje wywołanie JakasPetla1,
    rcall JakasPetla1  //stąd warunki są odwrotnie niż w Twoim programie
    mark1:
    CPI R18, 217 // Jeśli poniżej, to wykonaj Petlę2 (która zgasi jedną, a zapali inną LED).
    BRSH mark2
    rcall JakasPetla2
    mark2:

    RJMP Petla_Glowna // Po tym program wykonuje się od początku (od samej góry, czyli "JakasInstrukcjaTestowa" będzie wykonana).
    .EXIT


    Pamiętaj, że skok rjmp nie może przekraczać 2048 instrukcji do tyłu i 2047 instrukcji w przód.