mikrocontroller.net

Forum: Mikrocontroller und Digitale Elektronik ADC mit ATMega16 (Assambler) Problem


Autor: Fabi (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo,

Ich hab ein problem mit einer einfachen Singel-Messunge des ADC vom 
ATMega16.
Ich verwendet eine STK500 und bin nun am ende meiner Kenntnisse.

Die erste messung wird durchgeführt aber jeder weitere hat den Wert der 
ersten. Ich hab im Tutorial hier gelesen das die werte übernohmen werden 
müssen, nur ich weiß nicht wie genau.

Vorgabe: es muss mit Assambler programmiert werden.

Hier ist mein programmcode... der leider nach der erste messung nichts 
mehr einliest.
.INCLUDE "M16def.inc"

;*********************************************************************************
;* Definitionen und Zuweisungen                                                  *
;*********************************************************************************
.DEF akku = r16


;*********************************************************************************
;* Interrupt Vektortabelle                                                       *
;*********************************************************************************
.CSEG
.ORG 0x000
RJMP MainInit
.ORG 0x01C
RJMP ADinterput


;*********************************************************************************
;* Main Initzialisierung                                                         *
;*********************************************************************************
MainInit:

;Stackinitialisierung:
LDI akku, HIGH(RAMEND)
OUT SPH, akku
LDI akku, LOW(RAMEND)
OUT SPL, akku

;Portzuweisung EINGÄNGE PORT A (Für Analoges Signal)
LDI akku, 0x00
OUT DDRA, akku

;Portzuweisung AUSGÄNGE PORT B
LDI akku, 0xFF
OUT DDRB, akku
out PORTB, akku

;Portzuweisung EINGÄNGE PORT D
LDI akku, 0x00
OUT DDRD, akku

;**********************************
;*    AD-Converter einstellen.    *
;**********************************

clr akku

;Teiler einstellen Vorteiler 8 und Wandler Aktiveren
;ldi akku, (1<<ADEN) | (0<<ADPS2) | (1<<ADPS1) | (1<<ADPS0)
LDI akku, 0b10000011
OUT ADCSRA, akku

;Kanal ADC0 Wählen und Refernspannung Nutzen
;ldi akku, (1<<REFS0) | (1<<REFS1)
ldi akku, 0b11000000
OUT ADMUX, akku 

;*********************************************************************************
;* MAINPROGRAMM                                                                  *
;*********************************************************************************

Mainloop:
  sbis PIND, PD0  ;Taste 0 gedrückt = Einzelmessung
  rcall EINZEL
  sbis PIND, PD1
  rcall CLEAR
rjmp mainloop


;*********************************************************************************
;* Unterprogramm Einzelmessung                                                   *
;*********************************************************************************
EINZEL:
  ;Messung starten
  sbi ADCSRA, ADSC
  ;Schleife für Messung fertig
warte:
  sbic ADCSRA, ADSC
  rjmp warte
  in akku, ADCL
  com akku
  OUT PORTB, akku

ret

;*********************************************************************************
;* Unterprogramm LEDs - Clear                                                    
;*********************************************************************************
CLEAR:
  ser akku
  OUT PORTB, akku
  com akku
  OUT ADCL, akku
  OUT ADCH, akku
ret


ADinterput:
  nop
reti

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

Bewertung
0 lesenswert
nicht lesenswert
rjmp warte
  in akku, ADCL
  com akku
  OUT PORTB, akku


Dann lies noch mal im Artikel nach, wie das ist, wenn man ein 16-Bit 
Register auslesen will. Man muss das High-Byte ebenfalls auslesen. Das 
Lesen des Low-Bytes verriegelt den ADC gegen Updates. Das Lesen des 
High-Bytes hebt diese Verriegelung wieder auf.

Autor: Martin Meumann (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ja ob jetzt acht bit oder doch sechzen bit die brauchbaren ergebnisse 
sind mehr oder weniger im Highbyte Register

Autor: Fabi (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
rjmp warte
  in akku, ADCL
  in akku, ADCH
  com akku
  OUT PORTB, akku

Nun sieht es folgend aus: hoffe das passt so, jedoch

aber das hat auch nichts gebracht, noch immer steht das ergebnis der 
ersten messung drin

Autor: Sascha Weber (sascha-w)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo,

jetzt liest du nur die oberen beiden Bit's des Messwertes aus, wenn du 
da eine Veränderung sehen willst muss die Eingangsspannung in größerem 
Maß geändert werden. Entweder die liest ADCH in ein anderes Register 
wenn du die oberen Bits nicht brauchst, oder du setzt ADLAR=1 im ADMUX 
dann sind die oberen 8-Bits im ADCH und die unteren 2 im ADCL.

Sascha

Autor: Fabi (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
wieso ich lese doch jetzt beide einmal aus... aber da ich 8 LED´s auf 
dem STK500 habe kann und will ich nur 8 anzeigen. die anzeige ist ja 
nicht mein problem nur das die neuen Werte geschrieben werden.

Wie müsste es aussehen damit es funktioniert?

Autor: spess53 (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hi

Mit welcher Frequenz läuft dein ATMega. Der Prescaler von 8 scheint mir 
etwas klein.

MfG Spess

Autor: Sascha Weber (sascha-w)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo,

ja - du liest beide aus, aber überschreibst den 1. Wert gelesenen Wert 
(ADC-Bit's 7..0) in deinem Register 'akku' wieder mit dem 2. Wert 
(ADC-Bit's 9..8). Wenn du ADCH nicht brauchst, dann lies den Wert nicht 
in 'akku' sondern in ein anderes Register ein! Oder schalte die 
Anordnung der Daten mit ADLAR=1 um.
Wenn du nur Bit 9 und 8 ausliest, dann ändert sich dort bei Vref=2.56V 
nur alle 0.64V was!
Spannung           Bit 9 8
< 0.64                 0 0
> 0.64 , < 1.28        0 1
> 1.28 , < 1.92        1 0
> 1.92                 1 1

Achso: das ...
>  OUT ADCL, akku
>  OUT ADCH, akku

... kannst du dir sparen, ADCL/ADCH sind Readonly !


Sascha

Autor: Fabi (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Danke erstmal

Hab nun das ganz zum laufen gebracht.

die reihenfolge vom auslesen der ADC-Register ist wichtig.
Das mit in eine anderes register ist Richtig.
garnicht einlesen geht nicht und auch das umdrehen lässt keine
neuen Werte zu.

Zuerst muss das ADCL gelesen werden und erst danach das ADCH.
ins selbe Register speichern bewirkt wieder nichts, in zwei
seperate Register jedoch, lässt es zu und nun funktioniert auch alles.

Grüße

Als Anhang das funktionierde Programm

.INCLUDE "M16def.inc"

;*********************************************************************************
;Definitionen und Zuweisungen
;*********************************************************************************
.DEF akku = r16
.DEF akku2 = r17


;*********************************************************************************
;Interrupt Vektortabelle
;*********************************************************************************
.CSEG
.ORG 0x000
RJMP MainInit
.ORG 0x01C
RJMP ADinterput


;*********************************************************************************
;Main Initzialisierung
;*********************************************************************************
MainInit:

;Stackinitialisierung:
LDI akku, HIGH(RAMEND)
OUT SPH, akku
LDI akku, LOW(RAMEND)
OUT SPL, akku

;Portzuweisung EINGÄNGE PORT A (Für Analoges Signal)
LDI akku, 0x00
OUT DDRA, akku

;Portzuweisung AUSGÄNGE PORT B
LDI akku, 0xFF
OUT DDRB, akku
out PORTB, akku

;Portzuweisung EINGÄNGE PORT D
LDI akku, 0x00
OUT DDRD, akku

;**********************************
;*    AD-Converter einstellen.    *
;**********************************

clr akku

;Teiler einstellen Vorteiler 8 und Wandler Aktiveren
;ldi akku, (1<<ADEN) | (0<<ADPS2) | (1<<ADPS1) | (1<<ADPS0)
LDI akku, 0b10000011
OUT ADCSRA, akku

;Kanal ADC0 Wählen und Refernspannung Nutzen
;ldi akku, (1<<REFS0) | (1<<REFS1)
ldi akku, 0b11000000
OUT ADMUX, akku 

;*********************************************************************************
;MAINPROGRAMM
;*********************************************************************************

Mainloop:
  sbis PIND, PD0  ;Taste 0 gedrückt = Einzelmessung
  rcall EINZEL
  sbis PIND, PD1
  rcall CLEAR
rjmp mainloop


;*********************************************************************************
;Unterprogramm Einzelmessung
;*********************************************************************************
EINZEL:
  ;Messung starten
  sbi ADCSRA, ADSC
warte:
  sbic ADCSRA, ADSC
  rjmp warte
  in akku, ADCL
  in akku2, ADCH
  com akku
  OUT PORTB, akku
ret


;*********************************************************************************
;Unterprogramm LEDs - Clear
;*********************************************************************************
CLEAR:
  ser akku
  OUT PORTB, akku
ret

ADinterput:
  nop
reti

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.