Forum: Mikrocontroller und Digitale Elektronik ADC Problem Attiny 45


von Lukas (Gast)


Lesenswert?

Hallo habe ein Problem beim Einlesen einer ADC. Ich sehe im I/O View 
dass die Register ADCL und ADCH upgedatet werden nach jeder ADC kann sie 
aber nicht in meine Register auslesen.

ADCinit

  ldi    temp, 0b10000001    ;Prescaler
  out    ADCSRA,temp

  ldi    temp, 0b00100000
  out    DIDR0,temp

  ret


ADCstart2:

      ldi  temp,0b00000001
      out    ADMUX,temp

      ldi    temp, 0b11000001

      out    ADCSRA, temp
      ;clr    ADCH
      ;clr    ADCL

complete2:
      ldi    temp,ADCSRA
      sbrc   temp,ADSC
      rjmp  complete2


      lds    r16,ADCH
      lds    r17,ADCL



      ret


Ich hänge gerade.
Sieht wer den Fehler?

LG

von LostInMusic (Gast)


Lesenswert?

"in" statt "lds" ist richtig:

in     r16,ADCH
in     r17,ADCL

von LostInMusic (Gast)


Lesenswert?

Und Du musst auch noch ein "ldi" in ein "in" abändern. Finde selbst 
heraus, welches.

Vielleicht solltest Du Dir die genauen Unterschiede zwischen "ldi", 
"lds" und "in" nochmal klarmachen.

von Lukas (Gast)


Lesenswert?

Oh

in temp,ADCSRA

Ja die Unterschiede sind mir klar, nur ist das ja wieder vom 
Prozessorabhängig, bzw. abhängig wo das Register liegt im Prozessor

von Peter II (Gast)


Lesenswert?

Lukas schrieb:
> Ja die Unterschiede sind mir klar, nur ist das ja wieder vom
> Prozessorabhängig, bzw. abhängig wo das Register liegt im Prozessor

bei ASM ist immer vom Prozessor abhängig. Wenn du es mit C 
Programmierst, dann musst du so etwas nicht beachten.

von c-hater (Gast)


Lesenswert?

Lukas schrieb:

> Ja die Unterschiede sind mir klar, nur ist das ja wieder vom
> Prozessorabhängig, bzw. abhängig wo das Register liegt im Prozessor

Richtig. Und wenn man zu faul ist, das jeweils nachzuschlagen, schreibt 
man sich einfach zwei Macros, die einem die Arbeit abnehmen. Am besten 
mit Warnung, falls lds/sts statt in/out benutzt werden muß, damit man 
bei timingkritischen Sachen keine unangenehmen Überraschungen erlebt.
1
.EQU WARN_MMIO=1 ;oder 0 zum Unterdrücken der Warnungen
2
3
;->@0: Zielregister (MCU)
4
;  @1: Quellregister (IO)
5
.MACRO UNI_IN
6
.IF @1 < $40
7
  in @0,@1
8
.ELSE
9
  lds @0,@1
10
  .IF WARN_MMIO
11
    .WARNING "One extra tick for MMIO"
12
  .ENDIF
13
.ENDIF
14
.ENDMACRO
15
16
;->@0: Zielregister (IO)
17
;  @1: Quellregister (MCU)
18
.MACRO UNI_OUT
19
.IF @0 < $40
20
  out @0,@1
21
.ELSE
22
  sts @0,@1
23
  .IF WARN_MMIO
24
    .WARNING "One extra tick for MMIO"
25
  .ENDIF
26
.ENDIF
27
.ENDMACRO
Alternativ könnte man auch zwei Macros schreiben, die immer MMIO 
benutzen (und damit ggf. einen Takt mehr verbraten als nötig). Das hätte 
immerhin den Vorteil, daß das Timing Device-unabhängig wird und sähe 
dann so aus:
1
;->@0: Zielregister (MCU)
2
;  @1: Quellregister (IO)
3
.MACRO MMIO_IN
4
.IF @1 < $40
5
  lds @0,@1+$20
6
.ELSE
7
  lds @0,@1
8
.ENDIF
9
.ENDMACRO
10
11
;->@0: Zielregister (IO)
12
;  @1: Quellregister (MCU)
13
.MACRO MMIO_OUT
14
.IF @0 < $40
15
  sts @0+$20,@1
16
.ELSE
17
  sts @0,@1
18
.ENDIF
19
.ENDMACRO
Benutzen kann man die Macros dann genau wie von in bzw. out gewohnt, 
also z.B.:
1
  UNI_IN R16,ADCH
oder
1
  MMIO_OUT ADCSRA,R20

: Bearbeitet durch User
von der alte Hanns (Gast)


Lesenswert?

> in    r16,ADCH
> in    r17,ADCL


Die Reihenfolge ist falsch:

"ADCL must be read first, then ADCH."

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.