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

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

mirekk36 13 Mar 2009 11:54 2247 4
  • #1 6275679
    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
  • Pomocny post
    #2 6275746
    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!!
  • #5 6308325
    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):

    .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ę:


    extern void sputchar(uint8_t AChar);


    no i dalej już w main :

    	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



    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

    uint8_t aa = 65;


    i wszystko chuuula ślicznie ;)

    (eclipse jest superek)
REKLAMA