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.

[atmega][C]-Jak moża dołączyć do projektu plik asm

mirekk36 13 Mar 2009 11:54 2031 4
  • #1 13 Mar 2009 11:54
    mirekk36
    Poziom 42  

    Witam,

    Gdzieś kiedyś czytałem - ale że dawno (znowu) nie robiłem nic w C to jakoś mi to umknęło - a wiem, że można - hmmm chyba

    chodzi mi oto aby można było napisać sobie funkcję w asemblerze - a później korzystać z niej AVR GCC wywołując ją z paramertami.

    Dokładniej mówiąc znalazłem fajną notę AVR304 - to jest software UART, niewiele linijek kodu - a będzie mi to bardzo potrzebne. Po prostu zależy mi nawet tylko na wysyłaniu przez UART ale bez użycia żadnych dodatkowych przerwań, timerów itp. Jak dotąd znalazłem takie rozwiązanie tylko w tej nocie AVR.

    Pomoże mi ktoś - tzn przypomni jak można ożenić oddzielny plik asm z C. Zaznaczam, że nie chodzi mi tu o pisanie wstawki asm w C.

    Pozdrawiam

    0 4
  • Pomocny post
    #2 13 Mar 2009 12:14
    Freddie Chopin
    Specjalista - Mikrokontrolery

    piszesz funkcje w ASM pamietajac o tym ktore rejestry uzywane sa do przekazywania parametrow, ktore mozesz zmienic, a ktore musisz zachowac (instrukcja do kompilatora gcc wyjasnia ta kwestie, jest to rowniez poruszone w FAQ dla AVR-GCC). dolaczasz do projektu plik naglowkowy, w ktorym podajesz prototyp funkcji:

    extern uint8_t funkcja(uint8_t parametr);

    przy czym zalozylem, ze funkcja przyjmuje uint8_t i zwarca uint8_t - oczywiscie moze byc inaczej. nazwa funkcj (tu: funkcja) musi byc taka sama jak etykieta funkcji w assemblerze.

    plik assemblerowy musi byc w specjalny sposob skompilowany - do postaci obiektu ".o".

    4\/3!!

    0
  • #3 13 Mar 2009 14:59
    mirekk36
    Poziom 42  

    Freddie Chopin -> bardzo dziękuję, dzisiaj wieczorkiem potrenuję sobie z tym. Jak coś to najwyżej jeszcze dopytam.

    Pozdrawiam

    0
  • #4 13 Mar 2009 15:02
    Freddie Chopin
    Specjalista - Mikrokontrolery

    pytaj i napisz wtedy od razu czy kompilujesz to w avrstudio czy w eclipse z wtyczka dla AVR.

    4\/3!!

    0
  • #5 20 Mar 2009 17:51
    mirekk36
    Poziom 42  

    Witam,

    właśnie dopiero teraz to wszystko sprawdzam. Oczywiście piszę wszystko w eclipse. Stworzyłem sobie dodatkowy plik z rozszerzeniem *.S i napisałem swoją funkcję w asemblerze

    eclipse - ślicznie mi wszystko kompiluje tylko hmm mam jeszcze kłopot z przekazywaniem parametru(-ów)

    tzn wyczytałem gdzieś, że parametry przekazywane są przez pary rejestrów począwszy od R25:R24

    jeśli więc do mojej funkcji przekazuję tylko jeden parametr 8 bitowy to zdaje się że w asemblerze powinienem wczytać zawartość rejestru R24 do dalszej obróbki - no ale tu coś mi szwankuje

    generalnie ma to być funkcja (software uart):

    Code:
    .global sputchar
    

    sputchar:

          push   R16
          push   R17
          push   R18
          push   R19

          mov      R18, R24 -- tak nie działa
          ldi      R18, 65  --- tak działa

          ldi   r16,9+1   ;1+8+sb (sb is # of stop bits)
          com   r18      ;Inverte everything
          sec         ;Start bit

    putchar0:
          brcc   putchar1   ;If carry set
          cbi      _SFR_IO_ADDR(PORTD), 1   ;    send a '0'
          rjmp   putchar2   ;else

    putchar1:
          sbi   _SFR_IO_ADDR(PORTD), 1   ;    send a '1'
          nop

    putchar2:
          rcall UART_delay   ;One bit delay
          rcall UART_delay

          lsr      r18      ;Get next bit
          dec      r16      ;If not all bit sent
          brne   putchar0   ;   send next
                   ;else

          pop      R19
          pop      R18
          pop      R17
          pop      R16
          ret         ;   return


    UART_delay:
          ldi      r17, 135
    UART_delay1:
          dec      r17




          brne   UART_delay1

          ret


    a później w kodzie mam jej deklarację:


    Code:
    extern void sputchar(uint8_t AChar);


    no i dalej już w main :

    Code:
       DDRD SET (1<<1);
    
       PORTD SET (1<<1);

       while (1)
       {
          uint8_t aa;
          sputchar(aa);
          mkdelay_ms(950);
          //_delay_ms(250);
       }


    i oczywiście przekazywany parametr mi nie działa ale jak w asemblerowej funkcji "ręcznie" załaduję do R18 np kod literki A czyli 65 to ładnie wyświetla A na terminalu

    gdy natomiast mam w funkcji asemblerowej

    Code:
    mov R18, R24


    to kiszeczka :(

    Dodano po 8 [minuty]:

    sorki, sorki - już mi wszystko działa prześlicznie ;) no bo amba mi wcięła inicjalizację mojej zmiennej aa , którą przekazywałem jako parametr przecież. Czyli przekazywane było ZERO przez co nic nie pojawiało się na terminalu

    teraz mam

    Code:
    uint8_t aa = 65;


    i wszystko chuuula ślicznie ;)

    (eclipse jest superek)

    0