Forum: Mikrocontroller und Digitale Elektronik ad_wandler an atmega 8


von Bernhard F. (1atmel2)


Angehängte Dateien:

Lesenswert?

hallo profis,

wollte einen einfachen ad-wandler programmieren, macht auch im studio 4 
wie ich will, aber nicht auf der platine von "roland walter".
led an portb0 pin 14, rechtes poti an adc3 pin 26.

wenn ich im simulator in adch verschiedene werte > 128 bzw <128 schreibe
und das adsc bit loesche, sieht es gut aus und er setzt auch portb, bit0
bzw loescht dasselbe.

kann jemand helfen?

von Herr M. (herrmueller)


Lesenswert?

Da die REFS1 REFS0 Bits beide 0 sind, ist eine externe Ref.Spannung am 
AREF-Pin gewählt. Falls Du da nichts angeschlossen hast, musst Du 
entweder die internen 2.54V oder VCC als Referenzspannung wählen.

zB:
    ldi temp, (1<<REFS1) | (1<<REFS0) | (0<<MUX3) |(0<<MUX2) | (1<<MUX1) 
| (1<<MUX0)  ; Kanal 3  int. ref Spannung 2,56V
    out ADMUX, temp
    ldi temp, (1<<ADEN) | (1<<ADPS2) | (1<<ADPS1) | (1<<ADPS0)
    out ADCSRA, temp


Gute Nacht.

von Bernhard F. (1atmel2)


Angehängte Dateien:

Lesenswert?

erstmal danke an 'herrmüller',
jedoch funktioniert die schlatung immer noch nicht bzw hab ich was 
übersehen bzw falsch verstanden. anbei das modifizierte listing und ein 
bild des boards.

gruss bernhard.

von spess53 (Gast)


Lesenswert?

Hi

>jedoch funktioniert die schlatung immer noch nicht bzw hab ich was
>übersehen bzw falsch verstanden.

Ja. Du musst die Einstellung für REFS1/REFS0 ändern.

MfG Spess

von spess53 (Gast)


Lesenswert?

Hi

Und der Teil, wo du dem ADC sagst, das er Messen soll fehlt auch.

Vielleicht solltest du mal überlegen, ob du dir nicht mal einen Monitor 
anzuschaffst, der etwas breiter als 480 Pixel ist. Dann kann muss der 
Code nicht so an der linken Seite kleben.

MfG Spess

von Bernhard F. (1atmel2)


Lesenswert?

hallo spess53,

laut datenblatt table74 habe ich beide optionen ohne erfolg probiert,

refs1=0 & refs0=1  avcc with external capacitor at aref pin

refs1=1 & refs0=1 internal 2.56 voltage ref

kondensator habe ich noch keinen dran, ich denke eine reaktion müsste 
auch ohne denselben erfolgen.

gruss bernhard.

von Bernhard F. (1atmel2)


Lesenswert?

hallo spess53,

ich denke das waere der code für die messung ?!?
wenn ich werte in das adch register schreibe und mit f11 durchtippe, 
funktioniert es auch.

zum monitor: hab leider nur ein altes laptop und mit einer kleineren 
auflösung habe ich probleme mit den augen.




sbic adcsra,adsc            ; warte bis adc fertig
rjmp warte        ; skip if bit in i/o is cleard
in r16,adch        ; lese ergebnis

mfg ernhard.

von Bernhard F. (1atmel2)


Lesenswert?

hall spess53,
habe das ganze jetzt mit bascom probiert, funktioniert wunderbar, hätte 
aber gerne was ähnliches in assembler. das ich noch am anfang meiner 
kariere muss ich nicht extra betonen. gibt es eine möglichkeit den code 
zu disamblieren um fehler zu erkennen ?

$regfile "m8def.dat"
$crystal = 3686400
Dim Ad As Word
Config Portb = Output
Config Adc = Single , Prescaler = Auto , Reference = Avcc
Start Adc

Do

Ad = Getadc(0)

If Ad <= 340 Then
Portb.0 = 1 : Portb.1 = 0 : Portb.2 = 0
Elseif Ad > 340 And Ad <= 680 Then
Portb.0 = 0 : Portb.1 = 1 : Portb.2 = 0
Elseif Ad > 680 Then
Portb.0 = 0 : Portb.1 = 0 : Portb.2 = 1
End If
Loop

gruss bernhard.

von spess53 (Gast)


Lesenswert?

Hi

Ohne ein 'sbi adcsra,adsc' zum Starten der Messung macht der ADC nichts

MfG Spess

von Bernhard F. (1atmel2)


Angehängte Dateien:

Lesenswert?

lo,

vielen dank für deine geduld, hab das programm geändert, funktioniert
immer noch nicht schluchz.
warum funktioniert es im simulator, wenn ich das acsc-bit setze bzw 
lösche
und in das adch register werte reinschreibe ???

gruss bernhard.

von Bernhard F. (1atmel2)


Lesenswert?

noch eine frage: muss das ddrc pc3(adc3) auf null (eingang) gesetzt 
werden?
mfg b

von oldmax (Gast)


Lesenswert?

Hi
Leute, so wie dieses Programm geschrieben ist, blickt doch keiner durch. 
Versucht doch bitte etwas Struktur durch Absätze zu bekommen, das man 
das dann auch lesen kann. Hier mal ein paar Zeilen, die bei mir 
problemlos laufen.
1
;---------------------- Initialisieren Analogwandler ------------------ 1 * -------
2
;***********************************************************
3
;* die folgende Schreibweise ist nicht unbedingt mein Ding, aber die   *
4
;* Programmierer schwören darauf und weisen eine Zuweisung ala   *
5
;* 0bxxxxxxxx ab. Hinter REFSO,ADLAR, MUX2 und MUX0 stehen  *
6
;* konstante Werte, die die Bitstelle beschreiben. Ich bevorzuge     *
7
;* für mich einfach 0bxxxxxxxx                  *
8
;* Hier mal die Beschreibung der Bits im Steuerregister ADMUX     *
9
;*                    *
10
;* Bit 0- Bit 3  Kanal    Mux3 Mux2 Mux1 Mux0      *
11
;*        0     0    0    0  = Kanal 0    = Port C0  *
12
;*        0     0    0    1  = Kanal 1  = Port C1  *
13
;*        0     0    1    0  = Kanal 2  = Port C2  *
14
;*        0     0    1    1  = Kanal 3  = Port C3  *
15
;*        0     1    0    0  = Kanal 4  = Port C4  *
16
;*        0     1    0    1  = Kanal 5   = Port C5  *
17
;* Bit 4 n.belegt                *
18
;* Bit 5   Ausrichtung   0 = rechts (000000xx xxxxxxxx)     *
19
;*        1 = links (xxxxxxxx xx000000)    *
20
;* Bit 6 und 7 Auswahl Referenzspannung  Refs1  Refs0      *
21
;*          0      0  = externe Referenz    *
22
;*          0      1  = Interne Referenz AVCC  *
23
;*          1      0  = n.Benutzt      *
24
;*          1      1  = interne Referenz 2,56 V  *
25
;*                    *
26
;* und das Register mit den Bits             *
27
;*  Bit 0 = ADPS0  = Vorteiler 000 =2        *
28
;*  Bit 1 = ADPS1   = 001-111 = 2,4,8,16,32,64 und 128    *
29
;*  Bit 2 = ADPS2              *
30
;*  Bit 3 = ADIE =ADC Interrupt Enable 1 Interrupt bei ADIF  * 
31
;*  Bit 4 = ADIF =ADC Interrupt Flag   1 bei Ende Messung    *
32
;*  Bit 5 = ADFR =ADC Free Running  1 aut.Start nach Wandl.  *
33
;*  Bit 6 = ADSC =ADC Start Conversion 1 =Start Wandl.0=Ende  * 
34
;*  Bit 7 = ADEN =ADC Enable 1 = ADC ein        * 
35
;*                    *
36
;* Ergebnis 10 Bit steht in ADCH (High) und ADCL (Low)    *
37
;***********************************************************
38
Init_ADC:      ; Analogkanal initialisieren 
39
  ;LDI  a0, 0b01100000 ( so würd ich es schreiben...)
40
41
  ldi     a0, (1<<REFS0) | (1<<ADLAR)
42
  out     ADMUX, a0    
43
  ldi     a0, (1<<ADEN) | (1<<ADPS2) | (1<<ADPS0)   
44
  out     ADCSRA, a0
45
  
46
RET
47
;************************************************************

Soweit die Initialisierung. Nun das Lesen der Werte:
1
;------------ Potiwert erfassen ------------------
2
;****************************************************************
3
;* Für die Intervallzeit des Scheibenwischers wird mit einem  *
4
;* Analogeingang ein Potiwert eingelesen.        *
5
;****************************************************************
6
Read_Poti:  
7
  sbic      ADCSRA, ADSC  ; wenn der ADC fertig ist, wird dieses Bit gelöscht
8
  rjmp      End_Poti  
9
  in        Ablage, ADCL    ; immer zuerst LOW Byte lesen
10
  NOP
11
  in        Ablage, ADCH    ; danach das mittlerweile gesperrte High Byte
12
  STS  In_Analog, Ablage
13
  sbi  ADCSRA, ADSC    ; den ADC starten
14
End_Poti: 
15
      
16
RET
Auch wenn das noch nicht perfekt ist, doch so ein Aufbau ist natürlich 
besser zu lesen. Und das auch nach einem Jahr.
Gruß oldmax

von Bernhard F. (1atmel2)


Lesenswert?

mit diesem listing kann ich leider noch gar nichts anfangen. das 
datenblatt
kenne ich inzwischen, haette gerne gewusst wo der fehler liegt.


; ad wandler mit atmega 8

;.nolist
.include "m8def.inc"
.list


; led an portb, pb0 als ausgabe
; ddrb = 1

sbi ddrb,pb0

;port c3 auf eingang
cbi ddrc,pc3



;** herr müller kanal int ref spannung 2,56 v, adc0
ldi r16,(0<<refs1)|(1<<refs0)|(0<<mux3)|(0<<mux2)|(0<<mux1)|(0<<mux0)
out admux,r16

ldi r16,(1<<aden)|(1<<adfr)|(1<<adps2)|(1<<adps1)|(1<<adps0)
out adcsra,r16



convert:

sbi adcsra,adsc      ; start conversion
warte:
sbic adcsra,adsc    ; warte bis adc fertig
rjmp warte        ; skip if bit in i/o is cleard
in r16,adch        ; lese ergebnis




cpi r16,128
brlo convert_led_an

sbi portb,pb0
rjmp convert



convert_led_an:
cbi portb, pb0
rjmp convert

von Karl H. (kbuchegg)


Lesenswert?

Bernhard Fraunhofer schrieb:

> ldi r16,(1<<aden)|(1<<adfr)|(1<<adps2)|(1<<adps1)|(1<<adps0)
> out adcsra,r16

Du veränderst deine Konfigurationsbits schneller, als andere Leute ihre 
Unterwäsche.
Was hat auf einmal ADFR da drinnen zu suchen.
Selbst wenn die den Free Running MOdus benutzt, musst du die erste 
Messung immer noch händisch durch Setzen des ADSC starten.

> convert:
>
> sbi adcsra,adsc      ; start conversion
> warte:
> sbic adcsra,adsc    ; warte bis adc fertig

Das wirst du im Free Running Modus nicht erleben. Denn im Free Running 
ist der ADC NIEMALS fertig, weil sofort mit Abschluss einer Messung die 
nächste Messung beginnt.

> das datenblatt kenne ich inzwischen

vielleicht hilft dir das mehr:
http://www.mikrocontroller.net/articles/AVR-Tutorial:_ADC

Und arbeite an deiner Formatierung!
Deine ist grauenhaft!
Alles an den linken Rand zu quetschen ist maximal der Versuch, 
Labelnamen im Text unergehen zu lassen.
Wenn eine einzelne Leerzeile nicht ausreicht, eine Blockstruktur zu 
erreichen, dann schaffen das mehrere Leerzeilen hintereinander auch 
nicht. Sie ziehen nur den Code in die Länge, bringen aber ansonsten 
genau 0 mehr an Übersicht.

von Karl H. (kbuchegg)


Lesenswert?

1
; ad wandler mit atmega 8
2
3
;.nolist
4
.include "m8def.inc"
5
.list
6
7
; led an portb, pb0 als ausgabe
8
; ddrb = 1
9
      sbi DDRB, PB0
10
11
;port c3 auf eingang
12
      cbi DDRC, PC3
13
14
      ldi r16, (0<<REFS0) | (1<<REFS1) | (1<<ADLAR) | 0   ; 0 .. ADC Kanal 0
15
      out ADMUX, r16
16
17
      ldi r16, (1<<ADEN) | (1<<ADPS2) | (1<<ADPS1) | (1<<ADPS0)
18
      out ADCSRA, r16
19
20
convert:
21
      sbi ADCSRA, ADSC      ; start conversion
22
warte:
23
      sbic ADCSRA, ADSC     ; ADC löscht ADSC wenn er fertig ist
24
      rjmp warte
25
26
      in r16, ADCH          ; wegen ADLAR reicht das High Byte
27
28
      cpi r16, 128          ; mindestens halbe Referenzspannung gemessen?
29
      brlo convert_led_an   ; Nein -> Sprung
30
31
      sbi PORTB, PB0        ; Ja -> Led aus
32
      rjmp convert          ; ab zur nächsten Messung
33
34
convert_led_an:
35
      cbi PORTB, PB0        ; Led ausschalten
36
      rjmp convert          ; ab zur nächsten Messung


Wenn du nur das ADCH Register benutzen willst, musst du ADLAR benutzen. 
Ansonsten kann ADCH nur die Werte 0, 1, 2 und 3 haben.

von Karl H. (kbuchegg)


Lesenswert?

Und wenn du das nächste mal einen LÖtkolben zur Hand nimmst, dann setz 
deine Kondensatoren tiefer! Die Beinchen werden dir bald abreissen. Ein 
paar mal unabsichtlich hin und her und schon sind sie durch. Oder du 
drückst unabsichtlich von oben auf einen der Kondensatoren und reißt 
damit von der Unterseite die Leiterbahn von der Platine weg.
Schieb sie rein, bis du sie nicht mehr weiter reinkriegst! Am besten 
soll das Gehäuse auf der Platine aufsitzen und der Kondi sich nicht mehr 
bewegen lassen.

von oldmax (Gast)


Lesenswert?

Hallo Bernhard
Du scheinst etwas stur zu sein, was ich noch als geschmeichelt 
betrachte...
>mit diesem listing kann ich leider noch gar nichts anfangen.
Eigentlich wollte ich dir damit mitteilen, das es einmal die Möglichkeit 
gibt, Codezeilen auch als solche kenntlich zu machen und zum Anderen, 
das deine Schreibweise wie auch KHB feststellt, grauenhaft ist.
Es scheint dir aber völlig egal zu sein, wie deine Antworten erkennen 
lassen.
NA dann viel Spaß noch..... Ich für meinen Teil werd mich nicht durch 
solch unleserlichen Code kämpfen.
Gruß oldmax

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.