hallo!
bin noch anfänger in sachen assembler. habe ein beispiel prog fürs übertragen über RS232 gefunden.
hier:
die komentare sind von mir. können also auch falsch seinCode:.NOLIST .INCLUDE "D:\m32def.inc" .LIST .equ fck = 4000000 .equ baudrate = 4800 .equ baudconst = (fck / (baudrate * 16)) - 1 .def w = R19 ; Arbeitsregister .def wi = R20 ; Interrupt-Arbeitsregister .def rs_buf = R21 ; Buffer für empfangenes Byte .def a_flag = R25 ; Flagregister .equ rs_recv = 0 ; 1 = Byte empfangen - 0 = kein Byte empfangen ; Interrupt-Adressen .cseg .org $0000 rjmp main .org $0007 ; RS232 Empfangsinterrupt rjmp rs232_recv ; RS232 Behandlungsroutinge wenn etwas empfangen wird ; I/O-Port Initialisierung: hdw_init: ldi w, 0b11111111 out PORTD, w ; alle Pins am Port D auf 1 setzen ldi w, 0b11111110 out DDRD, w ; Datenrichtung am Port D festlegen: 1 = Ausgang; 0 = Eingang ; Pin 1 am Port D Empfangen (= 1) RX ; Pin 2 am Port D Senden (= 0) TX ldi w, 0b11111111 out PORTB, w ldi w, 0b11111111 out DDRB, w ; UART Initialisierung: uart_init: ldi w, baudconst out UBRRL, w ; UBRR = USART Baud Rate Register ldi w, 0 out UBRRH, w ldi w, 0b00011000 out UCSRB, w ; RXEN und TXEN setzen sbi UCSRB, RXCIE ; RS232 Interrupt freigeben ; PWM Initialisierung: pwm_init: ldi w, 0b10000001 out TCCR1A, w ldi w, 0 out OCR1AH, w ldi w, 1 out OCR1AL, w ldi w, 0b00000001 out TCCR1B, w sei ; gibt alle Interrups frei ret ; Behandlung für empfangene Bytes: rs_rec_up: cbr a_flag, 1 << rs_recv; durch '1<<' wird eine '1' n-mal nach links geschoben ; für rs_recv = 0: 0b00000001 ; für rs_recv = 1: 0b00000010 ; --> das erste bzw zweite Bit in a_flag wird somit gelöscht mov w, rs_buf ; empfangenes Byte in w out PORTB, w ; an Port B ausgeben ?(kein PWM)? out OCR1AL, w rcall rs_send ret rs_send: sbis UCSRA, UDRE ; überprüft, ob UDRE im Register UCSRA gesetzt ist, wenn ja (UDRE=1) überspringen ; UDRE = 1 Sender frei, UDRE = 0 Sender besetzt rjmp rs_send out UDR, w ret ; Interruptroutine wenn Bytes empfangen werden: rs232_recv: in wi, SREG ; CPU-Status push wi ; wi in Stackpointer in wi, UDR ; Byte vom Empfänger laden mov rs_buf, wi ; zwischenspeichern sbr a_flag, 1<<rs_recv ; durch '1<<' wird eine '1' n-mal nach links geschoben ; für rs_recv = 0: 0b00000001 ; für rs_recv = 1: 0b00000010 ; --> das erste bzw zweite Bit in a_flag wird somit gesetzt pop wi ; Stackpointer zurück in wi out SREG, wi ; zurück zur CPU reti ; Return from Interrupt main: ldi w, RAMEND ; RAMEND: Speicherende des Chips out SPL, w ; in Stackpointer schreiben clr a_flag rcall hdw_init ; Hardware Initialisierung endlos: sbrc a_flag, rs_recv rcall rs_rec_up ; wenn was empfangen wurde dann... rjmp endlos ; sonst warten![]()
geht man das prog schritt für schritt durch, springt er hier 'rcall hdw_init' in den initialisierungsteil. am ende von 'pwm_init:' steht ein 'ret'. an dieser stelle springt er aber dann nicht zurück zum 'rcall hdw_init' bzw in die endlosschleife, sondern springt ganz an den anfang zu: '.org $0000 rjmp main'
woran liegt das?
wird in 'main:' der stackpointer falsch beschrieben? was genau bedeutet denn RAMEND?
danke mal für eure geduld wenn ihr bis zum schluss gelesen habt! \/
freddy0815







Zitieren
Lesezeichen