Hallo,
hier ist mein Programm:

Code:
.include "m8def.inc"

;UBRR = Taktfrequenz / 16 * Baudrate -1
.def rBin1L = R1	;Wird gebraucht um bin -> ascii zu rechnen
.def rbin1H = R2	;Wird gebraucht um bin -> ascii zu rechnen
.def rbin2H = R3	;Wird gebraucht um bin -> ascii zu rechnen
.def rbin2L = R4	;Wird gebraucht um bin -> ascii zu rechnen

.def tmp = R16 ;universalregister
.def statusreg = R17 ;Statusregister um die Interrupts zu signalisieren
.def rmp = R18 ;universalregister für die Umrechnung
.equ sramanfang = 0x0060
.equ bumper = 7 ;Bit 7 von statusreg signalisiert INT1 Interrupt
.equ CLOCK = 8000000
.equ BAUD = 2400
.equ UBRRVAL = CLOCK / (BAUD*16)-1

.org 0x000
	rjmp reset
.org INT1addr
	rjmp kolision	;Ext Interrupt Vector Address
reset:
;Stackpointer
	ldi tmp,LOW(RAMEND)
	out SPL,tmp
	ldi tmp,HIGH(RAMEND)
	out SPH,tmp
;sram pointer
	ldi ZH,HIGH(sramanfang)
	ldi ZL,LOW(sramanfang)
;Baudrate einstellen
	ldi tmp,UBRRVAL
	out UBRRL,tmp
			;di tmp,HIGH(UBRRVAL)
			;ut UBRRL,tmp
;Frameformat 8Bit
	ldi tmp,(1<<URSEL) | (1<<UCSZ1) | (1<<UCSZ0) 
	out UCSRC,tmp
	
	sbi UCSRB,TXEN	;TX aktivieren
	
;AD converter Init
	ldi tmp,(1<< ADEN) | (1<<ADPS1) | (1<<ADPS2)
	out ADCSRA,tmp
	ldi tmp,(1<<REFS0) | (1<<MUX2)
	out ADMUX,tmp  
	;Einstellen Low Level Interrupt für Tastenabfrage
	ldi tmp,(1<<INT1)
	out GICR,tmp
	sei
loop_:
	;sram pointer
	ldi ZH,HIGH(sramanfang)
	ldi ZL,LOW(sramanfang)
loop:
	sbrs statusreg,bumper ;prüfe statusregister ob bit 7 -> bumper gesetzt ist wenn ja dann springe
	rjmp loop
	in tmp,GICR	;Schalte INT1 interrupt ab
	andi tmp,0x7f
	out GICR,tmp
	ldi statusreg,0	;lösche statusregister bumper
	cli		;Interrupts allgemein ausschalten
	sbi DDRD,PD3	;schalte pin PD3 als Ausgang
	sbi PORTD,PD3	;und setze es auf HIGH
	ldi R16, $85    ; 10 ms abwarten
L1:        ldi R18, $C7     
L2:        dec R18        
	brne L2        
	dec R16        
	brne L1        
	sbi ADCSRA,ADSC	;Starte ADC
warte:
	sbis ADCSRA,ADIF
	rjmp warte
	;fertig und lese Ergebnis ein 
	in rBin1L,ADCL
	in rBin1H,ADCH
	cbi PORTD,PD3	;Pin PD3 wieder LOW
	cbi DDRD,PD3	;und wieder als Eingang
	sei	;Interrups wieder an
	rcall berechne	;Rechne Ergebnis in ascii um und schreibe 
	;es in sram
			
	
	rcall serout	;gib das Ergebnis über UART aus
	in tmp,GICR	;Schalte Interrupts auf INT1 wieder ein
	ori tmp,0x80
	out GICR,tmp
	rjmp loop_	;wenn fertig wieder von vorne anfangen

serout:
	ldi tmp,0x00	;Zähler für Anzahl der CHAR
serout_:
	cpi tmp,0x05	;Vergleiche Zähler mit 0x05 	
	breq rausuart	;Wenn gleich springe
	ld R0,Z		;Hole ASCII kodierte Zahl aus den SRAM 
serout__:	
	sbis UCSRA,UDRE ;Springe wenn UDR gesetzt ist
	rjmp serout__
	out UDR,R0	;schiebe R0 in UDR 
	adiw ZL,1	;Z++
	inc tmp		;Zähler ++
	rjmp serout_
rausuart:
	sbis UCSRA,UDRE ;Springe wenn UDR gesetzt ist
	rjmp rausuart
	ldi tmp,10	;sende Zeilenvorschub
	out UDR,tmp
rausuart_:	
	sbis UCSRA,UDRE
	rjmp rausuart_
	ldi tmp,13	;sende Wagerücklauf
	out UDR,tmp
	ret

;Diese Routine stammt von Gerd Schmidt http://www.avr-asm-tutorial.net/avr_de/index.html
;Danke dafür
berechne:
	rcall Bin2ToBcd5 ; wandle Binärzahl in BCD um
	ldi rmp,4 ; Zähler auf 4
	mov rBin2L,rmp
Bin2ToAsc5a:
	ld rmp,z ; Lese eine BCD-Ziffer
	tst rmp ; prüfe ob Null
	brne Bin2ToAsc5b ; Nein, erste Ziffer ungleich 0 gefunden
	ldi rmp,' ' ; mit Leerzeichen überschreiben
	st z+,rmp ; und ablegen
	dec rBin2L ; Zähler um eins senken
	brne Bin2ToAsc5a ; weitere führende Leerzeichen
	ld rmp,z ; Lese das letzte Zeichen
Bin2ToAsc5b:
	inc rBin2L ; Ein Zeichen mehr
Bin2ToAsc5c:
	subi rmp,-'0' ; Addiere ASCII-0
	st z+,rmp ; und speichere ab, erhöhe Zeiger
	ld rmp,z ; nächstes Zeichen lesen
	dec rBin2L ; noch Zeichen behandeln?
	brne Bin2ToAsc5c ; ja, weitermachen
	sbiw ZL,5 ; Zeiger an Anfang
	ret ; fertig

Bin2ToBcd5:
	push rBin1H ; Rette Inhalt der Register rBin1H:L
	push rBin1L
	ldi rmp,HIGH(10000) ; Lade 10.000 in rBin2H:L
	mov rBin2H,rmp
	ldi rmp,LOW(10000)
	mov rBin2L,rmp
	rcall Bin2ToDigit ; Ermittle 5.Stelle durch Abziehen
	ldi rmp,HIGH(1000) ; Lade 1.000 in rBin2H:L
	mov rBin2H,rmp
	ldi rmp,LOW(1000)
	mov rBin2L,rmp
	rcall Bin2ToDigit ; Ermittle 4.Stelle durch Abziehen
	ldi rmp,HIGH(100) ; Lade 100 in rBin2H:L
	mov rBin2H,rmp
	ldi rmp,LOW(100)
	mov rBin2L,rmp
	rcall Bin2ToDigit ; Ermittle 3.Stelle durch Abziehen
	ldi rmp,HIGH(10) ; Lade 10 in rBin2H:L
	mov rBin2H,rmp
	ldi rmp,LOW(10)
	mov rBin2L,rmp
	rcall Bin2ToDigit ; Ermittle 2.Stelle durch Abziehen
	st z,rBin1L ; Rest sind Einer
	sbiw ZL,4 ; Setze Zeiger Z auf 5.Stelle (erste Ziffer)
	pop rBin1L ; Stelle den Originalwert wieder her
	pop rBin1H
	ret ; und kehre zurück
Bin2ToDigit:
	clr rmp ; Zähler auf Null
Bin2ToDigita:
	cp rBin1H,rBin2H ; Vergleiche MSBs miteinander
	brcs Bin2ToDigitc ; MSB Binärzahl kleiner, fertig
	brne Bin2ToDigitb ; MSB Binärzahl größer, subtrahiere
	cp rBin1L,rBin2L ; MSB gleich, vergleiche LSBs
	brcs Bin2ToDigitc ; LSB Binärzahl kleiner, fertig
Bin2ToDigitb:
	sub rBin1L,rBin2L ; Subtrahiere LSB Dezimalzahl
	sbc rBin1H,rBin2H ; Subtrahiere Carry und MSB
	inc rmp ; Erhöhe den Zähler
	rjmp Bin2ToDigita ; Weiter vergleichen/subtrahieren
Bin2ToDigitc:
	st z+,rmp ; Speichere das Ergebnis und erhöhe Zeiger
	ret ; zurück
kolision:
	ori statusreg,0x80
	reti
2/3 Davon belegt die Umrechnungsroutine von bin nach ascii , aber es ist ja nicht
die relevante Routine...



Gruß Sebastian