.NOLIST .INCLUDE "C:\Programme\Atmel\avr studio3.56\appnotes\m8def.inc" .LIST ;Konstanten .EQU A0 = 2 .EQU E1 = 0 .EQU E2 = 1 .EQU RES = 3 .EQU RW = 4 ; Benutzte Register ; .def save_sreg = R0 .def temp1 =r16 .def temp2 =r17 .def temp3 =r18 .def temp4 =r19 .def temp5 =r26 .def wo =r20 ;bit 0 bis 5 = spalte, 6+7 = seite .def wie =r21 ; Benutzte Register ; Reset- und Interrupt-Vektoren rjmp Start ; Reset-vector reti ;rjmp IInt0 ; External Interrupt Request 0 reti ;rjmp IInt1 ; External Interrupt Request 1 reti reti reti ;rjmp TCpt1 ; Timer/Counter1 Capture event reti;rjmp Timer1CompA ;Timer Conter1 Compare Match reti ;rjmp Timer1CompB ;Timer Conter1 Compare Match reti ;rjmp TOvf1 ; Timer/Counter1 Overflow reti;rjmp Timer0VF ;rjmp TOvf0 ; Timer/Counter0 Overflow reti ;rjmp SPI ; reti ;rjmp URxAv ; Uart Rx char available reti ;rjmp UTxDe ; Uart Tx data register empty reti ;rjmp UTxCp ; Uart Tx complete reti ;rjmp ADC reti ;rjmp eprom reti ;rjmp AnaCp ; Analog comparator reti ; TWI Two-wire Serial INterface reti ; SPM_RDI Store Programm Memory Ready ;Interruptroutinen Start: ;Initialisierung des Stackpointers, damit die Rücksprungadressen für die Unterprogramme abgelegt ;werden können ldi temp1, LOW(RAMEND) ; LOW-Byte der obersten RAM-Adresse out SPL, temp1 ldi temp1, HIGH(RAMEND) ; HIGH-Byte der obersten RAM-Adresse out SPH, temp1 ; Festlegen der Ports als Eingänge bzw. Ausgänge ; Eingänge (Setzen der internen Pullupwiderstände) ; Ausgänge (Setzen der Bit im Datenrichtungsregister) ;Port B ;ldi temp1,0b00000000 ;out DDRB,temp1 ;Port C ldi temp1, 0xFF ;Port C = Ausgang out DDRC, temp1 ;Port D ldi temp1, 0xFF ;Port D = Ausgang out DDRD, temp1 rcall delay;5ms ;kurze pause nach einschalten sbi PORTC,RES ;Reset auf high ziehen 68MPU rcall delay5ms ;warte 5ms ldi wie,0b11000000 rcall lcd_on ;lcd anschalten rcall lcd_clear ;lcd leerem rcall doppelpunkt Main: rjmp Main ;************************************************************************************ ;LCD Komandos ;********************************************************************************* ;pageadresse so setzen setline: ; dieser befehl wird zum scrollen des displays benötigt ;ori zeile,0b11000000 ; ;out PORTD,zeile ;rcall lcd_enable1 ;rcall lcd_enable2 ;ret setp: mov temp1,wo andi temp1,0b11000000 ;seite ausmaskieren lsr temp1 ;6 x nach rechts schieben lsr temp1 lsr temp1 lsr temp1 lsr temp1 lsr temp1 ori temp1,0b10111000 ;befehlbits setzen out PORTD,temp1 rcall lcd_enable setcolum: mov temp1,wo andi temp1,0b00111111 out PORTD,temp1 rcall lcd_enable ret ;*************************************************************************************** ;erzeugt den Enable-Puls für linke und rechte displayseite in abhänigkeit ;von register wie bit 6 rechte seite, bit 7 linke seite lcd_enable: sbrs wie,7 ;springt zu enable 2 wenn bit 6 = 1 rjmp lcd_enable2 sbi PORTC,E1 ;Enable high nop nop nop nop nop cbi PORTC,E1 ;Enable wieder low sbrs wie,6 rjmp lcd_enable_ende lcd_enable2: sbi PORTC,E2 ;Enable high nop nop nop nop nop cbi PORTC,E2 ;Enable wieder low lcd_enable_ende: ret ;******************************************************************************* lcd_reset: ;display software reset cbi PORTC,A0 cbi PORTC,RW ldi temp1,0b11100010 out portd,temp1 rcall lcd_enable rcall delay5ms ret lcd_on: ldi temp1,0b10101111 out portD,temp1 cbi PORTC,A0 rcall lcd_enable rcall delay5ms ret ;************************************************************************** ;Delayroutinen ;********************************************************************** 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 ;$21 WGLOOP0: ldi temp2,$C9 ;$C9 WGLOOP1: dec temp2 brne WGLOOP1 dec temp1 brne WGLOOP0 ret ;wieder zurück Delay: ldi temp1,$ff ldi temp2,$ff ldi temp3,$02 Delayx: dec temp1 brne delayx ;Verringere Zähler um eins dec temp2 brne Delayx dec temp3 brne Delayx ret ;*********************************************************************************** lcd_data: out PORTD,temp1 sbi PORTC,A0 rcall lcd_enable cbi PORTC,A0 ret ;************************************************************************* ;Display leeren, schreibe 0 überall rein ;benutze register temp1,2,3 ;************************************************************************* lcd_clear: ldi wie,0b11000000 ;diplay li + re ldi wo,0b11000000 ;seite3 rcall setp ;seite 3 wählen ldi temp3,$3D ;61 für anzahl spalten je displayhälfte ldi temp2,4 ;lade 4 für anzahl seiten clr temp1 ;lade 0 in temp1 -> wird ins displ. geschrieben lcd_clearw: rcall lcd_data dec temp3 brne lcd_clearw lsr wo lsr wo lsr wo lsr wo lsr wo lsr wo dec wo lsl wo lsl wo lsl wo lsl wo lsl wo lsl wo dec temp2 breq lcd_clear_ende rcall setp ldi temp3,$3D rjmp lcd_clearw lcd_clear_ende: ret ;****************************************************************************** ;doppelpunkte oben und unten doppelpunkt: ldi wie,0b10000100 ;linkes displ 4 zeichen breite ldi wo,0b00001010 ;seite 0 spalte 10 rcall zg_dp ldi wo,0b00100011 ;seite0 spalte 35 rcall zg_dp ldi wo,0b10001010 ;seite 2 spalte 10 rcall zg_dp ldi wo,0b10100011 ;seite 2 spalte 35 rcall zg_dp ret ;************************************************************************ ;*************************************************************************** ; schreibe ;***************************************************************************** rjmp zeichen_print zg_dp: ldi temp3,LOW(doppelp*2) ldi temp4,HIGH(doppelp*2) rjmp zeichen_print ;************************************************************************************ ;schreibt aus db mit einem !!!! seitenwechsel x(bit 0-6 register wie) zeichen in linke oder rechte seite zeichen_print: mov ZL,temp3 mov ZH,temp4 rcall setp mov temp1,wie andi temp1,0b00111111 mov temp2,temp1 ;lade zeichenbreite in temp2 rcall zeichen_print_w1 ; Unterfunktion print aufrufen ret zeichen_print_w1: lpm ; Erstes Byte des Strings nach R0 lesen mov temp1,r0 ; Inhalt von R0 nach R16 kopieren rcall lcd_data ; Datenausgabe adiw ZL, 1 ; Adresse des Z-Pointers um 1 erhöhen dec temp2 brne zeichen_print_w1 rcall delay mov temp1,wie ;wie in emp1 andi temp1,0b00111111 ;zeichenbreite ausmaskieren mov temp2,temp1 ;zeichenbreite in temp2 mov temp1,wo andi temp1,0b11000000 ;seite wird im register wo um 1 erhöht lsr temp1 lsr temp1 lsr temp1 lsr temp1 lsr temp1 lsr temp1 inc temp1 lsl temp1 lsl temp1 lsl temp1 lsl temp1 lsl temp1 lsl temp1 andi wo,0b0011111111 or wo,temp1 rcall setp zeichen_print_w2: lpm ; Erstes Byte des Strings nach R0 lesen mov temp1,r0 ; Inhalt von R0 nach R16 kopieren rcall lcd_data ; Datenausgabe adiw ZL, 1 ; Adresse des Z-Pointers um 1 erhöhen dec temp2 brne zeichen_print_w2 mov temp1,wo andi temp1,0b11000000 ;seite wird im register wo um 1 verringert lsr temp1 lsr temp1 lsr temp1 lsr temp1 lsr temp1 lsr temp1 dec temp1 lsl temp1 lsl temp1 lsl temp1 lsl temp1 lsl temp1 lsl temp1 andi wo,0b0011111111 or wo,temp1 rcall setp ret ;* ;*********************************************************************************** ; Datenbanken für Zeichen etc. , evt in Eprom nehmen ? ;************************************************************************************* doppelp: .db 0,48,48,0,0,48,48,0