Hallo, ich verzweifel gerade etwas an einem kleinen ATmega8 evtl. hat hier jemand einen Rat oder Tipp was ich falsch mache oder übersehe. Schaltung wie hier im Tutorial mit folgendem Programm: ----------------------------------------------------------- .include "m8def.inc" .def temp = R16 .equ CLOCK = 3686411 .equ BAUD = 9600 .equ UBRRVAL = CLOCK/(BAUD*16)-1 .org 0x00 rjmp main .org URXCaddr ;Interruptvektor für UART-Empfang rjmp int_rxc ;Hauptprogramm main: ldi temp, LOW(RAMEND) out SPL, temp ldi temp, HIGH(RAMEND) out SPH, temp ; Baudrate einstellen ldi temp, LOW(UBRRVAL) out UBRRL, temp ldi temp, HIGH(UBRRVAL) out UBRRH, temp ; Frame-Format: 8 Bit ldi temp, (1<<URSEL)|(3<<UCSZ0) out UCSRC, temp sbi UCSRB, RXCIE ;Interrupt bei Empfang sbi UCSRB, RXEN ;RX (Empfang) aktivieren sbi UCSRB, TXEN ;TX (Senden) aktivieren ldi temp, 0x01 ;0x01 ins Arbeitsregister r16 laden out DDRC, temp ;Inhalt von r16 ins IO-Register DDRC ausgeben ldi temp, 0x01 out PORTC, temp ;PORTC auf 0x01 setzen -> Port PC0 sei ;Interrupts global aktivieren loop: cbi PINC, 0 ;An rcall wait ;warten sbi PINC, 0 ;aus rcall wait ;warten rjmp loop ;Endlosschleife ;Interruptroutine: wird ausgeführt sobald ein Byte über das UART empfangen wurde int_rxc: push temp ldi temp, 'H' rcall serout ldi temp, 'a' rcall serout ldi temp, 'l' rcall serout ldi temp, 'l' rcall serout ldi temp, 'o' rcall serout ldi temp, 10 rcall serout ldi temp, 13 rcall serout pop temp ; temp wiederherstellen reti ; Interrupt beenden serout: sbis UCSRA,UDRE ;Warten bis UDR für das nächste ;Byte bereit ist rjmp serout out UDR, temp ret wait: ; ============================= ; delay loop generator ; 18432000 cycles: ; ----------------------------- ; delaying 18431985 cycles: ldi R17, $A9 WGLOOP0: ldi R18, $92 WGLOOP1: ldi R19, $F8 WGLOOP2: dec R19 brne WGLOOP2 dec R18 brne WGLOOP1 dec R17 brne WGLOOP0 ; ----------------------------- ; delaying 15 cycles: ldi R17, $05 WGLOOP3: dec R17 brne WGLOOP3 ; ============================= ret ------ENDE------- Das Problem ist ich bekomme weder eine serielle Verbindung zum Controller noch blinkt Port PC0. Der Controller lässt sich mit YAAP einwandfrei beschreiben und auslesen. Guten Rutsch Reinhard
Blinken wird's so sicher nicht. PINC und PORTC verwechselt. Die Interrupt-Routine ist bemerkenswert - statt den Status zu retten, ein konsequenter Verzicht auf alle Befehle die was dran ändern ;-). Sieht man nicht oft.
Hallo, folgendermaßen würde ich die Interruptroutine noch abändern und wie oben schon gesagt noch statt PINC PortC schreiben. ;Interruptroutine: wird ausgeführt sobald ein Byte über das UART empfangen wurde int_rxc: push temp in temp,SREG ; Statusregister sichern push temp ; dito ldi temp, 'H' rcall serout ldi temp, 'a' rcall serout ldi temp, 'l' rcall serout ldi temp, 'l' rcall serout ldi temp, 'o' rcall serout ldi temp, 10 rcall serout ldi temp, 13 rcall serout pop temp1 ; Statusregister vom Stack holen out SREG, temp1 ; dito pop temp ; temp wiederherstellen reti Gruß
Man sollte sich solche Art der schlechten Interruptprogrammierung garnicht erst angewöhnen. Das verstößt nämlich gegen die ersten 3 Lehrsätze der Interruptprogramierung: 1. Halte Interrupts so kurz wie möglich 2. Halte Interrupts so kurz wie möglich 3. Halte Interrupts so kurz wie möglich Und serielle Ausgabezeiten nutzlos zu verwarten, gulpt hier schon stolze 19200 Zyklen kostbarer CPU-Zeit: 3686411 / 9600 10 5 Peter
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.