.include"m8def.inc" .def temp = R16 .def temp1 = R17 .def temp2 = R18 .def temp3 = R19 .def countl = r20 .def counth = r21 .def temp4 = r22 .def comp = r23 .def verg = r24 ldi temp, Low(Ramend) out SPL, temp ldi temp, High(Ramend) out SPH, temp ldi countl, 0b00000000 ldi counth, 0b00000000 ldi temp, 0xFF out DDRD, temp ldi temp, 0x00 out DDRB, temp rcall lcd_init rcall lcd_clear anfang: ldi ZL, Low(post1*2) ldi ZH, High(post1*2) rcall lcd_clear start: lpm tst R0 breq warte mov temp1, R0 adiw ZL,1 rcall lcd_data rcall pause rjmp start warte: ldi temp1, 0b10000000 + $39 rcall lcd_command rcall anfang2 z2: rcall pause lpm tst R0 breq za mov temp1, R0 adiw ZL,1 rcall lcd_data rcall pause rjmp z2 za: ldi temp, 48 ldi comp, 0 inc countl inc counth clt ;T-Flag löschen ldi temp1, -1 + '0' ;temp1 für ASCII Ausgabe initialisiern; DIGIT5: inc temp1 ;temp1 Register subi countl, low (10000) ;Subtrahiere 10000 vom 16bit Wert >> Digit 5 des ASCII Zeichens sbci counth, high(10000) brcc DIGIT5 ;Schleife solange bis Wert negativ cp temp1,temp ;beide Register vergleichen wenn ungleich wird Zero Flag gelöscht in temp2,sreg ;Statusregister Laden sbrs temp2,1 ;Überspring nächsten Befehl wenn Z-Flag gesetzt set ;Setze T-Flag in temp2,sreg ;Staturegister nachladen sbrc temp2,6 ;Überspringe nächsten Befehl wenn T-Flag gelöscht rcall lcd_data ;Seriell ausgeben rcall pause ldi temp1,1 +'0' DIGIT4: dec temp1 subi countl, low (-1000) ; sbci counth, high(-1000) brcs DIGIT4 cp temp1,temp in temp2,sreg sbrs temp2,1 set in temp2,sreg sbrc temp2,6 rcall lcd_data ; rcall pause ldi temp1, -10 +'0' ;zweite stelle hinterm Komma DIGIT3: inc temp1 subi countl, low(100) sbci counth, high(100) brcc DIGIT3 cp temp1,comp in temp2,sreg sbrs temp2,1 set in temp2,sreg sbrc temp2,6 rcall lcd_data rcall pause ldi temp1, 10 +'0' ; dritte stelle hinterm Komma DIGIT2: dec temp1 subi countl, -10 brcs DIGIT2 cp temp1,comp in temp2,sreg sbrs temp2,1 set in temp2,sreg sbrc temp2,6 rcall lcd_data rcall pause DIGIT1: mov temp1, countl ;vierte stelle hinterm Komma subi temp1,-48 cp temp1,comp in temp2,sreg sbrs temp2,1 set in temp2,sreg sbrc temp2,6 rcall lcd_data rcall pause warte1: sbic PINB, 0b00000100 ; E Abfrage breq postda rjmp warte1 ;rjmp start postda: ldi ZL, low(post2*2) ldi ZH, high(post2*2) rcall lcd_clear postin: lpm tst R0 breq warte2 mov temp1, R0 adiw ZL,1 rcall lcd_data rcall pause rjmp postin warte2: sbic PINB, 0b00000001 ; E Abfrage breq anf rjmp warte2 anf: rjmp anfang anfang2: ldi ZL, low(zaehler*2) ldi ZH, high(zaehler*2) ret ;LCD Routinen ;sendet ein Datenbyte an das LCD lcd_data: mov temp2, temp1 ;"Sicherungskopie" für ;die Übertragung des 2.Nibbles swap temp1 ;Vertauschen andi temp1, 0b00001111 ;oberes Nibble auf Null setzen sbr temp1, 1<<4 ;entspricht 0b00010000 out PORTD, temp1 ;ausgeben rcall lcd_enable ;Enable-Routine aufrufen ;2. Nibble, kein swap da es schon ;an der richtigen stelle ist andi temp2, 0b00001111 ;obere Hälfte auf Null setzen sbr temp2, 1<<4 ;entspricht 0b00010000 out PORTD, temp2 ;ausgeben rcall lcd_enable ;Enable-Routine aufrufen rcall delay50us ;Delay-Routine aufrufen ret ;zurück zum Hauptprogramm ;sendet einen Befehl an das LCD lcd_command: ;wie lcd_data, nur ohne RS zu setzen mov temp2, temp1 swap temp1 andi temp1, 0b00001111 out PORTD, temp1 rcall lcd_enable andi temp2, 0b00001111 out PORTD, temp2 rcall lcd_enable rcall delay50us ret ;erzeugt den Enable-Puls lcd_enable: sbi PORTD, 7 ;Enable high nop ;3 Taktzyklen warten nop nop cbi PORTD, 7 ;Enable wieder low ret ;Und wieder zurück ;Pause nach jeder Übertragung delay50us: ;50us Pause ldi temp1, $42 delay50us_:dec temp1 brne delay50us_ ret ;wieder zurück ;Längere Pause für manche Befehle delay5ms: ;5ms Pause ldi temp1, $21 WGLOOP0: ldi temp2, $C9 WGLOOP1: dec temp2 brne WGLOOP1 dec temp1 brne WGLOOP0 ret ;wieder zurück ;Initialisierung: muss ganz am Anfang des Programms aufgerufen werden lcd_init: ldi temp3,50 powerupwait: rcall delay5ms dec temp3 brne powerupwait ldi temp1, 0b00000011 ;muss 3mal hintereinander gesendet out PORTD, temp1 ;werden zur Initialisierung rcall lcd_enable ;1 rcall delay5ms rcall lcd_enable ;2 rcall delay5ms rcall lcd_enable ;und 3! rcall delay5ms ldi temp1, 0b00000010 ;4bit-Modus einstellen out PORTD, temp1 rcall lcd_enable rcall delay5ms ldi temp1, 0b00101000 ;noch was einstellen... rcall lcd_command ldi temp1, 0b00001100 ;...nochwas... rcall lcd_command ldi temp1, 0b00000100 ;endlich fertig rcall lcd_command ret ;Sendet den Befehl zur Löschung des Displays lcd_clear: ldi temp1, 0b00000001 ;Display löschen rcall lcd_command rcall delay5ms ret pause: ldi r25, 0xFF loop1: ldi r26, 0xff loop2: dec r26 brne loop2 dec r25 brne loop1 ldi r25, 0xFF loop3: ldi r26, 0xff loop4: dec r26 brne loop4 dec r25 brne loop3 ret ;Text post1: .db"Keine Post gekommen!",0 post2: .db"Es ist Post gekommen!",0 zaehler: .db"Zaehler:",0