.device ATtiny26 .nolist .include "tn26def.inc" .list .def temp1 = r16 ; allgemeines temp Register, zur kurzfristigen Verwendung .def temp2 = r17 ; 8 höchstwertigen bits für display .def adlow = r18 ; Ergebnis vom ADC .def adhigh = r19 ; Ergebnis vom ADC .def temp3 = r20 ; benötigt von lcd routine ?!?!?! .equ F_CPU = 4000000 ; Systemtakt in Hz .equ BAUD = 9600 ; Baudrate ldi temp1, (1<= 8 MHz) kann es notwendig sein, ; vor dem Enable High 1-2 Wartetakte (nop) einzufügen. ; Siehe dazu http://www.mikrocontroller.net/topic/81974#685882 lcd_enable: sbi PORTB, 5 ; Enable high nop ; 3 Taktzyklen warten nop nop cbi PORTB, 5 ; 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 PORTB, 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 PORTB, temp1 rcall lcd_enable rcall delay5ms ldi temp1, 0b00101000 ; 4Bit / 2 Zeilen / 5x8 rcall lcd_command ldi temp1, 0b00001100 ; Display ein / Cursor aus / kein Blinken rcall lcd_command ldi temp1, 0b00000100 ; inkrement / kein Scrollen 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 ; Sendet den Befehl: Cursor Home lcd_home: ldi temp1, 0b00000010 ; Cursor Home rcall lcd_command rcall delay5ms ret ;********************************************************************** ;********************************************************************** ; ; Eine 8 Bit Zahl ohne Vorzeichen ausgeben ; ; Übergabe: Zahl im Register temp1 ; veränderte Register: keine ; lcd_number: push temp1 ; die Funktion verändert temp1 und temp2, push temp2 ; also sichern wir den Inhalt, um ihn am Ende ; wieder herstellen zu können mov temp2, temp1 ; das Register temp1 frei machen ; abzählen wieviele Hunderter ; in der Zahl enthalten sind ;** Hunderter ** ldi temp1, '0'-1 ; temp1 mit ASCII '0'-1 vorladen lcd_number_1: inc temp1 ; ASCII erhöhen (somit ist nach dem ersten ; Durchlauf eine '0' in temp1) subi temp2, 100 ; 100 abziehen brcc lcd_number_1 ; ist dadurch kein Unterlauf entstanden? ; nein, dann zurück zu lcd_number_1 subi temp2, -100 ; 100 wieder dazuzählen, da die ; vorherhgehende Schleife 100 zuviel ; abgezogen hat rcall lcd_data ; die Hunderterstelle ausgeben ;** Zehner ** ldi temp1, '0'-1 ; temp1 mit ASCII '0'-1 vorladen lcd_number_2: inc temp1 ; ASCII erhöhen (somit ist nach dem ersten ; Durchlauf eine '0' in temp1) subi temp2, 10 ; 10 abziehen brcc lcd_number_2 ; ist dadurch kein Unterlauf enstanden? ; nein, dann zurück zu lcd_number_2 subi temp2, -10 ; 10 wieder dazuzählen, da die ; vorherhgehende Schleife 10 zuviel ; abgezogen hat rcall lcd_data ; die Zehnerstelle ausgeben ;** Einer ** ldi temp1, '0' ; die Zahl in temp2 ist jetzt im Bereich add temp1, temp2 ; 0 bis 9. Einfach nur den ASCII Code für rcall lcd_data ; '0' dazu addieren und wir erhalten dierekt ; den ASCII Code für die Ziffer pop temp2 ; den gesicherten Inhalt von temp2 und temp1 pop temp1 ; wieder herstellen ret ; und zurück ;**********************************************************************