mikrocontroller.net

Forum: Mikrocontroller und Digitale Elektronik AVR-Tutorial: ADC


Autor: Neuling (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Habe hier ein Mega88 und wollte mal das AVR-Tutorial: ADC abarbeiten.

Aber bei mir läuft das nicht so ganz

bei
    sbi     ADCSRA, ADSC        ; den ADC starten
 
wait_adc:
    sbic    ADCSRA, ADSC        ; wenn der ADC fertig ist, wird dieses Bit gelöscht
    rjmp    wait_adc

kommen die Fehler beim übersetzen

Test.asm(153): error: Operand 1 out of range: 0x7a

WARUM das jetzt???

Autor: Alter Fux (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
kommentierer Zeile 42 aus!

Autor: Neuling (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hääääää ??????????????????

Zeile 42 wie wo was ???????????????????????

Autor: spess53 (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hi

>WARUM das jetzt???

Die Adressen der ADC-Register liegen ausserhalb des Adressbereichs von 
'sbi', 'sbic'. Da hilft nur Lesen des IO-Registers in ein Register. 
'in/out' gehen auch nicht.
   sbi     ADCSRA, ADSC

ersetzen durch z.B. :

   lds r16,ADCSRA
   sbr r16,1<<ADSC
   sts ADCSRA, r16

    sbic    ADCSRA, ADSC 
    rjmp    wait_adc
->
    lds r16,ADCSRA
    sbrs r16,ADSC
    rjmp    wait_adc


MfG Spess

Autor: Neuling (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Und wieso Zeile 42 raus?

Autor: Alter Fux (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
42 ist die Antwort auf alle Fragen :-)

Autor: spess53 (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hi

>Und wieso Zeile 42 raus?

Vergiss es. Die haben keine Ahnung.

MfG Spess

Autor: Justus Skorps (jussa)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Neuling schrieb:
> Und wieso Zeile 42 raus?

das sollte ein dezenter Hinweis sein, dass so Mini-Ausschnitte aus 
Programmen selten für die Fehlersuche sinnvoll sind

Autor: Neuling (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
spess53 schrieb:
> Die Adressen der ADC-Register liegen ausserhalb des Adressbereichs von
>
> 'sbi', 'sbic'. Da hilft nur Lesen des IO-Registers in ein Register.
>
> 'in/out' gehen auch nicht.
>     rjmp    wait_adc
> MfG Spess

Ist das langsamer als auf dem Mega8? Sind ja mehr Befehle?

Alter Fux schrieb:
> 42 ist die Antwort auf alle Fragen :-)

Sorry sollte ich jetzt einwenig hart sein. A...... klasse einen Anfänger 
zu verarschen hast es ja voll drauf. Hoffe du als Experte bekommst mal 
auf eine Frage auch so eine Irreführung.

Autor: gerd (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Neuling schrieb:
> Und wieso Zeile 42 raus?

Siehe Netiquette - Äußere Form!

- gerd

Autor: spess53 (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hi

>das sollte ein dezenter Hinweis sein, dass so Mini-Ausschnitte aus
>Programmen selten für die Fehlersuche sinnvoll sind

In dem Fall war doch alles da: ATMega88, ADC-Register ,IO-Befehle und 
Fehlermeldung 'Operand 1 out of range: 0x7a'.

Gleich los Schreien statt Denken ist halt einfacher.

MfG Spess

Autor: spess53 (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hi

>Ist das langsamer als auf dem Mega8? Sind ja mehr Befehle?

Ja. Geht aber nicht anders. Aber da du sowieso auf die Wandlung wartest, 
ist das vollkommen egal.

MfG Spess

Autor: Neuling (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
gerd schrieb:
> Neuling schrieb:
>
>> Und wieso Zeile 42 raus?
>
>
>
> Siehe Netiquette - Äußere Form!
>
>
>
> - gerd

Wo habe ich mit meiner Frage die Netiquette nicht eingehalten das ich so 
verarscht werde?

Ich glaube da sollte hier jemand anderes mal die Netiquette einhalten.

Es gibt aber auch User die NORMAL und echt Hilfsbereit sind

Danke spess53

Autor: Neuling (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
spess53 schrieb:
> Ja. Geht aber nicht anders. Aber da du sowieso auf die Wandlung wartest,
>
> ist das vollkommen egal.
>
>
>
> MfG Spess

Also lieber einen Mega8 als ein Mega88 ???

Autor: Stefan B. (stefan) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Nicht unbedingt. Du braucht nur zusätzlich zum Tutorial das kostenlose 
PDF und den Willen zum Nachlesen der Unterschiede.

AVR094: Replacing ATmega8 by ATmega88 (PDF)
http://www.atmel.com/dyn/resources/prod_documents/...

Autor: Alter Fux (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Neuling schrieb:
> Sorry sollte ich jetzt einwenig hart sein. A......

Um es kurz zu machen, Zitat:
"
Klare Beschreibung des Problems. Besonders für Anfänger gilt: Gerade am 
Anfang ist es immer gut zu sagen, was man erreichen will und nicht so 
sehr Annahmen darüber zu treffen, wie man es erreichen könnte und dann 
das Wie zu hinterfragen. Oft ist der Denkfehler nämlich schon im Ansatz 
und man kann besser helfen, wenn man das Ziel des Fragenden kennt.Im 
Betreff angeben um welchen Controllertyp es geht (AVR, PIC, ...) Welcher 
Compiler in welcher Version (Z.B WINAVR 17032007, BASCOM-AVR 1.4; nicht: 
"neueste Version"!) Das Problem in Zahlen fassen! Nicht einfach 
schreiben "so schnell wie möglich", "so stromsparend wie möglich" etc, 
sondern mal ein paar Zahlen nennen. X MHz, Y ms, Z µA etc. Wenn man 
keine exakte Vorstellung davon hat, sollte wenigstens eine Größenordnung 
angegeben werden (1..5 MHz, <1mA etc.) Welcher IC in welchem Gehäuse. 
Wenn Datenblätter vorhanden sind diese ggf. anhängen oder als Link 
angeben. Daran denken, dass die Leute im Forum nicht neben einem sitzen 
und alles so vor sich sehen wie der Fragesteller Klare Fragen 
formulieren und nicht davon ausgehen, dass eine diffuse 
Zustandsbeschreibung als Frage interpretiert wird.
"

denke mal drüber nach.

Autor: Stefan B. (stefan) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Kompletter Code ist i.d.R besser und hier im Forum gewünscht. Aber keine 
Regel ohne Ausnahme. Für mich war die prägnante Anfangsfrage auch 
vollständig. Wenn alle Neulinge 2011 ihr Problem so auf den Punkt 
bringen, sehen wir einem rosigen Jahr entgegen :-)

Autor: spess53 (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hi

>Also lieber einen Mega8 als ein Mega88 ???

Blödsinn. Das merkst du überhaupt nicht. sbi/cbi/sbis/sbic kannst du 
auch beim ATMega8 nicht auf alle IO-Register anwenden. Also, warum 
diesen Dinosaurier verwenden?

MfG Spess

Autor: gerd (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Neuling schrieb:
> Wo habe ich mit meiner Frage die Netiquette nicht eingehalten das ich so
> verarscht werde?
>
> Ich glaube da sollte hier jemand anderes mal die Netiquette einhalten.

Möglich! Ich wollte lediglich deine Frage beantworten, warum jemand nur 
"42" gepostet hat (ob das nun angebracht war oder nicht).

- gerd

Autor: Neuling (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Alter Fux schrieb:
> Um es kurz zu machen, Zitat:
>
> "
> Klare Beschreibung des Problems. Besonders für Anfänger gilt: Gerade am
> Anfang ist es immer gut zu sagen, was man erreichen will und nicht so
> sehr Annahmen darüber zu treffen, wie man es erreichen könnte und dann
> das Wie zu hinterfragen. Oft ist der Denkfehler nämlich schon im Ansatz
> und man kann besser helfen, wenn man das Ziel des Fragenden kennt.Im
> Betreff angeben um welchen Controllertyp es geht (AVR, PIC, ...) Welcher
> Compiler in welcher Version (Z.B WINAVR 17032007, BASCOM-AVR 1.4; nicht:
> "neueste Version"!) Das Problem in Zahlen fassen! Nicht einfach
> schreiben "so schnell wie möglich", "so stromsparend wie möglich" etc,
> sondern mal ein paar Zahlen nennen. X MHz, Y ms, Z µA etc. Wenn man
> keine exakte Vorstellung davon hat, sollte wenigstens eine Größenordnung
> angegeben werden (1..5 MHz, <1mA etc.) Welcher IC in welchem Gehäuse.
> Wenn Datenblätter vorhanden sind diese ggf. anhängen oder als Link
> angeben. Daran denken, dass die Leute im Forum nicht neben einem sitzen
> und alles so vor sich sehen wie der Fragesteller Klare Fragen
> formulieren und nicht davon ausgehen, dass eine diffuse
> Zustandsbeschreibung als Frage interpretiert wird.
>
> denke mal drüber nach.

Da man mir ja hier auf anhieb helfen konnte denke ich habe ich alles 
gesagt zu meinem Problem was zu sagen war. Wo bitte habe ich was 
weggelassen was man hätte benötigt um das problem besser zu lösen.

Lerne bitte jemand richtig essen der kleckert und das im normalen Ton 
und nicht mit einer verarsche das jemand her geht und seine 
Programmzeilen abzählt und sich gedanken macht über die Antwort.

Autor: Alter Fux (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Alter Fux schrieb:
> Sorry sollte ich jetzt einwenig hart sein. A......

etwa hier?

Autor: Neuling (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Alter Fux schrieb:
> Alter Fux schrieb:
>
>> Sorry sollte ich jetzt einwenig hart sein. A......
>
>
>
> etwa hier?

Das war ja wohl lange nach deiner Verarsche und nicht der Grund deiner 
Verarschung.

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Jungs beruhigt euch

Wenn er im Eröffnungsposting noch die Zeile 153 aus der Fehlermeldung 
markiert hätte, wäre es eine perfekte Frage gewesen. 10 Punkte von 10 
möglichen.
Aber auch so war offensichtlich und gut erkennbar, was das Problem 
darstellt.

Im Vergleich, wie andere Fragen hier manchmal aussehen, ist das hier 
harmlos und schon fast vorbildlich.

Autor: Neuling (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Karl heinz Buchegger schrieb:
> Jungs beruhigt euch
>
>
>
> Wenn er im Eröffnungsposting noch die Zeile 153 aus der Fehlermeldung
>
> markiert hätte, wäre es eine perfekte Frage gewesen. 10 Punkte von 10
>
> möglichen.
>
> Aber auch so war offensichtlich und gut erkennbar, was das Problem
>
> darstellt.
>
>
>
> Im Vergleich, wie andere Fragen hier manchmal aussehen, ist das hier
>
> harmlos und schon fast vorbildlich.

Danke und es zeigt mir auf das es sich doch eventuell lohnt sich hier 
anzumelden.

Eine Entschuldigung und die Einsicht wäre auch ok gewesen und ich hätte 
mich nicht so aufgeregt. Ich kann es halt nicht leiden mich hin zu 
setzen und zu denke das mir einer helfen möchte und nach 5 Minuten zu 
merken das ich GRUNDLOS verarscht wurde und die Zeit dahin ist.

Autor: Neuling (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Aber mein Problem geht weiter.
; Stackpointer initialisieren
ldi Temp1, high(RAMEND) 
out SPH,Temp1           
ldi Temp1, low(RAMEND)
out SPL,Temp1

; Ports initialisieren
ldi  Temp1, 0b11111111
out DDRC,Temp1 ; Port-C Ausgang
ldi  Temp1, 0b11111110
out DDRD,Temp1 ; Port-D Ausgang PD0=Eingang RXD
out DDRB,Temp1 ; Port-B Ausgang PB0=Eingang ADC0

; Alle Port's auf Low
ldi Temp1,0b00000000
out PortB,Temp1 ; Port B alles auf Low
out PortC,Temp1 ; Port C alles auf Low
out PortD,Temp1 ; Port D alles auf Low

;Alle Interrups an
sei

; neuen ADC-Wert lesen
loop:
; den ADC starten
   lds Temp1,ADCSRA
   sbr Temp1,1<<ADSC
   sts ADCSRA, Temp1
   
 
wait_adc:
; wenn der ADC fertig ist, wird dieses Bit gelöscht
   lds  Temp1,ADCSRA
   sbrs Temp1,ADSC
   rjmp wait_adc


; Cursor auf die 5 Stelle in Zeile 4 setzen
   ldi Temp1, 0b11011000
   rcall lcd_command

; ADC einlesen:
   ldi  xl, ADCL    ; immer zuerst LOW Byte lesen
   ldi  xh, ADCH    ; danach das mittlerweile gesperrte High Byte
   
   rcall lcd_number_big


   rjmp loop

lcd_number_big ist eine Routine die mir auf dem Display die Zahl 
darstellt die in xh und xl steht. Die Routine geht auch. Ich bekomme 
aber immer den gleichen Wert angezeigt obwohl ich PC0 (ADC0) mit GND 
verbunden habe.

Sinn der Übung ist es mich in den ADC einzuarbeiten und ich wollte gerne 
mal die Werte sehen.

Habe ich was vergessen was zur lösung des Problemes führen kann?

Autor: Stefan B. (stefan) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Bei Verbindung GND zum abgefragten Eingangspin des ADC sollte ein 
gleichbleibender Wert (um die 0 :-) rauskommen. Was anderes wäre 
komisch.

Um eine Spannung zu messen, müsstest du auch eine Spannung auf den 
betreffenden ADC-Pin geben z.B. mit einem Potentiometer wie in 
AVR-Tutorial: ADC: Beschaltung des ADC-Eingangs

Autor: Neuling (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Stefan B. schrieb:
> Bei Verbindung GND zum abgefragten Eingangspin des ADC sollte ein Wert
>
> um die 0 rauskommen. Was anderes wäre komisch :-)

Ja und weil es komisch ist das ich 31096 herraus bekomme suche ich 
gerade nache dem Fehler den ich gemacht habe.

Autor: spess53 (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hi

>Habe ich was vergessen was zur lösung des Problemes führen kann?

Vielleicht solltest du mal den ADC initialisieren.

MfG Spess

Autor: Stefan B. (stefan) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Neuling schrieb:

> Ja und weil es komisch ist das ich 31096 herraus bekomme suche ich
> gerade nache dem Fehler den ich gemacht habe.

Ah sorry, ich dachte du gehst nach Code im Tutorial vor.

Autor: Neuling (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Sorry vor dem sei mach ich natürlich
; ADC initialisieren: ADC0, Vcc als Referenz, Single Conversion, Vorteiler 128
ldi Dummy1, (1<<REFS0) ; Kanal 0, interne Referenzspannung 5V
sts ADMUX, Temp1
ldi Temp1, (1<<ADEN) | (1<<ADPS2) | (1<<ADPS1) | (1<<ADPS0)
sts ADCSRA, Temp1

somit sieht das ganze so aus
; Stackpointer initialisieren
ldi Temp1, high(RAMEND) 
out SPH,Temp1           
ldi Temp1, low(RAMEND)
out SPL,Temp1

; Ports initialisieren
ldi  Temp1, 0b11111111
out DDRC,Temp1 ; Port-C Ausgang
ldi  Temp1, 0b11111110
out DDRD,Temp1 ; Port-D Ausgang PD0=Eingang RXD
out DDRB,Temp1 ; Port-B Ausgang PB0=Eingang ADC0

; Alle Port's auf Low
ldi Temp1,0b00000000
out PortB,Temp1 ; Port B alles auf Low
out PortC,Temp1 ; Port C alles auf Low
out PortD,Temp1 ; Port D alles auf Low


; ADC initialisieren: ADC0, Vcc als Referenz, Single Conversion, Vorteiler 128
ldi Dummy1, (1<<REFS0) ; Kanal 0, interne Referenzspannung 5V
sts ADMUX, Temp1
ldi Temp1, (1<<ADEN) | (1<<ADPS2) | (1<<ADPS1) | (1<<ADPS0)
sts ADCSRA, Temp1

;Alle Interrups an
sei

; neuen ADC-Wert lesen
loop:
; den ADC starten
   lds Temp1,ADCSRA
   sbr Temp1,1<<ADSC
   sts ADCSRA, Temp1
   
 
wait_adc:
; wenn der ADC fertig ist, wird dieses Bit gelöscht
   lds  Temp1,ADCSRA
   sbrs Temp1,ADSC
   rjmp wait_adc


; Cursor auf die 5 Stelle in Zeile 4 setzen
   ldi Temp1, 0b11011000
   rcall lcd_command

; ADC einlesen:
   ldi  xl, ADCL    ; immer zuerst LOW Byte lesen
   ldi  xh, ADCH    ; danach das mittlerweile gesperrte High Byte
   
   rcall lcd_number_big


   rjmp loop

Autor: spess53 (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hi

>ldi Dummy1, (1<<REFS0) ; Kanal 0, interne Referenzspannung 5V
>sts ADMUX, Temp1

Fällt dir etwas auf?

Ich weiss schon, warum ich dieses .def-Geraffel nicht benutze.

MfG Spess

Autor: Neuling (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ich habe bei mir
; ADC initialisieren: ADC0, Vcc als Referenz, Single Conversion, Vorteiler 128
ldi Temp1, (1<<REFS0) ; Kanal 0, interne Referenzspannung 5V
sts ADMUX, Temp1
ldi Temp1, (1<<ADEN) | (1<<ADPS2) | (1<<ADPS1) | (1<<ADPS0)
sts ADCSRA, Temp1

stehen das mit dem Dummy1 habe ich hier aus einem anderen Thread 
übernommen war aber nicht richtig nur noch bei mir in der 
Zwischenablage. In meinem Programm ist es Temp1

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Müsste es hier

wait_adc:
; wenn der ADC fertig ist, wird dieses Bit gelöscht
   lds  Temp1,ADCSRA
   sbrs Temp1,ADSC
   rjmp wait_adc


nicht SBRC anstelle von SBRS heißen?

Autor: spess53 (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hi

>   sbrs Temp1,ADSC  <-----
>   rjmp wait_adc

   sbrc Temp1,ADSC   <-----
   rjmp wait_adc

ADSC ist während der Wandlung H.

MfG Spess

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
spess53 schrieb:
> Hi
>
>>   sbrs Temp1,ADSC  <-----
>>   rjmp wait_adc
>
>    sbrc Temp1,ADSC   <-----
>    rjmp wait_adc
>
> ADSC ist während der Wandlung H.

Hab ich mir auch überlegt. Allerdings müsste irgendwann das ADC Ergebnis 
auch so fertig werden und korrekt sein. D.h. seine hohen Zahlen erklärt 
das nicht, weil er ja in einer Schleife läuft.

Die sind überhaupt seltsam. Ich wüsste nicht, wie es zu einem 
Messergebnis von 31096 kommen kann. Von daher tendiere ich sogar eher zu 
einem Fehler in den Ausgabefunktionen.

Autor: spess53 (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hi

>Allerdings müsste irgendwann das ADC Ergebnis
>auch so fertig werden und korrekt sein.

Nein. Das Ende der Wandlung wird überhaupt nicht abgewartet.

>Ich wüsste nicht, wie es zu einem
>Messergebnis von 31096 kommen kann. Von daher tendiere ich sogar eher zu
>einem Fehler in den Ausgabefunktionen.

Der Wert kann nicht >1023 werden.

MfG Spess

Autor: Neuling (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Trage ich hier xl mit 255 und xh mit 1 ein:
; ADC einlesen:
   ldi  xl, 255    ; immer zuerst LOW Byte lesen
   ldi  xh, 1      ; danach das mittlerweile gesperrte High Byte
   
   rcall lcd_number_big


   rjmp loop

wird richtig 00511 auf dem Display angezeigt.

Ein xl mit 255 und ein xh 255 zeigt auch 65535 an also auch OK
Ein xl mit 0 und ein xh mit 0 liefert mir 00000 wie es sich gehört.

So glaube ich nicht das es an der ausgabenroutine liegt.

Diese sieht so aus ( angelhnt aus dem Tutorial )
 ; Eine Zahl aus dem Register xh(high) und xl(low) dezimal ausgeben

lcd_number_big:
  push  xl
  push  xh

; Division durch mehrfache Subtraktion
 
    ldi     Temp1,'0'-1     ; Ziffernzähler direkt als ASCII Code
    ; bzgl. '0'-1 siehe http://www.mikrocontroller.net/topic/198681
Z_ztausend:
    inc     Temp1
    subi    xl, low(10000)   ; -10,000
    sbci    xh, high(10000) ; 16 Bit
    brcc    Z_ztausend
                                    
    rcall   lcd_data
    subi    xl, low(-10000)  ; nach Unterlauf wieder einmal addieren
    sbci    xh, high(-10000); +10,000
 
    ldi     Temp1, '0'-1      ; Ziffernzähler direkt als ASCII Code
Z_tausend:
    inc     Temp1
    subi    xl, low(1000)    ; -1,000
    sbci    xh, high(1000)  ; 16 Bit
    brcc    Z_tausend
                                    
    rcall   lcd_data
    subi    xl, low(-1000)   ; nach Unterlauf wieder einmal addieren
    sbci    xh, high(-1000) ; +1,000
 
    ldi     Temp1, '0'-1      ; Ziffernzähler direkt als ASCII Code
Z_hundert:
    inc     Temp1
    subi    xl, low(100)     ; -100
    sbci    xh, high(100)   ; 16 Bit
    brcc    Z_hundert
                                    
    rcall   lcd_data
    subi    xl, low(-100)    ; nach Unterlauf wieder einmal addieren
    sbci    xh, high(-100)  ; +100
 
    ldi     Temp1, '0'-1       ; Ziffernzähler direkt als ASCII Code
Z_zehner:
    inc     Temp1
    subi    xl, low(10)      ; -10
    sbci    xh, high(10)    ; 16 Bit
    brcc    Z_zehner
                                    
    rcall   lcd_data
    subi    xl, low(-10)     ; nach Unterlauf wieder einmal addieren
    sbci    xh, high(-10)   ; +10
 
    subi    xl, -'0'         ; adlow enthält die Einer, Umwandlung in ASCII
    mov     Temp1,xl
    rcall   lcd_data

    pop   xh
    pop   xl
    ret

Autor: Neuling (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Der Code zu dem Programm:
.INCLUDE "m88def.inc"

.def Temp1    = r16

.equ F_CPU = 8000000                            ; Systemtakt in Hz
.equ BAUD  = 38400                              ; Baudrate

; Berechnungen
.equ UBRR_VAL   = ((F_CPU+BAUD*8)/(BAUD*16)-1)  ; clever runden
.equ BAUD_REAL  = (F_CPU/(16*(UBRR_VAL+1)))     ; Reale Baudrate
.equ BAUD_ERROR = ((BAUD_REAL*1000)/BAUD-1000)  ; Fehler in Promille
 
.if ((BAUD_ERROR>10) || (BAUD_ERROR<-10))       ; max. +/-10 Promille Fehler
  .error "Systematischer Fehler der Baudrate grösser 1 Prozent und damit zu hoch!"
.endif 

.org 0x000     ; kommt ganz an den Anfang des Speichers
  rjmp RESET ; Interruptvektoren überspringen und zum Hauptprogramm

reti           ; $001 External Interrupt Request 0
reti           ; $002 External Interrupt Request 1
reti           ; $003 Pin Change Interrupt Request 0
reti           ; $004 Pin Change Interrupt Request 0
reti           ; $005 Pin Change Interrupt Request 1
reti           ; $006 Watchdog Time-out Interrupt
reti           ; $007 Timer/Counter2 Compare Match A
reti           ; $008 Timer/Counter2 Compare Match A
reti           ; $009 Timer/Counter2 Overflow
reti           ; $00A Timer/Counter1 Capture Event
reti           ; $00B Timer/Counter1 Compare Match A
reti           ; $00C Timer/Counter1 Compare Match B
reti           ; $00D Timer/Counter1 Overflow
reti           ; $00E TimerCounter0 Compare Match A
reti           ; $00F TimerCounter0 Compare Match B
reti           ; $010 Timer/Couner0 Overflow
reti           ; $011 SPI Serial Transfer Complete
rjmp InRS232   ; $012 USART Rx Complete
reti           ; $013 USART, Data Register Empty
reti           ; $014 USART Tx Complete
reti           ; $015 ADC Conversion Complete
reti           ; $016 EEPROM Ready
reti           ; $017 Analog Comparator
reti           ; $018 Two-wire Serial Interface
reti           ; $019 Store Program Memory Read

RESET:         ; Hier beginnt das Hauptprogramm 


; Stackpointer initialisieren
ldi Temp1, high(RAMEND) 
out SPH,Temp1           
ldi Temp1, low(RAMEND)
out SPL,Temp1

; Ports initialisieren
ldi  Temp1, 0b11111111
out DDRC,Temp1 ; Port-C Ausgang
ldi  Temp1, 0b11111110
out DDRD,Temp1 ; Port-D Ausgang PD0=Eingang RXD
out DDRB,Temp1 ; Port-B Ausgang PB0=Eingang ADC0


; Baudrate einstellen
ldi Temp1, HIGH(UBRR_VAL)
sts UBRR0H, Temp1
ldi Temp1, LOW(UBRR_VAL)
sts UBRR0L, Temp1

; RS232 Frame-Format: 8 Bit 
ldi Temp1, (1<<RXEN0)|(1<<RXCIE0)|(1<<TXEN0) ; TX aktivieren Interrupt bei Empfang RX (Empfang) aktivieren
sts UCSR0B, Temp1

ldi Temp1, (1<<USBS0)|(1<<UCSZ01)|(1<<UCSZ00) ; 8 Bit Daten kein Paraty, 1 Stopbit
sts UCSR0C, Temp1 


; Alle Port's auf Low
ldi Temp1,0b00000000
out PortB,Temp1 ; Port B alles auf Low
out PortC,Temp1 ; Port C alles auf Low
out PortD,Temp1 ; Port D alles auf Low


; ADC initialisieren: ADC0, Vcc als Referenz, Single Conversion, Vorteiler 128
 
ldi Temp1, (1<<REFS0) ; Kanal 0, interne Referenzspannung 5V
sts ADMUX, Temp1
ldi Temp1, (1<<ADEN) | (1<<ADPS2) | (1<<ADPS1) | (1<<ADPS0)
sts ADCSRA, Temp1



rcall FirmOut       ; Meldung auf RS232 ausgeben
rcall Ton           ; Tonfolge ausgeben
rcall StartDisplay  ; Startbildschirm aufbauen und Display Init


;Alle Interrups an
sei



; neuen ADC-Wert lesen
loop:
; den ADC starten
   lds Temp1,ADCSRA
   sbr Temp1,1<<ADSC
   sts ADCSRA, Temp1
   
 
wait_adc:
; wenn der ADC fertig ist, wird dieses Bit gelöscht
   lds  Temp1,ADCSRA
   sbrs Temp1,ADSC
   rjmp wait_adc


; Cursor auf die 5 Stelle in Zeile 4 setzen
   ldi Temp1, 0b11011000
   rcall lcd_command

; ADC einlesen:
   ldi  xl, ADCL    ; immer zuerst LOW Byte lesen
   ldi  xh, ADCH    ; danach das mittlerweile gesperrte High Byte
   
   rcall lcd_number_big


   rjmp loop

          
.include "lcd-routines.asm"            ; LCD Funktionen 
.include "ton.asm"                     ; Ton Funktionen 
.include "rs232.asm"                   ; RS232 Funktionen
.include "StartDisplay.asm"            ; Display Funktionen

Das ganze geht schon fein und das gerüsst benutze ich zum lernen immer.

Nur den Teil zwischen Loop benutze ich um weiter zu lernen und neue 
Funktionen zu erkunden.

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
spess53 schrieb:
> Hi
>
>>Allerdings müsste irgendwann das ADC Ergebnis
>>auch so fertig werden und korrekt sein.
>
> Nein. Das Ende der Wandlung wird überhaupt nicht abgewartet.

Schon.
Aber im nächsten Schleifendurchlauf ist es dann in den ADC Registern 
vorliegend und er würde es sich holen, während der ADC schon wieder 
arbeitet. Ich weiß allerdings nicht auswendig ob es zulässig ist, 
während der Wandlung auf ADCH/ADCL zuzugreifen. Muss es aber wohl, sonst 
würde der Free-Running Mode keinen Sinn ergeben.

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ähm,


   ldi  xl, ADCL    ; immer zuerst LOW Byte lesen
   ldi  xh, ADCH    ; danach das mittlerweile gesperrte High Byte


LDI ist hier der falsche Befehl. Du lädst die Adressen von ADCL und ADCH 
und gibst sie aus.
Das müssen IMHO LDS sein.

(Und natürlich SBRC anstelle von SBSR. Aber das hatten wir schon)

Autor: Neuling (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
1000 Dank as war es. Jetzt wo es so aussieht:
; neuen ADC-Wert lesen
loop:
; den ADC starten
   lds Temp1,ADCSRA
   sbr Temp1,1<<ADSC
   sts ADCSRA, Temp1
   
 
wait_adc:
; wenn der ADC fertig ist, wird dieses Bit gelöscht
   lds  Temp1,ADCSRA
   sbrc Temp1,ADSC
   rjmp wait_adc


; Cursor auf die 5 Stelle in Zeile 4 setzen
   ldi Temp1, 0b11011000
   rcall lcd_command

; ADC einlesen:
   lds  xl, ADCL    ; immer zuerst LOW Byte lesen
   lds  xh, ADCH    ; danach das mittlerweile gesperrte High Byte
   
   rcall lcd_number_big


   rjmp loop

bekomme ich gegen GND 00000
und gegen VCC 01019

warum nicht 1023? aber das ist wohl eine andere geschichte

Autor: Thomas Eckmann (Firma: Thomas Eckmann Informationst.) (thomase)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Neuling schrieb:
> Eine Entschuldigung und die Einsicht wäre auch ok gewesen und ich hätte
>
> mich nicht so aufgeregt. Ich kann es halt nicht leiden mich hin zu
>
> setzen und zu denke das mir einer helfen möchte und nach 5 Minuten zu
>
> merken das ich GRUNDLOS verarscht wurde und die Zeit dahin ist.

Wenn man "42" liest und das irgendwas mit Software zu tun hat, dann wird 
man nicht verarscht.

42 ist die Antwort auf die Frage nach dem Leben, dem Universum und dem 
ganzen Rest.

Dafür hat der leistungsstärkste Computer seiner Zeit 7,5 Millionen Jahre 
gebraucht, um das auszurechen. Die Antwort ist natürlich völlig 
unbefriedigend. Aber die Frage war auch falsch.

Daraufhin wurde ein neuer noch leistungsfähigerer Computer, dessen 
Hauptbestandteil die Erde war, gebaut, um die Frage auf die Antwort 42 
zu finden.
Leider wurde die Erde von einem Vogonenabrisskommando, fünf Minuten 
bevor die Berechnung fertig war, zerstört, um einer hypergalaktischen 
Umgehungsstrasse Platz zu machen.

42 findet seither in der Software Verwendung als eine Zahl ohne 
Bedeutung.
Das wirst du in diversen Beispielen in diversen Büchern finden.
Bitte zehn Informatiker, dir irgendeine Zahl zu nennen und du wirst 
mindestens 7 Mal die Zahl 42 als Antwort bekommen.

Wenn du sowas liest: "kommentierer Zeile 42 aus!",
ist das fast dasselbe wie "????????????????????????".
Will heissen, ich kann mit deiner Frage so nichts anfangen.

Softwareentwickler haben alle irgendwie einen Knall.

Das zur Netiquette und zur Zahl 42.

Nachzulesen in Douglas Adams, Per Anhalter durch die Galaxis.

Und immer ein Handtuch dabei haben...

mfg.

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Neuling schrieb:

>
> warum nicht 1023? aber das ist wohl eine andere geschichte

Referenzspannung nicht ganz exakt. Irgendwo ein kleiner 
Übergangswiderstand. Poti (zum Spannungseinstellen) geht der Schleifer 
nicht ganz bis ans Ende, etc. etc.

Autor: Neuling (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Thomas Eckmann schrieb:
> Nachzulesen in Douglas Adams, Per Anhalter durch die Galaxis.

Sorry das ich das Buch nicht gelesen habe. Wusste nicht das ich das für 
das Programmieren benötige. Steht hier auch in keinem Tutorial und wie 
mein Name schon sagt ich bin Neuling und beschäftige mich erst so seit 
einem Monat mit der sache. Vorab noch nie etwas Programmiert.

Ein Freund und ich machen das aus dem Spaß herraus wer weiter kommt. 
Idee hatten wir dazu aus der Schule bekommen. Und auch da hatte wir noch 
nie etwas mit 42 im Sinn.

Autor: Holger P. (holg_i)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
lach

Ich merke ich darf Dir keine Tipps geben wo du weiter suchen kannst. Ich 
war zuerst hier grins

Leutz immer langsam wir machen das zum Spaß und ich selber finde das 
Forum echt klasse. Ok sein begrüßung war für sein erstes fragen nicht 
gerade fein.


Ach ja Das mit Dummy1, hättest du Micha nicht schreiben solle. Die regel 
sagt aus keiner schaut vom anderen ab.

wie in meinem Blog unter Beitrag "Viele Fragen und ein kleiner Blog" 
zu sehen ist ist das meine Variable lach

Ach ja wir sind 16 und er ist echt total neu bei der Sache. Also hoho 
Brauner.

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Neuling schrieb:
> Thomas Eckmann schrieb:
>> Nachzulesen in Douglas Adams, Per Anhalter durch die Galaxis.
>
> Sorry das ich das Buch nicht gelesen habe.

Nicht dass es jetzt in diesem Zusammenhang wichtig wäre.
Wenn du Freude an verschrobenem englischen Humor im Bereich Science 
Fiction hast, dann lies es! Eine unbedingte 5-Sterne Empfehlung.

(Der Anhalter ist seit vielen Jahren so was wie ein 'running Gag' in der 
Software-Szene. Du wirst auch heute noch immer wieder auf viele Zitate 
daraus stossen, die man nicht verstehen kann, wenn man das Buch (und die 
restlichen 4 Teile der Trilogie) nie gelesen hat.)

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.