Hallo zusammen Ich habe einzelne Beispiele bei dem ich über den UART senden oder empfangen kann. Aber das Programm geht nicht. Ich will das auf den AVR schicken und dann den Wert verändert zurückbekommen. Einmal lief die Sache. Aber ich weiss nicht mehr warum. include "8515def.inc" .equ CLOCK = 6000000 .equ BAUD = 9600 .equ UBRRVAL = CLOCK/(BAUD*16)-1 .def temp = r16 rjmp Reset ;Reset vector reti ;Ext Int 0 reti ;Ext Int 1 reti ;Timer 1 Capt reti ;Timer 1 CompA reti ;Timer 1 CompB reti ;Timer 1 OVF reti ;Timer 0 OVF reti ;Serial Transfer Complete rjmp int_rxc;UART Rx Complete reti ;UART Data register empty rjmp int_txc;UART Tx Complete reti ;Analog Comparator Reset: ldi temp,LOW(RAMEND) ;LOW-Byte der obersten RAM-Adresse out SPL, temp ldi temp,HIGH(RAMEND) ;HIGH-Byte der obersten RAM-Adresse out SPH, temp ldi temp,UBRRVAL ;Baudrate einstellen out UBRR,temp sbi UCR, RXEN ;Interrupt für Empfangen vom PC sbi UCR, RXCIE ;Interrupt für Empfangen vom PC sbi UCR, TXEN ;Interrupt für Senden zum PC sbi UCR, TXCIE ;Interrupt für Senden zum PC ldi temp , 0b11000000 ;RXC=Aktiv, TXC=Aktiv out USR, temp ldi temp,0xFF out DDRB, temp ;Datenrichtung von Port B einstellen, 1 = Ausgang sei Main: sei Lupping: rjmp Lupping ;********************* Empfangen von PC ********************* int_rxc: in temp,SREG ;CPU-Status sichern push temp ;temp auf dem Stack sichern in temp, UDR ;später Wert ausgeben out PORTB, temp ;rcall int_txc pop temp ;temp aus dem Stack wieder herstellen reti ;Interrupt beenden ;********************* Empfangen von PC ********************* ;********************* Senden an PC ************************* int_txc: inc temp sbis UCR,UDRE ;Warten bis UDR für das nächste rjmp int_txc ;Byte bereit ist out UDR, temp reti ;********************* Senden an PC ************************* MfG Peter
Möglicherweise weil 'rcall int_txc' auskommentiert ist?
nach dem int_rxc: in tmp1, sreg push tmp1 ... pop tmp1 fehlt das out sreg, tmp1 hmm temp heist das hier, ich nenne es immer tmp1
Hallo Es geht immer noch nicht. Wo liegt der Fehler? Blöde Frage warum muss man das CPU-Register sichern? .include "8515def.inc" .equ CLOCK = 6000000 .equ BAUD = 9600 .equ UBRRVAL = CLOCK/(BAUD*16)-1 .def temp = r16 rjmp Reset ;Reset vector reti ;Ext Int 0 reti ;Ext Int 1 reti ;Timer 1 Capt reti ;Timer 1 CompA reti ;Timer 1 CompB reti ;Timer 1 OVF reti ;Timer 0 OVF reti ;Serial Transfer Complete rjmp int_rxc;UART Rx Complete reti ;UART Data register empty rjmp int_txc;UART Tx Complete reti ;Analog Comparator Reset: ldi temp,LOW(RAMEND) ;LOW-Byte der obersten RAM-Adresse out SPL, temp ldi temp,HIGH(RAMEND) ;HIGH-Byte der obersten RAM-Adresse out SPH, temp ldi temp,UBRRVAL ;Baudrate einstellen out UBRR,temp sbi UCR, RXEN ;Interrupt für Empfangen vom PC sbi UCR, RXCIE ;Interrupt für Empfangen vom PC sbi UCR, TXEN ;Interrupt für Senden zum PC sbi UCR, TXCIE ;Interrupt für Senden zum PC ldi temp , 0b11000000 ;RXC=Aktiv, TXC=Aktiv out USR, temp ldi temp,0xFF out DDRB, temp ;Datenrichtung von Port B einstellen, 1 = Ausgang sei Main: sei Lupping: rjmp Lupping ;********************* Empfangen von PC ********************* int_rxc: in temp,SREG ;CPU-Status sichern push temp ;temp auf dem Stack sichern in temp, UDR ;später Wert ausgeben out PORTB, temp pop temp out sreg, temp ;CPU-Status aus dem Stack wieder herstellen rcall int_txc reti ;Interrupt beenden ;********************* Empfangen von PC ********************* ;********************* Senden an PC ************************* int_txc: inc temp sbis UCR,UDRE ;Warten bis UDR für das nächste rjmp int_txc ;Byte bereit ist out UDR, temp reti ;********************* Senden an PC *************
beim aufruf einen interrupts - dafür sind sie da- wird der normal ablauf unterbrochen und der interrupt eingschoben. wenn du aber im normalen programm grad in einer berechnung bist und brauchst zB das carry flag oder sowas (die sind ja alle im SREG versammelt) musst du das sichern, bevor es in der interrupt routine verändert wird. hab mir das ganze nochmal genauer angeguckt (heut is nicht so spät :) das kann doch nicht gehen ;) ich würd da so machen: main: hier den Stack initiallisieren rcall uart_init loop: rjmp loop und hier die unterfunktionen UART_Init: ;Baudrate einstellen ldi tmp1, UART_fosc / (UART_Baud * 16)-1 out UBRR, tmp1 ;Baudrate in Register übertragen sbi UCR, TXEN ;TX (Senden) aktivieren sbi UCR, RXEN ;RX (Empfang) aktivieren sbi UCR, RXCIE ;bei Empfang Interrupt auslösen ret UART_SendByte: ;Warten, bis UDR für das nächste Byte bereit ist: sbis USR,UDRE rjmp UART_SendByte out UDR, prm1 ;das Byte aus prm1 Senden ret ;interrupt zum emfangen über uart UART_Int_rxc: ;SREG nicht gesichert, da nicht verändert push prm1 ;tmp1 retten in prm1, UDR rcall UART_SendByte ;hier das byte senden pop prm1 ;tmp1 wieder herstellen reti
Das rcall int_txc muss schon an der Stelle bleiben an der es auch vorher war, also bevor temp gepopt wird
ach ja: hab das sei vergessen nach dem Uart_init. und im komentar steht noch tmp1, dabei push ich prm1, aber das ja nich so wild. der interrupt tx ready ist dazu da, wenn du große datenmengen im ram ablegt und schnell senden möchtes wird nach der fertigen übertragung eines bytes der interrupt ausgelöst und du kannst sofort das nächste senden. so kannst du die uart maximal auslasten. tut hier aber ja nicht not... sach, wenn´s klappt
Hallo Danke für die Hilfe. Hier habe ich mein Beispiel so abgeändert dass es geht. MfG Peter .include "8515def.inc" .equ CLOCK = 6000000 .equ BAUD = 9600 .equ UBRRVAL = CLOCK/(BAUD*16)-1 .def temp = r16 rjmp Reset ;Reset vector reti ;Ext Int 0 reti ;Ext Int 1 reti ;Timer 1 Capt reti ;Timer 1 CompA reti ;Timer 1 CompB reti ;Timer 1 OVF reti ;Timer 0 OVF reti ;Serial Transfer Complete rjmp int_rxc;UART Rx Complete reti ;UART Data register empty rjmp int_txc;UART Tx Complete reti ;Analog Comparator Reset: ldi temp,LOW(RAMEND) ;LOW-Byte der obersten RAM-Adresse out SPL, temp ldi temp,HIGH(RAMEND) ;HIGH-Byte der obersten RAM-Adresse out SPH, temp ldi temp,UBRRVAL ;Baudrate einstellen out UBRR,temp sbi UCR, RXEN ;RX (Empfang) aktivieren sbi UCR, RXCIE ;bei Empfang Interrupt auslösen sbi UCR, TXEN ;TX (Senden) aktivieren ldi temp , 0b11000000 ;RXC=Aktiv, TXC=Aktiv out USR, temp ldi temp,0xFF out DDRB, temp ;Datenrichtung von Port B einstellen, 1 = Ausgang sei Main: sei loop: rjmp loop ;********************* Empfangen von PC ********************* int_rxc: in temp,SREG ;CPU-Status sichern push temp ;temp auf dem Stack sichern in temp, UDR ;später Wert ausgeben out PORTB, temp rcall int_txc pop temp out sreg, temp ;CPU-Status aus dem Stack wieder herstellen reti ;Interrupt beenden ;********************* Empfangen von PC ********************* ;********************* Senden an PC ************************* int_txc: sbis USR,UDRE rjmp int_txc inc temp out UDR, temp ;das Byte aus prm1 Senden ret ;********************* Senden an PC *************************
Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.