STACK-Init, etc, pp. SERIIELLE AUSGABE an PIN0 vom PORTB ; Lösche Display ldi r17, 0x0C rcall TX_UART ldi r17, 0x47 rcall TX_UART ; Leerlaufschleife (wird von Interrupt unterbrochen) LOOP: rcall LOOP ; Software UART Routine für 9600Kbaud, 8N1 ; Ankommendes Register r17 enthält das zu sendende Zeichen TX_UART: ; Sende Startbit cbi PORTB, PB0 ; Setze Bit 0 von PORTB auf Low nop ; 1 | Ausgleichstakt rcall WAIT_UART ; 3 | Ruhepause für das nächste Bit ; zählerroutine für die 8 Bits eines Bytes ldi r16, 0x07 ; 1 |Lade 0x08 (8) nach Register r16 NEXT_BIT: dec r16 ; 1 | Erniedrige Register r16 um breq UART_FIN ; 1/2 | Springe zu UART_FIN wenn Register r16 = 0 ; Teste ob zu sendendes Bit 1 oder 0 ist sbrc r17, 0 ; 1/2 | Überspringen den nachfolgenden Befehl, wenn Bit 0 von Register r16 = 0 rjmp HIGH_BIT ; 2 | Springe zu HIGH_BIT (zu sendendes Bit ist "1") nop ; 1 | Ausgleichstakt rjmp LOW_BIT ; 2 | Springe zu HIGH_BIT (zu sendendes Bit ist "0") ; Sende Low-Bit "0" LOW_BIT: nop ; 1 | Ausgleichstakt nop ; 1 | Ausgleichstakt nop ; 1 | Ausgleichstakt nop ; 1 | Ausgleichstakt nop ; 1 | Ausgleichstakt nop ; 1 | Ausgleichstakt nop ; 1 | Ausgleichstakt nop ; 1 | Ausgleichstakt nop ; 1 | Ausgleichstakt nop ; 1 | Ausgleichstakt nop ; 1 | Ausgleichstakt nop ; 1 | Ausgleichstakt nop ; 1 | Ausgleichstakt nop ; 1 | Ausgleichstakt nop ; 1 | Ausgleichstakt nop ; 1 | Ausgleichstakt rcall WAIT_UART ; 3 | Ruhepause für das nächste Bit rjmp ROLL_BIT ; 2 | Springe zu ROLL_BIT ; Sende High-Bit "1" HIGH_BIT: sbi PORTB, 0 ; 2 | Setze Bit 0 von PORTB auf High nop ; 1 | Ausgleichstakt nop ; 1 | Ausgleichstakt nop ; 1 | Ausgleichstakt nop ; 1 | Ausgleichstakt nop ; 1 | Ausgleichstakt nop ; 1 | Ausgleichstakt nop ; 1 | Ausgleichstakt nop ; 1 | Ausgleichstakt nop ; 1 | Ausgleichstakt nop ; 1 | Ausgleichstakt nop ; 1 | Ausgleichstakt nop ; 1 | Ausgleichstakt nop ; 1 | Ausgleichstakt nop ; 1 | Ausgleichstakt nop ; 1 | Ausgleichstakt nop rcall WAIT_UART ; 3 | Ruhepause für das nächste Bit rjmp ROLL_BIT ; 2 | Springe zu ROLL_BIT ; Rotiere Bitfolge ROLL_BIT: ror r17 ; 1 | Rotiere Bitfolge im Register r16 um ein Bit nach rechts rjmp NEXT_BIT ; 2 | Bearbeite nächstes Bit vom zu sendenen Byte UART_FIN: ; Sende Paritätsbit (odd) nop ; 1 | Ausgleichstakt nop ; 1 | Ausgleichstakt sbi PORTB, PB0 ; 2 | Setze Bit 0 von PORTB auf High nop ; 1 | Ausgleichstakt nop ; 1 | Ausgleichstakt nop ; 1 | Ausgleichstakt nop ; 1 | Ausgleichstakt nop ; 1 | Ausgleichstakt nop ; 1 | Ausgleichstakt nop ; 1 | Ausgleichstakt nop ; 1 | Ausgleichstakt nop ; 1 | Ausgleichstakt nop ; 1 | Ausgleichstakt nop ; 1 | Ausgleichstakt nop ; 1 | Ausgleichstakt nop ; 1 | Ausgleichstakt nop ; 1 | Ausgleichstakt nop ; 1 | Ausgleichstakt nop ; 1 | Ausgleichstakt nop ; 1 | Ausgleichstakt nop ; 1 | Ausgleichstakt nop ; 1 | Ausgleichstakt nop ; 1 | Ausgleichstakt nop ; 1 | Ausgleichstakt nop ; 1 | Ausgleichstakt nop ; 1 | Ausgleichstakt nop ; 1 | Ausgleichstakt nop ; 1 | Ausgleichstakt nop ; 1 | Ausgleichstakt nop ; 1 | Ausgleichstakt nop ; 1 | Ausgleichstakt rcall WAIT_UART ; 3 | Ruhepause für das nächste Bit ; Sende Stopbit nop ; 1 | Ausgleichstakt nop ; 1 | Ausgleichstakt nop ; 1 | Ausgleichstakt nop ; 1 | Ausgleichstakt nop ; 1 | Ausgleichstakt nop ; 1 | Ausgleichstakt nop ; 1 | Ausgleichstakt nop ; 1 | Ausgleichstakt nop ; 1 | Ausgleichstakt nop ; 1 | Ausgleichstakt nop ; 1 | Ausgleichstakt nop ; 1 | Ausgleichstakt nop ; 1 | Ausgleichstakt nop ; 1 | Ausgleichstakt nop ; 1 | Ausgleichstakt nop ; 1 | Ausgleichstakt nop ; 1 | Ausgleichstakt nop ; 1 | Ausgleichstakt nop ; 1 | Ausgleichstakt nop ; 1 | Ausgleichstakt nop ; 1 | Ausgleichstakt nop ; 1 | Ausgleichstakt nop ; 1 | Ausgleichstakt nop ; 1 | Ausgleichstakt nop ; 1 | Ausgleichstakt nop ; 1 | Ausgleichstakt nop ; 1 | Ausgleichstakt nop ; 1 | Ausgleichstakt rcall WAIT_UART ; 3 | Ruhepause für das nächste Bit ; Ruhepause von einer Bitlänge rcall WAIT_UART ; 3 | Ruhepause für die Bearbeitung des nächsten Bytes rcall WAIT_UART ; 3 | Ruhepause für die Bearbeitung des nächsten Bytes rcall WAIT_UART ; 3 | Ruhepause für die Bearbeitung des nächsten Bytes rcall WAIT_UART ; 3 | Ruhepause für die Bearbeitung des nächsten Bytes rcall WAIT_UART ; 3 | Ruhepause für die Bearbeitung des nächsten Byte rcall WAIT_UART ; 3 | Ruhepause für die Bearbeitung des nächsten Bytes rcall WAIT_UART ; 3 | Ruhepause für die Bearbeitung des nächsten Bytes rcall WAIT_UART ; 3 | Ruhepause für die Bearbeitung des nächsten Bytes ret ; Pausenzeitroutine für 104µS Pause zwischen den Impulsen ; Taktlänge bei 4MHz ist 250nS -> 416 Runden für 104µS ; Zähler macht 133 Runden (133x3 Takte + 6 Takte - 1 Sprungausgleichstakt) ; Unter Berücksichtigung der Rotuinentakte im URAT-Teil, bleiben 101µS übrig ; Die Differenz zu 104µS erledigen die Takte in der Routine ; Die verbleibenden Bits bleiben innerhalb der Zeittoleranz von 2% WAIT_UART: push r16 ; 2 | Lege Register 16 ab ldi r16, 0x84 ; 1 | Lade Low-Byte von 0x84 (132) nach r16 INWAIT_UART: dec r16 ; 1 | Erniedrige r16 um 1 (-1) brne INWAIT_UART ; 2 | Springe zu INWAIT_UART wenn nicht r16 nicht 0 pop r16 ; 2 | Hole register r16 zurück ret ; 1 | Springe zurück