Forum: Mikrocontroller und Digitale Elektronik AtTiny13 & 2xADC


von Sebastian F. (snake080)


Lesenswert?

Hallo,
ich habe mich schon durch die Suche gewühlt aber bisher nichts 
gefunden...
Ich habe folgendes, einfaches Problem: Ich möchte 2 ADC-Werte auslesen 
und verarbeiten. Aber es lässt sich nur einer auslesen. Sobald ich beide 
in der main lesen lasse ist der Wert 0... Ich denke mal es liegt an der 
Konfiguration des ADC. Aber ich finde nicht den Fehler...

Der Code sieht so aus:
.include "tn13def.inc"
.def temp1  = r16
.def timer1  = r17

ldi temp1, LOW(RAMEND)
out SPL, temp1

;Hardware
sbi DDRB,0  ;FET
sbi DDRB,1  ;LED gelb (0-an)
sbi DDRB,3  ;LED rot (1-an)
cbi PORTB,0
sbi PORTB,1
cbi PORTB,3

init:
ldi temp1, 0b10000011  ; ADC enable / f=150kHz
out ADCSRA, temp1

ldi temp1, 0b00000000  ; Analog Komperator aus / Timer Compare Match
out ADCSRB, temp1

ldi temp1, 0b10000011  ; Analog Komperator aus
out ACSR, temp1

ldi temp1, 0b01000001  ; Int.1,1V ref  ADLAR-0  ADC1
out ADMUX, temp1

ldi temp1, 0b00010100  ; Digital Input Disable
out DIDR0, temp1

main:
rcall tcheck
rcall ucheck
rjmp main

ucheck:
ldi temp1, 0b01000001  ; Int.1,1V ref  ADLAR-0  ADC1
out ADMUX, temp1
sbi ADCSRA, ADSC    ; ADC start
  ucheck1:
  sbis ADCSRA, ADIF
  rjmp ucheck1
  in YL, ADCL
  in YH, ADCH
        mov temp1, YH
  clc
  subi temp1, 0x10
  brcs stop
ret

tcheck:
ldi temp1, 0b01100010  ; Int.1,1V ref  ADLAR-1  ADC2
out ADMUX, temp1
sbi ADCSRA, ADSC    ; ADC start
  tcheck1:
  sbis ADCSRA, ADIF
  rjmp tcheck1
  in YL, ADCL
  in YH, ADCH
  mov temp1, YH
  clc
  subi temp1, 0x46
  brcs stop    ; Utemp > 270mV (>60°)?
ret

stop:
sbi PORTB,1    ; LED aus
sbi PORTB,3    ; LED an
rjmp stop

von spess53 (Gast)


Lesenswert?

Hi

>stop:
>sbi PORTB,1    ; LED aus
>sbi PORTB,3    ; LED an
>rjmp stop

Dir ist bewusst, das du da nicht mehr herauskommst?

MfG Spess

von Karl H. (kbuchegg)


Lesenswert?

sbis ADCSRA, ADIF
  rjmp ucheck1


Nimm zum Checken ob der ADC fertig ist, das ADSC Bit.
Du setzt es um den ADC zu starten und wenn er fertig ist, setzt er es 
zurück.

Das ADIF Flag müsstest du aktiv löschen, was du nicht tust.

von Sebastian F. (snake080)


Lesenswert?

Die Spannungen müssen über bestimmten Pegeln liegen 
(Temperatursensoren).
Wenn die unterschritten sind, soll die rote LED angehen und Feierabend 
sein.


sbis ADCSRA, ADIF

Ich hatte mal auf nem Mega8 4 ADC's hintereinander mit dem gelesen, da 
hatte es geklappt... habs aber auch mal so probiert... klappt immer nich 
nicht :(

von Karl H. (kbuchegg)


Lesenswert?

Und was willst du damit
1
        mov temp1, YH
2
  clc
3
  subi temp1, 0x10
erreichen?
Das High Byte kann maximal 3 werden. Oder hast du ADLAR gesetzt?

Warum machst du es dir und deinem Leser so schwer, rauszukriegen was du 
gesetzt hast?
1
  ldi temp1, 0b01000001  ; Int.1,1V ref  ADLAR-0  ADC1

sowas wie ADLAR-0 oder ADLAR-1 gibt es nicht.



wo sieht man leichter was du im Register eingeschaltet hast?
Deine Version,
1
  ldi temp1, 0b01100010  ; Int.1,1V ref  ADLAR-1  ADC2
oder die hier:
1
  ldi temp1, (1<<REFS0) | (1<<ADLAR) | 2

von Sebastian F. (snake080)


Lesenswert?

Sorry, wenn das Kommentar nicht so toll ist. Ich dachte, das reicht hin. 
Ja das ADLAR ist da drin gesetzt. Und das clc hatte ich noch drin um 
alles auszuschließen.

von Karl H. (kbuchegg)


Lesenswert?

Sebastian F. schrieb:
> Sorry, wenn das Kommentar nicht so toll ist. Ich dachte, das reicht hin.
> Ja das ADLAR ist da drin gesetzt.

Nein ist es nicht.

In
1
  ldi temp1, 0b01000001  ; Int.1,1V ref  ADLAR-0  ADC1
ist ADLAR nicht gesetzt.

Daher nochmal der Appell:
Schreibs so
1
  ldi temp1, (1<<REFS0) | (1<<ADLAR) | 1  ; Int.1,1V ref  ADLAR ADC1

dann kann auch ein Blinder greifen, dass ADLAR gesetzt ist.
Und zwar wirklich und nicht nur als Wunschdenken im Kommentar.

von Sebastian F. (snake080)


Lesenswert?

da ich mich mit der schreibung so ca. 0 auskenne, schreibe ich das so.
Bei dem tcheck ist ADLAR gesetzt, bei ucheck nicht. Das ist absicht. 
Aber es ist auch egal, ob es gesetzt ist oder nicht. Die Spannung ist 
auf jeden Fall höher als der Wert, der angegeben ist.

von Karl H. (kbuchegg)


Lesenswert?

Sebastian F. schrieb:
> da ich mich mit der schreibung so ca. 0 auskenne, schreibe ich das so.

Jetzt weißt du es, dass das besch...eiden ist und schwenkst um auf die 
bessere Schreibweise.

> Bei dem tcheck ist ADLAR gesetzt, bei ucheck nicht. Das ist absicht.

Wie soll dann bitte im High Byte vom ADC jemals etwas größeres als 0x10 
rauskommen?

> Aber es ist auch egal, ob es gesetzt ist oder nicht. Die Spannung ist
> auf jeden Fall höher als der Wert, der angegeben ist.

Wenn ADLAR nicht gesetzt ist, kann das High_byte vom ADC nur die Werte 
0, 1, 2, 3 haben. Andere Werte sind nicht möglich! Ohne ADLAR ist es 
völlig ausgeschlossen, dass du im High Byte jemals 16 oder gar noch 
größere Werte vorfinden wirst.

von Sebastian F. (snake080)


Lesenswert?

Stimmt.
Aber lustigerweise habe ich da irgendwo ne Macke beim kopieren gehabt... 
Be ucheck, wo das ADLAR 0 ist, wird YL gelesen.

von Sebastian F. (snake080)


Lesenswert?

Selbst so klappt es nicht :-(


ldi temp1, (1<<ADEN) | (1<<ADPS1) | (1<<ADPS0)  ; ADC enable / f=150kHz
out ADCSRA, temp1

ldi temp1, 0x00                  ; Analog Komperator aus / Timer Compare 
Match
out ADCSRB, temp1

ldi temp1, (1<<ACD) | (1<<ACIS1) | (1<<ACIS0)  ; Analog Komperator aus
out ACSR, temp1

ldi temp1, (1<<REFS0) | (1<<MUX0)        ; Int.1,1V ref  ADLAR-0  ADC1
out ADMUX, temp1

ldi temp1, (1<<ADC2D) | (1<<ADC1D)        ; Digital Input Disable
out DIDR0, temp1

main:
rcall ucheck
rcall tcheck
rjmp main

ucheck:
ldi temp1, (0<<ADLAR) | (0<<MUX1) | (1<<MUX0)  ; Int.1,1V ref / ADLAR-0 
/ ADC1
out ADMUX, temp1
sbi ADCSRA, ADSC    ; ADC start
  ucheck1:
  sbis ADCSRA, ADSC
  rjmp ucheck1
  in YL, ADCL
  in YH, ADCH
  mov temp1, YL
        subi temp1, 0x15
        brmi stop
ret

tcheck:
ldi temp1, (1<<ADLAR) | (1<<MUX1) | (0<<MUX0)  ; Int.1,1V ref / ADLAR-1 
/ ADC2
out ADMUX, temp1
sbi ADCSRA, ADSC    ; ADC start
  tcheck1:
  sbis ADCSRA, ADSC
  rjmp tcheck1
  in YL, ADCL
  in YH, ADCH
  mov temp1, YH
  clc
  subi temp1, 0x46
  brcs stop    ; Utemp > 270mV (>60°)?
ret

stop:
  sbi PORTB,1    ; LED gelb aus
  sbi PORTB,3    ; LED rot an
  rjmp stop

von Karl H. (kbuchegg)


Lesenswert?

Sebastian F. schrieb:

>   mov temp1, YL
>         subi temp1, 0x15
>         brmi stop

Du willst hier BRLO benutzen und nicht BRMI

BRLO ist für vorzeichenlose Zahlen, BRMI für Vorzeichenbehaftete.
Die Notation vorzeichenbehaftete Zahlen ist aber hier unangebracht, wenn 
du nur das Low-Byte einer Zahl betrachtest. Bit 7 hat hier nicht die 
Funktion eines Vorzeichens.

http://www.mikrocontroller.net/articles/AVR-Tutorial:_Vergleiche#Bedingte_Spr.C3.BCnge

von Sebastian F. (snake080)


Lesenswert?

Ist das nicht egal, wenn durch das "subi" die entsprechenden Flags 
gesetzt werden? Auch wenns unkoventionell ist frage ich ja einfach das 
N-Flag ab.

von Kluchscheißernder N. (kluchscheisser)


Lesenswert?

Das nützt Dir nix, das N-Flag ist nur eine Kopie von Bit 7.
Schau in der Beschreibung des Befehlssatzes an, welcher Branch welche 
Flags berücksichtigt.

von Karl H. (kbuchegg)


Lesenswert?

Sebastian F. schrieb:
> Ist das nicht egal, wenn durch das "subi" die entsprechenden Flags
> gesetzt werden? Auch wenns unkoventionell ist frage ich ja einfach das
> N-Flag ab.

Du rechnest eine Subtraktion.

Wenn dein ADC Wert 0x0192  also dezimal 402 ist, dann ist das Low-Byte 
davon 0x92.  Da in dieser Zahl das 7. Bit gesetzt ist, ist das für BRMI 
eine negative Zahl. Selbst wenn du dann noch 0x10 davon abziehst, ist es 
immer noch eine negative Zahl.


Nimm die richtigen Befehle für den richtigen Datentyp.
Du hast hier kein Vorzeichen! Also benutz auch nicht die Abfragen für 
vorzeichenbehaftete Zahlen.

Du willst feststellen, ob es bei der Subtraktion einen Unterlauf gab. 
Zuständig dafür ist BRLO oder BRCS

von Sebastian F. (snake080)


Lesenswert?

So, ich habe alles mal nach den Tipps geändert.

Aber leider ist es nach wie vor so, dass der erste ADC funktioniert aber 
der zweite springt immer in die stop-Schleife.
Im Simulator funktioniert alles.
Habe ich vielleicht bei der Initialisierung einen Fehler?


ucheck:
ldi temp1, (0<<ADLAR) | (0<<MUX1) | (1<<MUX0)
out ADMUX, temp1
sbi ADCSRA, ADSC    ; ADC start
  ucheck1:
  sbic ADCSRA, ADSC
  rjmp ucheck1
  in YL, ADCL
  in YH, ADCH
  mov temp1, YL
  subi temp1, 0x15
  brcc stop1
ret

tcheck:
rcall loop
ldi temp1, (1<<ADLAR) | (1<<MUX1) | (0<<MUX0)
out ADMUX, temp1
sbi ADCSRA, ADSC    ; ADC start
  tcheck1:
  sbic ADCSRA, ADSC
  rjmp tcheck1
  in YL, ADCL
  in YH, ADCH
  mov temp1, YH
  subi temp1, 0x46
  brcs stop2
ret

stop1:
    sbi PORTB,3    ; LED rot an
    rjmp stop1

stop2:
    cbi PORTB,1    ; LED gelb an
    rjmp stop2

von Hannes L. (hannes)


Lesenswert?

Schau mal hier:
Beitrag "Re: Spannungsmesserbau mit XMega128"
Da werden zwei ADCs des Tiny24 ausgelesen und deren Werte separat 
aufgearbeitet und angezeigt.

Es schadet Dir vermutlich nicht, auch mal etwas auf den dortigen 
Programmierstil zu achten.

...

von spess53 (Gast)


Lesenswert?

Hi

>  in YL, ADCL
>  in YH, ADCH
>  mov temp1, YL
>  subi temp1, 0x15
>  brcc stop1

Diese Abfrage ist nicht eindeutig. Der Fall, das YL<$15 ist tritt bei 
10Bit, wenn ich mich nicht verrechnet habe, 88 mal auf. Ausserdem gibt 
es Vergleichsbefehle (

Mach eine eindeutige Abfrage:
1
   ldi temp1,0
2
   cpi YL,$15
3
   cpc YH,temp1
4
   brcc ....

MfG Spess

von Sebastian F. (snake080)


Lesenswert?

Das ucheck funktioniert einwandfrei. beim tcheck ist das Problem, dass 
er immer ins stop springt...

von Karl H. (kbuchegg)


Lesenswert?

Das andre was ich tun würde.
Ich würde erst mal nicht 'stoppen' wenn der ADC Wert zu klein ist, 
sondern beim Unterschreitung 1 LED ein bei Überchreiten des Grenzwerts 
die LED wieder ausschalten.

Den 2. ADC würde ich zunächst mal links liegen lassen und mich nur auf 1 
konzentrieren. Wenn irgendwie geht, dann die restlichen Pins vom Tiny 
ebenfalls mit LED bestücken und mir den ADC Wert dort so gut es geht 
ausgeben lassen. Ziel ist es, herauszufinden, ob vom ADC überhaupt 
sinnvolle Werte kommen.

Im Moment stocherst du im Nebel, und da musst du Abhilfe schaffen, indem 
du irgendwie an den Messwert rannkommst. Und zwar in echt und nicht im 
Simulator.


Du hast das klassische Problem: zuviel auf einmal geschrieben, nichts 
funktioniert und jetzt weißt du nicht wo du mit der Suche anfangen 
sollst.

von Sebastian F. (snake080)


Lesenswert?

Alle anderen Pins sind belegt. Wie gesagt, den ADC1 kann ich problemlos 
lesen/auswerten. Habe ja so umgeändert, dass bei nem Fehler eine der 
LEDs angeht. Werde mal nen blink-Zähler für den 2.ADC reinbauen...

von spess53 (Gast)


Lesenswert?

Hi

>Das ucheck funktioniert einwandfrei.

Denkst du.

MfG Spess

von Sebastian F. (snake080)


Lesenswert?

Das weiss ich, wenn ich in der main-Schleife das tcheck wegmache und 
eine Spannung drauf gebe, mit dem Oszi kontrolliere, und beobachte was 
passiert...
0V - kein Problem, geht wieder raus(Dauerloop). 25mV - springt in die 
Stopschleife und die LED geht an. Wenn ich die tcheck- Schleife 
dazunehme geht die andere LED an... also warum sollte die erste nicht 
funktionieren?

von spess53 (Gast)


Lesenswert?

Hi

Wohin wird er wohl springen, wenn Y z.B. den Wert $0115 hat?

MfG Spess

von Sebastian F. (snake080)


Lesenswert?

Warum $0115? Es gibt YL & YH. Beide maximal 255. Ich frage doch nur YH 
ab, wo Bit 3-10 sind...

von spess53 (Gast)


Lesenswert?

Hi

>Warum $0115? Es gibt YL & YH. Beide maximal 255. Ich frage doch nur YH
>ab, wo Bit 3-10 sind...

Meine Aussage bezieht sich auf dein 'ucheck'. Du springst nach 'stop' 
wenn YL >=$15 ist. Und das passiert wenn der ADC Werte von 
$0015...$00FF, $0115...01FF,$0215...02FF und $0215...02FF liefert.

MfG Spess

von MWS (Gast)


Lesenswert?

Wenn ADC1 > 22mV dann stop1
Wenn ADC2 < 300mV dann stop2

Ist es das was, Du willst ?

Außerdem, besteht die Möglichkeit, daß ADC1 gleich zu Beginn > 275mV ist 
? Denn das könnte aufgrund der Auswertung einzig des LB nicht erkannt 
werden.

von Sebastian F. (snake080)


Lesenswert?

Genau, das ist das was ich will.
ADC1 kann am Anfang nur 0V sein, da ich nichts angeschlossen habe. An 
dem Port hängt über 10k ein 0,2 Ohm Widerstand auf Masse.

von Karl H. (kbuchegg)


Lesenswert?

Sebastian F. schrieb:
> Genau, das ist das was ich will.
> ADC1 kann am Anfang nur 0V sein, da ich nichts angeschlossen habe. An
> dem Port hängt über 10k ein 0,2 Ohm Widerstand auf Masse.

Du musst deine Teststategien verbessern.
Wie unterschiedest du den Fall davon, dass du einen Programmfehler hast 
und der ADC aufgrund dieses Programmfehlers 0 liefert?


Schmeiss den Widerstand raus (und was du sonst noch drann hängen hast) 
und bau mit einem Poti einen Spannungsteiler auf. Damit speist du eine 
bestimmte Spannung in den ADC ein (Poti deshalb weil es dann beim 
nächsten Programmlauf einigermassen reproduzierbar ist solange du nicht 
am Poti drehst. Und das ist das Um und Auf in der ganzen Debuggerei: 
Reproduzierbarkeit)

Dann legst du dir das High Byte vom ADC (wenn ADLAR ausgeschaltet ist), 
bzw. die obersten beiden Bits vom High Byte (wenn ADLAR eingschaltet 
ist) auf die beiden LED. Beim Durchdrehen des Potis (und damit verändern 
der SPannung am ADC Eingang von 0 bis 1.1V) müssen die beiden LED die 
Binärzahlen 0 bis 3 anzeigen. Und zwar korrelierend mit deiner Poti 
Stellung. Erst dann hast du die Gewissheit, dass deine ADC 
funktionieren. Ehe ich das nicht sehe, würde ich mich auf keinen Fall 
auf irgendetwas festlegen wollen.
Wenn möglich würde ich sogar noch eine dritte LED dazunehmen (selbst 
wenn das bedeutet, dass ich andere Hardware temporär abklemmen muss) und 
natürlich dann die obersten 3 Bit jedes Ergebnisses. Die LED zeigen mir 
dann 8 Stufen vom ADC an.

Du testest beide ADC unabhängig voneinander, damit du die vorhandenen 
LED für 1 ADC einsetzen kannst.


Und erst dann, wenn ich mich davon überzeugt habe, dass die ADC 
brauchbare Werte liefern, erst dann geht es daran, diese Werte in 
irgendeiner Form auszuwerten.

von MWS (Gast)


Lesenswert?

Wird denn auch ADC2/PB4/Pin3 mit der nötigen Spannung versorgt, damit er 
nicht gleich in stop2 springt ?

von Sebastian F. (snake080)


Lesenswert?

Jupp, die Spannung passt.
Aber ich werde das jetzt so machen, wie Hr. Buchegger das vorschlägt:
Ich mache eine nue Platine mit entsprechend 2 Potis und der Rest 
LED's...
Meld mich dann gleich wieder :)

von Sebastian F. (snake080)


Lesenswert?

OK, hab gesehen dass die ADC's funktionieren...
Auch beide Kanäle gleichzeitig...
Problem: Ich füge es 1:1 in das Originalprogramm ein und nix geht :(

von MWS (Gast)


Lesenswert?

> Problem: Ich füge es 1:1 in das Originalprogramm ein und nix geht :(
Dann würd' ich vorschlagen den Code so zu posten wie er geht und einmal 
das Originalprogramm in letzter Fassung, wie's nicht geht.

von Sebastian F. (snake080)


Angehängte Dateien:

Lesenswert?

Einen guten Montag morgen wünsche ich.
Ich füge der Einfachheit halber mal die Programme in Dateien ein.
Das Testprogramm läuft. Auch wenn ich die LED's hin und hersetzte.
Das Hauptprogramm springt immer in die Stop Routine...

von Sebastian F. (snake080)


Lesenswert?

Kleines update: Hatte am Freitag ein Testprogramm, das lief. Aber aus 
versehen gelöscht. Jetzt funktioniert es doch nicht mehr... trotz dass 
ich die ADC's wechsel wird irgendwie ein Mischmasch aus beiden 
ausgegeben... ??? Die Bits werden angezeigt und hochgezählt. Und je nach 
Poti, das ich drehe werden dann die LED's noch ein wenig heller...

von MWS (Gast)


Lesenswert?

Ich würd die Stop-Condition erstmal weglassen und eine Led setzen, um 
den Status zu sehen. Ansonsten würd' ich nach Einschalten des Wandlers 
entweder eine Dummy-Messung machen, oder ein Delay bis zur ersten 
Messung setzen. Alternative ist immer zwei Wandlungen ausführen und 
erste verwerfen.

> Kleines update: Hatte am Freitag ein Testprogramm, das lief. Aber aus
> versehen gelöscht.
Was soll das heißen ? Daß die gepostete test.asm jetzt nicht als 
funktionierend zu betrachten ist ? Deas ist schon alles etwas konfus. 
Ein wenig mehr Zielgerichtetheit würde nicht schaden.

von Kluchscheißernder N. (kluchscheisser)


Lesenswert?

Zürnet ihnen nicht, denn sie wissen nicht was sie tun...

MfG

von Sebastian F. (snake080)


Angehängte Dateien:

Lesenswert?

Ich bin wieder beim Testprogramm...
Das läuft, wenn ich eine Zählschleife & Doppelt lesen mache... Wenn 
eines von beiden nicht ist, funktionierts auch nicht... OK, 
Geschwindigkeit ist mir nicht wichtig.
Jetzt habe ich nichts geändert, ausser meine Zahlen abzuziehen... und es 
passt nicht. Die LED, die angesprochen wird bei den jewailigen Poti 
leuchtet... aber bei 20mV. Nicht die eine bei 20mV und die andere bei 
300mV...
Wo ist da der Fehler???

von MWS (Gast)


Lesenswert?

Wird das jetzt Programmieren durch Raten ? Du solltest gezielt aufbauen, 
sonst wird das nix.

Darf ich mir jetzt eine der zwei Versionen aussuchen ? :D

Bei test.asm verwendest Du zweimal ADCH zum Vergleich, das "Konzept" war 
vorher ein anderes, bei test2.asm sollte Led2 sofort bei Poti = 0V 
angehen. Diese Led ist ja für jeden Wert unterhalb 0x46 an und geht erst 
ab diesem Wert aus.

Steht übrigens nirgends im DB, daß die Werte aus dem ADC geholt werden 
müssen, wenn man sie nicht benötigt.

Das Problem vorhin bestand daraus daß beim ersten Start des ADC das 
Setzen des ADSC Bits den AD Converter initialisiert, so im DB des Tiny13 
nachzulesen. Wenn man dann dieses Ergebnis dann hernimmt und sofort in 
eine Endlosschleife rennt, braucht man sich über die Nichtfunktion nicht 
zu wundern.
An Deiner Stelle würde ich erst mal mehr die Basics üben, Tutorials 
durcharbeiten, DB lesen, usw., etwas zu dem ich angesichts der gezeigten 
Programmiererei ernsthaft raten würde.

von Sebastian F. (snake080)


Lesenswert?

Das ist kein programmieren durch raten. Das Test.asm funktioniert. Das 
Test2.asm funktioniert nicht.
Ich hatte ganz am Anfang (1.Post) mal gefragt, ob ich beim 
initialisieren vielleicht einen Fehler habe. Aber anstatt von einem 
einfachen Tipp wurde ja gleich auf allem anderen rumgehackt. Ich bin 
kein Programmierer..
Das ADSC-Bit setzte ich nicht, ich lese es aus - was mir hier geraten 
wurde...

von Kluchscheißernder N. (kluchscheisser)


Lesenswert?

> Das ADSC-Bit setzte ich nicht,

Und wie soll der ADC arbeiten, wenn Du ihn nicht (durch Setzen des 
ADSC-Bits) startest???

> ich lese es aus

Das hat nur Sinn, wenn Du es zuvor gesetzt hast.

> - was mir hier geraten
> wurde...

Ja, Dir wurde geraten, statt des Interrupt-Pending-Flags des ADC das 
ADSC-Flag auszulesen, da dies einfacher ist. Und dieser Rat ist richtig, 
da Du den ADC ja nicht mittels Interrupt betreiben möchtest.

- Du setzt das ADSC-Bit per Programm
- Der ADC beginnt zu "rattern" (arbeitet seinen Zyklus ab)
- Wenn der ADC fertig ist, löscht er das ADSC-Bit und setzt das ADIF-Bit

Das ADIF-Bit sorgt in Verbindung mit dem ADIE-Bit für das Auslösen eines 
Interrupts, da Du diese Betriebsart nicht nutzt, musst Du Dich darum 
nicht kümmern.

So, nun zu Deinem Code.
Nehmen wir z.B. diese Sequenz:
1
ucheck:
2
ldi temp1, (1<<REFS0) | (0<<ADLAR) | (0<<MUX1) | (1<<MUX0)
3
out ADMUX, temp1
4
sbi ADCSRA, ADSC
5
  ucheck1:
6
  sbis ADCSRA, ADSC
7
  rjmp ucheck1
8
  in YL, ADCL
9
  in YH, ADCH
Du setzt also Messquelle, Referenzquelle und Formatierung (ADMUX). Ich 
habe es jetzt nicht überprüft, gehe aber davon aus, dass es richtig ist.

Dann setzt Du ADSC in ADCSRA, worauf der ADC die Arbeit aufnimmt. Das 
ADSC-Bit bleibt solange gesetzt, bis der ADC fertig ist, dann löscht der 
ADC dieses Bit per Hardware.

Nun fragst Du das ADSC-Bit ab:
 sbis adcsra,adsc (Skip, if Bit in I/O is set, also überspringe den 
folgenden Befehl, wenn das Bit gesetzt ist)

Das Bit ist natürlich (noch) gesetzt, denn der ADC ist ja noch nicht 
fertig. Also hüpft das Programm über den Rücksprung (Schleife) 
drüberweg, liest den noch nicht vorhandenen Messwert aus und geht zur 
Tagesordnung über.

Haste nun gemerkt, dass Deine Bedingung logisch falsch ist? Anstatt zu 
warten, bis der ADC fertig ist, springst Du weiter, solange er noch 
beschäftigt ist. Und da Du bereits über alle Berge bist, wenn der ADC 
irgendwann mal fertig wird, wirst Du es nie bemerken (dass er fertig 
ist).

In ucheck2 ist natürlich derselbe Fehler. Den Rest habe ich nicht 
genauer untersucht, da ich mich mit Deinem Konzept nicht anfreunden 
kann. Ich programmiere anders. Und ich bin (von der Ausbildung her) auch 
kein Programmierer, ich mache das auch nur als Hobby.

Viel Erfolg.

MfG

von MWS (Gast)


Lesenswert?

@kluchscheisser, Respekt, das entging mir, das falsche sbis hätte ich 
sehen müssen ;-)

@snake080, das war nicht böse von mir gemeint, ich vermisste nur eine 
gewisse Kontinuität in Deinen Programmierbemühungen :D

von Kluchscheißernder N. (kluchscheisser)


Lesenswert?

Nun isser eingeschnappt...

von MWS (Gast)


Lesenswert?

> Nun isser eingeschnappt...
Würd' eher sagen, die Schaltung geht jetzt, und damit entfällt aus Sicht 
des TO's jegliche weitere Kommunikationsnotwendigkeit. Jedenfalls 
solange bis das nächste Problem ansteht...

von Sebastian F. (snake080)


Lesenswert?

Hi, bei beiden falsch getippt. :)
Ich konnte nicht weiter probieren, da ich einen Anruf bekommen habe, 
dass meine Steine für die Garage da sind. Ergo - Früh Feierabend & 
Urlaub. Am Freitag bin ich wieder dran. Das mit dem checken von dem 
"sbis" war schon ein super Tipp. Aber irgendwas hatte noch nicht ganz 
geklappt.

Erst mal Danke an euch, die mir helfen!!!

von Sebastian F. (snake080)


Angehängte Dateien:

Lesenswert?

So, habe die Testdatei richtig und fertig zum laufen bekommen. Ich denke 
mal, dass ich das jetzt auch ins richtige Programm einbauen kann.
Danke!

von spess53 (Gast)


Lesenswert?

Hi

> mov temp1, YL
> subi temp1, 0x15
> brcc led1

Der Befehl 'cpi' ist dir wohl noch nicht untergekommen?
1
  cpi YL,0x15
2
  brcc led1

macht das gleich wie dein Konstrukt.

MfG Spess

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.