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

ST7Flite39 C RS232 z użyciem przerwań.

krzysztof-u 11 Cze 2009 23:18 1757 2
  • #1 6644916
    krzysztof-u
    Poziom 2  
    Witam.
    Zabrałem się za pisanie biblioteki do obsługi interfejsu SCI w ww. kontrolerze w języku C.
    Transmisja i odbiór są realizowane w przerwaniach. Tu mam problem. W procedurze obsługi przerwania wywołanego pojawieniem się odebranego znaku w buforze muszę skasować flagę przerwania (RDRF). Skasować ją można sekwencją:

    - odczyt SCISR
    - odczyt SCIDR

    Robię tak, ale po podejrzeniu wygenerowanego pliku asemblerowego rozdziela mi te dwie operacje innymi:
    w C robię tak:

    temp = SCISR;
    temp = SCIDR;

    W asm otrzymuję to:

    1823 ; 189 temp = SCISR;
    1825 01b4 96 ld x,s
    1826 01b5 b640 ld a,_SCISR
    1827 01b7 d70103 ld (OFST-1,x),a
    1828 ; 190 temp = SCIDR; //read data
    1830 01ba 96 ld x,s
    1831 01bb b641 ld a,_SCIDR
    1832 01bd d70103 ld (OFST-1,x),a

    Wie ktoś może jak to zrobić prawidłowo ?
    Myślałem o wstawce w asemblerze, ale nie wiem jak się odwołać do zmiennych zadeklarowanych przed nią w C.
  • #2 6676030
    jdoe77
    Poziom 2  
    Kilka pytań na początek:
    1. Jakiego kompilatora C używasz?
    2. Czy próbowałeś zmienić opcję kompilacji - zmienić poziom optymalizacji kodu (przykładowo w kompilatorze Raisonance - Optimization preference=Speed)?

    Mogę Ci podać przykład kodu w ASM wywoływany jako metoda w C dla kompilatora Raisonance - kawałek biblioteki obsługującej transmisję 1-Wire (dokładnie - metoda generująca opóźnienie). Plik z kodem (rozszerzenie *.asm) jest dodany bezpośrednio do projektu, jego zawartość:

    ; metoda generujaca opoznienie 
    ; parametr: A - opoznienie
    ; wyliczenie: A + 2,5 us 
    
    PUBLIC ?delay
    
        MYSEG SEGMENT CODE
        RSEG MYSEG
        
    ?delay:   
        
    loop:   NOP
            DEC A
            JRNE loop
            RET
    END


    natomiast odwołanie do metody delay - poprzez zadeklarowanie jej w kodzie:
    // wykorzystanie metody napisanej w ASM, dla obliczania opoznien
    extern void delay(unsigned char d) reentrant;


    W przypadku metod jednoparametrowych, (dokładniej - jednobajtowych) przekazanie parametru odbywa się poprzez rejestr A, tak samo przy zwracaniu wartości typu char (lub unsigned char). Więcej o tym jest w pliku pomocy do kompilatora (sekcja "Compiler internals").
  • #3 6676945
    krzysztof-u
    Poziom 2  
    Dzięki, już sobie poradziłem.
    Kompilator to Cosmic C.
    Najpierw zadeklarowałem zmienna globalna do której można się odwoływać we wstawkach asemblerowych poprzez _NAZWAZMIENNEJ i wykorzystałem wstawki, potem jednak doszedłem że instrukcje dostępu do SCISR i odczyt lub zapis SCIDR nie muszą być kolejno po sobie. Widać trochę nadinterpretowałem pdfa :) W każdym razie nadawanie oprogramowane w czystym C działa mimo rozdzielenia tych instrukcji innymi.

    W międzyczasie bawiłem się Raisonancem i doszedłem, że żeby używać wstawek w kodzie C, trzeba na początku pliku z kodem w C, wpisać komendę SRC powodująca wygenerowanie pliku ze źródłem w asm. Tyle że działa to podobno tylko w płatnej wersji i wróciłem do Cosmica.

    Pisania całej funkcji w asm i jej użycia w C jeszcze nie próbowałem (dla ST7) więc Twój przykład na pewno się przyda, dzięki.
REKLAMA