Code:
.include "C:\Dokumente und Einstellungen\eric\Desktop\asm\m8def.inc"
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;Thermometer 4Mhz Eric Schneider ;;
;; ;;
;; ;;
;; ;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
.def temp1 = r16
.def temp2 = r17
.def temp3 = r18
.def adcwh = r19
.def adcwl = r20
.cseg
; ############
; ##Tabellen##
; ############
.org 0x0071
.db 0b01010101, 0b01010100, 0b01010011, 0b01010010, 0b01010001, 0b01010000 ;-55 bis -50
.db 0b01001001, 0b01001000, 0b01000111, 0b01000110, 0b01000110, 0b01000101 ;-49 bis -45
.db 0b01000100, 0b01000011, 0b01000010, 0b01000001, 0b01000000, 0b00111001 ;-44 bis -39
.db 0b00111000, 0b00110111, 0b00110110, 0b00110101, 0b00110100, 0b00110011 ;-38 bis -33
.db 0b00110010, 0b00110010, 0b00110001, 0b00110000, 0b00101001, 0b00101000 ;-32 bis -28
.db 0b00100111, 0b00100110, 0b00100101, 0b00100101, 0b00100100, 0b00100011 ;-27 bis -23
.db 0b00100010, 0b00100001, 0b00100000, 0b00011001, 0b00011001, 0b00011000 ;-22 bis -18
.db 0b00010111, 0b00010110, 0b00010101, 0b00010100, 0b00010100, 0b00010011 ;-17 bis -13
.db 0b00010010, 0b00010001, 0b00010000, 0b00001001, 0b00001000, 0b00001000 ;-12 bis -8
.db 0b00000111, 0b00000110, 0b00000101, 0b00000100, 0b00000100, 0b00000011 ;-7 bis -3
.db 0b00000010, 0b00000001, 0b00000000, 0b00000001, 0b00000001, 0b00000010 ;-2 bis 2
.db 0b00000011, 0b00000100, 0b00000101, 0b00000101, 0b00000110, 0b00000111 ;3 bis 7
.db 0b00001000, 0b00001001, 0b00001001, 0b00010000, 0b00010001, 0b00010010 ;8 bis 12
.db 0b00010010, 0b00010011, 0b00010100, 0b00010101, 0b00010110, 0b00010110 ;13 bis 16
.db 0b00010111, 0b00011000, 0b00011001, 0b00100000, 0b00100000, 0b00100001 ;17 bis 21
.db 0b00100010, 0b00100011, 0b00100011, 0b00100100, 0b00100101, 0b00100110 ;22 bis 26
.db 0b00100110, 0b00100111, 0b00101000, 0b00101001, 0b00110000, 0b00110000 ;26 bis 30
.db 0b00110001, 0b00110010, 0b00110011, 0b00110011, 0b00110100, 0b00110101 ;31 bis 35
.db 0b00110110, 0b00110110, 0b00110111, 0b00111000, 0b00111001, 0b00111001 ;36 bis 39
.db 0b01000000, 0b01000001, 0b01000010, 0b01000010, 0b01000011, 0b01000100 ;40 bis 44
.db 0b01000101, 0b01000101, 0b01000110, 0b01000111, 0b01001000, 0b01001000 ;45 bis 48
.db 0b01001001, 0b01010000, 0b01010001, 0b01010001, 0b01010010, 0b01010011 ;49 bis 53
.db 0b01010100, 0b01010100, 0b01010101, 0b01010110, 0b01010111, 0b01010111 ;54 bis 57
.db 0b01011000, 0b01011001, 0b01100000, 0b01100000, 0b01100001, 0b01100010 ;58 bis 62
.db 0b01100010, 0b01100011, 0b01100100, 0b01100101, 0b01100101, 0b01100110 ;62 bis 66
.db 0b01100111, 0b01101000, 0b01101000, 0b01101001, 0b01110000, 0b01110001 ;67 bis 71
.db 0b01110001, 0b01110010, 0b01110011, 0b01110100, 0b01110100, 0b01110101 ;71 bis 75
.db 0b01110110, 0b01110111, 0b01110111, 0b01111000, 0b01111001, 0b01111001 ;76 bis 79
.db 0b10000000, 0b10000001, 0b10000010, 0b10000010, 0b10000011, 0b10000100 ;80 bis 84
.db 0b10000101, 0b10000101, 0b10000110, 0b10000111, 0b10001000, 0b10001000 ;85 bis 88
.db 0b10001001, 0b10010000, 0b10010001, 0b10010001, 0b10010010, 0b10010011 ;89 bis 93
.db 0b10010011, 0b10010100, 0b10010101, 0b10010110, 0b10010110, 0b10010111 ;93 bis 97
.db 0b10011000, 0b10011001, 0b10011001, 0b00000000; 100
.org 0x0000
rjmp reset ;reset
reti ;int0
reti ;int1
reti
reti
reti
reti
reti
reti
reti
reti
reti
reti
reti
rjmp adccomp ;adc complete
reset: ldi temp1, low(ramend) ;Stack initialisiern
out spl, temp1
ldi temp1, high(ramend)
out sph, temp1
ldi temp1, 0x00 ;Porteingang initialisieren
out DDRC, temp1 ;input
ldi temp1, 0x00
out PORTC, temp1 ;interne pullups aus
ldi temp1, 0b00111111 ;lcd ausgänge initialisieren
out DDRD, temp1
cbi ADMUX, 7
cbi ADMUX, 6 ;reference spannung an Aref
cbi ADMUX, 5 ;rechts(9..0) angeordnetes Ergebnis
cbi ADMUX, 0
cbi ADMUX, 1
cbi ADMUX, 2
cbi ADMUX, 3 ;ADC0 ist analoger eingang
sbi ADCSRA, 7 ;ADC einschalten
cbi ADCSRA, 5 ;free running mode aus
sbi ADCSRA, 3 ;ADC interrupt ein
sbi ADCSRA, 0
cbi ADCSRA, 1
sbi ADCSRA, 2 ;Prescaler auf 32
SEI ;interrupts anschalten
rcall lcd_init ;lcd initialisieren
main:
ldi temp1, 0x01
sbi ADCSRA, 6 ;adc starten
fertig: cpi temp1, 0x00
brne fertig
andi adcwh, 0b00000011 ;bit 9 und 10 ausmaskieren
sbrc adcwh, 0 ;Vorzeichen erkennen, ab 175 ohne minus
rjmp pos
cpi adcwl, 0xaf
brlo neg ;springe wenn weniger
rjmp pos
neg: ldi temp1, 0b10110000 ;minuszeichen
rcall lcd_data
rjmp hunderter
pos: ldi temp1, 0b00100000 ;leerstelle
rcall lcd_data
hunderter: sbrs adcwh, 0 ;überprüfen ab wert 308 oder mehr, fals ja dann temperatur dreistellig
rjmp leer ;sonst leerstelle
cpi adcwl, 0x34 ;springe wenn mehr oder gleich
brsh hundert
leer: ldi temp1, 0b00100000
rcall lcd_data ;leerstelle ausgeben
rjmp rest
hundert: ldi temp1, 0b00110001 ;eins ausgeben
rcall lcd_data
rest: ldi temp1, 0x71 ;tabellenadresse festlegen
add adcwl, temp1 ;zu low adc wert dazu zählen
brcc keinue
inc adcwh ;carry in high adc wert
keinue: mov zh, adcwh
mov zl, adcwl ;in das pointerregister laden
LPM ;programminhalt laden
mov temp1, r0
swap temp1
andi temp1, 0b00001111 ;zehnerstelle sind obere 4bit
sbr temp1, 0b00110000
rcall lcd_data
mov temp1, r0
andi temp1, 0b00001111 ;einerstelle sind untere 4bit
sbr temp1, 0b00110000
rcall lcd_data
rcall grad
rcall time
rjmp main
time: ldi temp1, 0x20
loop2: ldi temp2, 0xff
loop1: ldi temp3, 0xff
loop0: dec temp3 brne loop0
dec temp2
brne loop1
dec temp1
brne loop2 ret
grad: ldi temp1, 0b01000111 ;"G"
rcall lcd_data
ldi temp1, 0b01110010 ;"r"
rcall lcd_data
ldi temp1, 0b01100001 ;"a"
rcall lcd_data
ldi temp1, 0b01100100 ;"d"
rcall lcd_data
ret
; ##############
; ##Interrupts##
; ##############
adccomp: in adcwl, ADCL ;Ergebnis in adcwl (untere 8bit)
in adcwh, ADCH ;Ergebnis in adcwh (0bere 2bit)
clr temp1
rcall lcd_clear ;lcd reset
reti
.org 0x0100
; ############
; ##routinen##
; ############
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; LCD-Routinen ;;
;; ============ ;;
;; (c)andreas-s@web.de ;;
;; ;;
;; 4bit-Interface 4Mhz temp1-3 ;;
;; DB4-DB7: PD0-PD3 2 und 3 noch ;;
;; RS: PD4 verwendbar ;;
;; E: PD5 1 ist befehl ;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;sendet ein Datenbyte an das LCD
lcd_data:
push temp2
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
pop temp2
ret ;zurück zum Hauptprogramm
;sendet einen Befehl an das LCD
lcd_command: ;wie lcd_data, nur ohne RS zu setzen
push temp2
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
pop temp2
ret
;erzeugt den Enable-Puls
lcd_enable:
sbi PORTD, 5 ;Enable high
nop ;3 Taktzyklen warten
nop
nop
cbi PORTD, 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
push temp2
ldi temp1, $21
WGLOOP0: ldi temp2, $C9
WGLOOP1: dec temp2
brne WGLOOP1
dec temp1
brne WGLOOP0
pop temp2
ret ;wieder zurück
;Initialisierung: muss ganz am Anfang des Programms aufgerufen werden
lcd_init:
push temp3
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
pop temp3
ret
;Sendet den Befehl zur Löschung des Displays
lcd_clear:
ldi temp1, 0b00000001 ;Display löschen
rcall lcd_command
rcall delay5ms
ret
ist leider alles etwas verrutscht, da ichs im texteditor etwas zu breit geschrieben hab, müsst ihr halt gegebenfals überarbeiten
Lesezeichen