Wir haben in der Schule ein Board mit einem Atmega48. Dazu soll ich, bzw. darf ich ein kleines Programm schreiben, das die Funktion des UART im Atmega48 veranschaulichen soll. Ich hab mir dazu einfach den Code aus dem Tutorial genommen und mal ganz treudoof assembliert. Da es dann logischerweise Fehler gab, da der Code im Tutorial für ein Atmega8 ist, habe ich dann auch noch erkannt. Allerdgins bin ich mir nicht sicher, ob meine "Anpassungen" so richtig sind. Wenn ich das ganze ausprobieren will, passiert nix. Ich habe das Programm AVR-Stduio 4 und wollte den Beispielcode (Anhang) benutzen: .include "m48def.inc" .def temp = R16 .def temp1 = R17 .equ F_CPU = 8000000 ; Systemtakt in Hz .equ BAUD = 9600 ; Baudrate ; Berechnungen .equ UBRR_VAL = ((F_CPU+BAUD*8)/(BAUD*16)-1) ; clever runden .equ BAUD_REAL = (F_CPU/(16*(UBRR_VAL+1))) ; Reale Baudrate .equ BAUD_ERROR = ((BAUD_REAL*1000)/BAUD-1000) ; Fehler in Promille .if ((BAUD_ERROR>10) || (BAUD_ERROR<-10)) ; max. +/-10 Promille Fehler .error "Systematischer Fehler der Baudrate grösser 1 Prozent und damit zu hoch!" .endif .org 0x00 rjmp main .org URXCaddr rjmp int_rxc ; Hauptprogramm main: ldi temp, LOW(RAMEND) out SPL, temp ldi temp, HIGH(RAMEND) out SPH, temp ldi temp, 0xFF ; Port B = Ausgang out DDRB, temp ; Baudrate einstellen ldi temp, HIGH(UBRR_VAL) sts UBRR0H, temp ldi temp, LOW(UBRR_VAL) sts UBRR0L, temp ; Frame-Format: 8 Bit ldi temp, (3<<USBS0)|(1<<UCSZ00) sts UCSR0C, temp lds temp, UCSR0B ; Interrupt bei Empfang sbr temp, RXCIE0 sts UCSR0B, temp lds temp1, UCSR0B ; RX (Empfang) aktivieren sbr temp1, RXEN0 sts UCSR0B, temp1 sei ; Interrupts global aktivieren loop: rjmp loop ; Endlosschleife ; Interruptroutine: wird ausgeführt sobald ein Byte über das UART empfangen wurde int_rxc: push temp ; temp auf dem Stack sichern lds temp, UDR0 cpi temp, '1' ; empfangenes Byte mit '1' vergleichen brne int_rxc_1 ; wenn nicht gleich, dann zu int_rcx_1 cbi PORTB, 0 ; LED einschalten rjmp int_rxc_2 ; Zu int_rxc_2 springen int_rxc_1: cpi temp, '0' ; empfangenes Byte mit '0' vergleichen brne int_rxc_2 ; wenn nicht gleich, dann zu int_rcx_2 sbi PORTB, 0 ; LED ausschalten int_rxc_2: pop temp ; temp wiederherstellen reti Das Programm soll ein Signal das seriell über eine Terminalsoftware gesendet wird, auswerten und der Atmega soll eine LED schalten, je nach Zustand. Vielen Dank im Voraus. Pascal
@ Pascal Knies (Firma MHK) (pascal2002) >Dazu soll ich, bzw. darf ich ein kleines Programm schreiben, das die >Funktion des UART im Atmega48 veranschaulichen soll. Ich hab mir dazu >einfach den Code aus dem Tutorial genommen und mal ganz treudoof >assembliert. Ist ja erstmal nicht verwerflich ;-) >Allerdgins bin ich mir nicht sicher, ob meine "Anpassungen" so richtig >sind. Wenn ich das ganze ausprobieren will, passiert nix. AVR-Tutorial: UART http://www.mikrocontroller.net/articles/AVR_Checkliste#UART.2FUSART Interrupt Hehe, böser Fehler. Probiers mal so.
1 | lds temp, UCSR0B ; Interrupt bei Empfang |
2 | sbr temp, (1<<RXCIE0) |
3 | sts UCSR0B, temp |
4 | |
5 | lds temp1, UCSR0B ; RX (Empfang) aktivieren |
6 | sbr temp1, (1<<RXEN0) |
7 | sts UCSR0B, temp1 |
Siehe Bitmanipulation. MFG Falk
Hi Ersetze mal 'sbr temp, RXCIE0' durch 'sbr temp, 1<<RXCIE0' und 'sbr temp1, RXEN0' durch 'sbr temp1, 1<<RXEN0' 'sbr' erwartet eine Bitmaske, keine Bitnummer. MfG Spess
habs geändert, passiert aber trotzdem nichts. :( mit einem basic code gehts einwandfrei EDIT: jetzt geht es, allerdings so das bei 0 die LED leuchtet anstatt bei 1
@ Pascal Knies (Firma MHK) (pascal2002) >EDIT: jetzt geht es, allerdings so das bei 0 die LED leuchtet anstatt >bei 1 Logisch, die werden ja auch LOW aktiv angesteuert. MFG Falk
naja eigentlich will ich es aber anderstrum ^^
Pascal Knies wrote:
> naja eigentlich will ich es aber anderstrum ^^
Dann drehs halt um. Wo liegt das Problem?
hmm.....irgendwie bin ich zu doof dafür ^ muss ich da nicht einfach die zwei zeilen: cpi temp, '1' ; empfangenes Byte mit '1' vergleichen cpi temp, '0' ; empfangenes Byte mit '0' vergleichen umschrieben, das es so aussieht? cpi temp, '0' ; empfangenes Byte mit '1' vergleichen cpi temp, '1' ; empfangenes Byte mit '0' vergleichen mfg p.knies
Hi Ja. Oder du tauscht die Befehle 'cbi PORTB, 0' und 'sbi PORTB, 0'. MfG Spess
habs gefunden, was es war. hab jetzt sbi und cbi getauscht. int_rxc: push temp ; temp auf dem Stack sichern lds temp, UDR0 cpi temp, '1' ; empfangenes Byte mit '1' vergleichen brne int_rxc_1 ; wenn nicht gleich, dann zu int_rcx_1 sbi PORTB, 0 ; LED einschalten rjmp int_rxc_2 ; Zu int_rxc_2 springen int_rxc_1: cpi temp, '0' ; empfangenes Byte mit '0' vergleichen brne int_rxc_2 ; wenn nicht gleich, dann zu int_rcx_2 cbi PORTB, 0 ; LED ausschalten int_rxc_2: pop temp ; temp wiederherstellen reti
spess53 wrote: > Hi > > Ja. Oder du tauscht die Befehle 'cbi PORTB, 0' und 'sbi PORTB, 0'. > > MfG Spess ah danke....habe es auch gerade gemerkt ^^
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.