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

AT90USB1287, assembler – obsługa przerwań, licznik i zapis czasu transmisji USART

klokos 24 Kwi 2013 21:49 1662 6
REKLAMA
  • #1 12236166
    klokos
    Poziom 11  
    Posty: 30
    Pomógł: 1
    Ocena: 3
    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.
  • REKLAMA
  • #2 12236371
    tmf
    VIP Zasłużony dla elektroda
    Posty: 14318
    Pomógł: 2090
    Ocena: 2205
    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.
  • REKLAMA
  • #3 12236500
    klokos
    Poziom 11  
    Posty: 30
    Pomógł: 1
    Ocena: 3
    przyznam się szczerze, że nie rozumiem.
  • #4 12236512
    BlueDraco
    Specjalista - Mikrokontrolery
    Posty: 6479
    Pomógł: 939
    Ocena: 421
    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.
  • REKLAMA
  • #5 12238115
    klokos
    Poziom 11  
    Posty: 30
    Pomógł: 1
    Ocena: 3
    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
  • REKLAMA
  • #6 12240116
    klokos
    Poziom 11  
    Posty: 30
    Pomógł: 1
    Ocena: 3
    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
  • #7 12256787
    Konto nie istnieje
    Konto nie istnieje  

Podsumowanie tematu

✨ Użytkownik pracuje z mikrokontrolerem AT90USB1287 i poszukuje pomocy w implementacji programu, który zlicza czas i konwertuje licznik na kod BCD, jednocześnie obsługując transmisję danych przez USART. W odpowiedziach zasugerowano różne podejścia do konwersji licznika, w tym bezpośrednie liczenie w BCD oraz przechowywanie cyfr w osobnych bajtach. Użytkownik zadał pytania dotyczące obsługi przerwań i konfiguracji timera, a także prosił o weryfikację swojego podejścia do implementacji. Otrzymał krytykę dotyczącą złożoności swojego kodu oraz wskazówki dotyczące poprawnej konfiguracji przerwań i timera.
Podsumowanie AI na podstawie dyskusji. Może zawierać błędy.
REKLAMA