So also hier mein quellcode:
.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 :-b
Also die ADC Werte nehm ich als Sprungadresse und an dieser stehen dann die Zahlen im ASCII und zwar immer die unteren nibbles beider zahlen. die tabelle ist leider nötig da sich der temperatursensor nicht linear verhält. ich habs bis jetzt von -55 bis 100 gerechnet. Die Zeitverzögerung hab ich gemacht damit das Thermometer nicht ständig springt O:) Alles klar soweit?
Powered by vBulletin® Version 4.2.5 Copyright ©2024 Adduco Digital e.K. und vBulletin Solutions, Inc. Alle Rechte vorbehalten.