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
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
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 *************************