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

Atmel - obsługa przerwań, assembly

klokos 24 Kwi 2013 21:49 1356 6
  • #1 24 Kwi 2013 21:49
    klokos
    Poziom 9  

    Cześć, mam takie zadanie, w sumie nie tyle chciałbym żeby ktoś mi je rozwiązał co poprowadził. Korzystam z AT90USB1287 ale nie ma to dla mnie większego znaczenia później przełożyć taki program jeśli propozycje będą na inne :)
    Jestem totalnym amatorem na poziomie migiania diodek, więc proszę o wyrozumiałość.
    ------------------------------------------------------------------------------
    Zadanie:

    W programie co określony czas zwiększany jest licznik programowy, a jego wartość jest konwertowana na kod BCD w celu wyświetlenia.
    Jednocześnie odbierana jest transmisja danych z USART - dane pojawiają się w różnych odstępach czasu.
    W tablicy czasy_transmisji notowany jest stan licznika programowego w chwili transmisji. Załóżmy, że:
    - konwertuj_na_BCD_i_wyswietl jest zdefiniowane i czasochłonne
    - inicjalizuj_USART oraz obsluga_przerwan_USART_i_zapis_do_tablicy są zdefiniowane.
    Zadaniem jest jest więc stosunkowo proste(ehe, chyba nie dla mnie): napisz obsługę licznika programowego (w tym wywołanie konwersji na BCD) z wykorzystaniem systemu przerwań timera, tak aby
    zminimalizować ryzyko utracenia danych z USART i przekłamań w tablicy czasy_transmisji.
    ------------------------------------------------------------------------------
    Czyli rozumiem to tak, chodzi sobie timer, cały czas jest konwertowany na BCD(pojedyncze cyfry) i wyświetlany. USART będzie wykorzystywany tylko jako odbiornik. Czyli jest uruchomiony licznik i odbiornik, przychodzi sygnał do odbiornika, uruchamiane jest przerwanie, licznik wrzuca swój krok do tablicy i wraca do dalszego liczenia? O to chodzi?

    Program:

    Cytat:
    .include "m32def.inc"

    .cseg
    .org 0 jmp restart;
    .org 0x002A rjmp timer;
    .org 0x0032 rjmp usart;

    start: // ustawienie stosu
    cli //wyłączenie przerwań
    ldi R16, HIGH(RAMEND)
    out SPH, R16
    ldi R16, LOW(RAMEND)
    out SPL, R16
    sei //właczenie przerwan



    od tego zaczynam, (szkoda że większość pomocy jest napisana w C), chętnych do pomocy zapraszam do tematu, natomiast tych którzy chcieliby pomóc bardziej
    można walić na pw.

    0 6
  • #2 24 Kwi 2013 22:28
    tmf
    Moderator Mikrokontrolery Projektowanie

    A może inaczej. Konwersja BIN->BCD jest czasochłonna, więc może od razu liczyć w BCD? Korekta dla BCD przy inkrementacji binarnej jest banalna, a AVR ma flagę przeniesienia z młodszej tetrady, co ułatwia liczenie. Przerwanie odbioru USART przepisuje wartość licznika do tablicy i tyle.

    0
  • #3 24 Kwi 2013 22:54
    klokos
    Poziom 9  

    przyznam się szczerze, że nie rozumiem.

    0
  • #4 24 Kwi 2013 22:57
    BlueDraco
    Specjalista - Mikrokontrolery

    Jeszcze prościej: trzymaj ten licznik w postaci tylu bajtów, ile masz cyfr dziesiętnych - po jednej cyfrze w bajcie. Inkrementacja takiego licznika jest całkiem szybka, a jego zawartość jest stale gotowa do wyświetlenia.

    0
  • #5 25 Kwi 2013 14:16
    klokos
    Poziom 9  

    coś w ten deseń?

    na razie chodzi mi o to że:
    Licznik działa zgodnie z zegarem.
    Po przepełnieniu występuje przerwanie, a jego obsługa skacze do timera i uruchamia go na nowo.
    cały czas nasłuchuje usart i gdy nadejdzie przerwanie, to obsługa wrzuca z tcnt(czyli wartość licznika) do tablicy
    coś z tego ma sens?

    Cytat:
    .include "m32def.inc"

    .cseg
    .org 0 jmp restart;
    .org 0x002A rjmp timer_restart;
    .org 0x0032 rjmp usart_wykonaj;

    start: // ustawienie stosu
    cli //wyłączenie przerwań
    ldi R16, HIGH(RAMEND)
    out SPH, R16
    ldi R16, LOW(RAMEND)
    out SPL, R16
    sei //właczenie przerwan

    timer:
    ldi r17, 1<<CS02
    out TCCR0, r17
    in r16, TIMSK //tryb normalny
    sbr r16, 1<<TOIE0
    out TIMSK, r16 //przerwanie od przepełnienia

    timer_restart:
    jmp timer
    reti

    //inicjalizacja przerwania usart

    usart_wykonaj:
    mov r20, TCNT0
    r20 wrzuc do tablicy
    reti




    edit: poprawka, możliwe że ma większy sens
    Cytat:
    .include "m32def.inc"

    .cseg
    .org 0 jmp restart;
    .org 0x002A rjmp timer_restart;
    .org 0x0032 rjmp usart_wykonaj;

    start: // ustawienie stosu
    cli //wyłączenie przerwań
    ldi R16, HIGH(RAMEND)
    out SPH, R16
    ldi R16, LOW(RAMEND)
    out SPL, R16
    sei //właczenie przerwan

    ldi r17, 1<<CS02
    out TCCR0, r17
    in r16, TIMSK //tryb normalny
    sbr r16, 1<<TOIE0
    out TIMSK, r16 //przerwanie od przepełnienia

    //inicjalizacja przerwania usart

    timer_restart:
    ldi TCNT0, 0
    reti

    usart_wykonaj:
    mov r20, TCNT0
    tablica<<r20 //wrzucamy do tablicy r20
    reti

    0
  • #6 25 Kwi 2013 22:44
    klokos
    Poziom 9  

    podbiję, temat.

    Ktoś mógłby sprawdzić czy to jest w miarę akceptowalne? Z góry dzięki.

    Cytat:
    .include "m32def.inc"

    .cseg
    .org 0 jmp restart;
    .org 0x002A rjmp timer_restart;
    .org 0x0032 rjmp usart_wykonaj;

    start: // ustawienie stosu
    cli //wyłączenie przerwań
    ldi R16, HIGH(RAMEND)
    out SPH, R16
    ldi R16, LOW(RAMEND)
    out SPL, R16
    sei //właczenie przerwan

    ldi r17, 1<<CS02
    out TCCR0, r17
    in r16, TIMSK //tryb normalny
    sbr r16, 1<<TOIE0
    out TIMSK, r16 //przerwanie od przepełnienia

    {
    //inicjalizacja przerwania usart
    }

    main:
    {
    konwertuj_na_BCD_i_wyswietl << TCNT0
    }
    rjmp main


    timer_restart:
    ldi TCNT0, 0
    reti


    usart_wykonaj:
    tablica << TCNT0 //wrzucamy do tablicy TCNT0
    reti

    0
  • #7 30 Kwi 2013 20:22
    30402
    Użytkownik usunął konto