mikrocontroller.net

Forum: Mikrocontroller und Digitale Elektronik ADC lässt sich mit cbi ADEN nicht ausschalten


Autor: Andy11 (Gast)
Datum:
Angehängte Dateien:

Bewertung
0 lesenswert
nicht lesenswert
ich weis nicht wieso aber, es lässt sich irgendwie nicht machen, dass 
ich per ADEN den ADC ausschalte

die Unterprogramme habe ich der Textdatei beschrieben
;**********************************Header**************************************
;* Projektname:  Roboter-Linienverfolgung                    *
;* Name des Erstellers: Shamoon Andy                      *
;* Zuletzt aktualisiert: 7.4.2010                        *
;* Beschreibung: Ein ROboter, der einer ca1,5-2cm Linie nachfaährt        *                                      
;******************************************************************************


;*****************************Initialisierungen********************************
.include "m16def.inc" ;Definitionsdatei des Mega8

;Stackpointer-init***********
rjmp Stack_init
Weiter:

;ADC-init***********
rcall ADC_init  ;Externe Refernz, Prescaler = 128, Enable ADC = true, Kanal 0

;*****************Deklarierete Funktionen und Subroutinen**********************

;*************************Variablendeklarationen*******************************

;*****************************Ein-Ausgänge*************************************
  ser r16
  out DDRB, r16  ;PORTB als ausgabeport

;******************************************************************************


;*****************************Hauptprogramm************************************
    Hauptprogramm:;Do
call    EnableADC
call    DisableADC
call     ADC_Kanal3
call      StartADC
          in r16, ADCH
          com r16
          out PORTB, r16
call      EndADC
rjmp   Hauptprogramm ;Loop



;***********************Unterprogramme/Funktionen******************************
;################################################################################
.include "Division8Bit+Rest.asm"   ;8 Bit division    //call division
.include "WaitCA1s.asm"        ;Warte ca 1s ab    //call wait
.include "Stack_init.asm"      ;Stackinitialisieung//call Stack_init
.include "ADC_init.asm"        ;ADCinitialisieung  //call ADC_init
.include "EnableADC.asm"      ;ADC erlauben    //call EnableADC
.include "DisableADC.asm"      ;ADC sperren    //call DisableADC
.include "StartADC.asm"        ;Starte Messung    //call StartADC
.include "EndADC.asm"        ;Stoppe Messung    //call EndADC
.include "ADC_Kanal0.asm"      ;Wechsel zu Kanal 0 //call ADC_Kanal0
.include "ADC_Kanal1.asm"      ;Wechsel zu Kanal 1 //call ADC_Kanal1
.include "ADC_Kanal2.asm"      ;Wechsel zu Kanal 2 //call ADC_Kanal2
.include "ADC_Kanal3.asm"      ;Wechsel zu Kanal 3 //call ADC_Kanal3
;################################################################################



Autor: Andy11 (Gast)
Datum:
Angehängte Dateien:

Bewertung
0 lesenswert
nicht lesenswert
sry hier sind die Erklärungen

Autor: Hc Zimmerer (mizch)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
> .include "m16def.inc" ;Definitionsdatei des Mega8

Da ist entweder der Kommentar oder der Filename falsch.  Die beiden 
genannten Prozessoren sind sich aber tatsächlich sehr ähnlich, so dass 
das noch nicht der gesuchte Fehler sein muss.

Was aber der Fehler ist, hast Du weder genau genug beschrieben noch hast 
Du den nötigen Code geliefert.  Wenn man nach dem sucht, finden sich nur 
ein paar .include-Direktiven.

Autor: AVRuser (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo,

in Inhalt.txt steht:

> DisableADC:
> cbi ADMUX, ADEN
> ret

> EnableADC:
> sbi ADMUX, ADEN
> ret

Hast du nicht ins Datenblatt geschaut? Das Bit ADEN ist nicht im ADMUX, 
sondern im ADCSRA-Register zu finden ...

Autor: Andy11 (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
>Hast du nicht ins Datenblatt geschaut? Das Bit ADEN ist nicht im ADMUX,
>sondern im ADCSRA-Register zu finden ..

hah danke, natürlich habe ich im Datenblatt nachgeschaut, jedoch merke 
ich mir die Register nie und habe hier wahrscheinlich irrtümlich das 
falsche genommen

lg andy

Autor: Hc Zimmerer (mizch)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ah, den Code hast Du nachgeliefert, das hat sich mit meiner Antwort 
überschnitten.

Und der Fehler äüßert sich nun genau worin?

Übrigens:  StartADC wartet nicht, bis der ADC fertig ist, sondern kehrt 
in diesem Fall sofort zurück.  Das kann vielleicht noch gewünscht sein. 
Aber für den Fall, dass der ADC 'fertig' meldet, läuft es in die Wüste 
(in den hier nicht beschriebenen Code danach).

Autor: spess53 (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hi

Hat es einen bestimmten Grund, das du dein Programm auf zig, fast leere, 
Dateien verteilst?
Ebenfalls ist es recht sinnfrei, Programmteile, die nur einmal benötigt 
werden, (z.B. Stackinitialisierung) in Unterprogramme zu packen.
Sinnvoller ist es, z.B. die Umschaltung der Kanäle in einem 
Unterprogramm zu machen. Die Kanalnummer wird einfach in einem Register 
übergeben.
Im Datenblatt findest du übrigens ein Codebeispiel aus dem du ersehen 
kannst, wie man eine ADC-Wandlung startet und auf das Ergebnis wartet.

MfG Spess

Autor: Hannes Lux (hannes)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
> Hat es einen bestimmten Grund, das du dein Programm auf zig, fast leere,
> Dateien verteilst?

Ich mach's auch manchmal, weil Blättern zum anderen Editorfenster 
schneller geht als Scrollen und Zurückscrollen im längeren Quältext. Und 
ich muss (dank Alzheimer Light) oft nachschaun, wie ich denn nun meine 
Labels auf Konstanten, Register, RAM-Bereiche und Routinen genannt habe. 
Daher rechnet sich das Aufsplitten des Quältextes gelegentlich. Meist 
kopiere ich die Teile aber später wieder zusammen.

Bei den restlichen Punkten stimme ich Dir zu.

Ich kann mir aber gut vorstellen, dass man versucht, modular zu 
programmieren und wie bei einer Hochsprache alles in "Funktionen" zu 
packen. Das täuscht Übersichtlichkeit vor, verbraucht aber aufgrund 
unnötiger Sprünge und Rücksprünge unnötig Ressourcen. Dieselbe 
Übersichtlichkeit erreicht man auch mit ein paar Kommentaren. ;-)

...

Autor: Peter Dannegger (peda)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Anstatt Dich tot zupushen, definier Dir lieber ein paar 
Scratchpadregister, die jede Funktion zerstören darf.

Und nenn die Programme wie es sich gehört *.asm.
*.txt ist für Prosa (Liebesbriefe usw.) reserviert.


Peter

Autor: Peter Dannegger (peda)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hannes Lux schrieb:

> Ich kann mir aber gut vorstellen, dass man versucht, modular zu
> programmieren und wie bei einer Hochsprache alles in "Funktionen" zu
> packen. Das täuscht Übersichtlichkeit vor, verbraucht aber aufgrund
> unnötiger Sprünge und Rücksprünge unnötig Ressourcen.

Das ist einer der Vorteile einer Hochsprache, sie kann beim Optimieren 
alle nur einmal aufgerufene Funktionen inlinen.


Peter

Autor: spess53 (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hi

>Anstatt Dich tot zupushen, definier Dir lieber ein paar
>Scratchpadregister, die jede Funktion zerstören darf.

Dann lieber push/pop.

MfG Spess

Autor: Peter Dannegger (peda)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
spess53 schrieb:
> Hi
>
>>Anstatt Dich tot zupushen, definier Dir lieber ein paar
>>Scratchpadregister, die jede Funktion zerstören darf.
>
> Dann lieber push/pop.

Wenn man unbedingt deutlich größeren und langsameren Code als jeder 
C-Compiler produzieren will.


Peter

Autor: spess53 (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hi

>Wenn man unbedingt deutlich größeren und langsameren Code als jeder
>C-Compiler produzieren will.

Das gleicht der Compiler mit seinen Registerkonventionen wieder aus.

MfG Spess

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

Bewertung
0 lesenswert
nicht lesenswert
Na ja
Bei sowas
ADC_Kanal1:
  push r16
    ldi r16, 0x21
    out ADMUX, r16
  pop r16
ret

hat der Programmierer schon ein wenig  übertrieben. Das ist zwar (aus 
Registersicht) alles abgesichert, jedoch stehen die Chancen, dass dieser 
Code in einer tief verschatelten Aufrufhierarchie aufgerufen wird, nicht 
besonders gut. Benutzt man, wie Peter meint, ein paar Scratchpad 
Register, die jeder nach Gutdünken verändern darf (in dem Fall r16), 
dann ist man ds 'Problem' erst mal los.

Der Programmierer wollte eben Universalroutinen haben, die er überall 
einsetzen kann ohne sich grossartig Gedanken zu machen. Dagegen ist 
erstmal nicht viel zu sagen, ausser: Machs dann wenigstens richtig! Wenn 
die Funktion nur einen bestimmten Kanal einstellen soll, dann soll sie 
auch nur das tun! D.h. die restlichen Bits in ADMUX sind für die 
Funktion tabu und dürfen nicht verändert werden.

So wie sie jetzt ist, ist diese Funktion nicht Fisch und nicht Fleisch.

Autor: Andy11 (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
>Übrigens:  StartADC wartet nicht, bis der ADC fertig ist, sondern kehrt
>in diesem Fall sofort zurück.
wie lässt es sich denn anders schreiben?


>So wie sie jetzt ist, ist diese Funktion nicht Fisch und nicht Fleisch.
ADC_Kanal0:
  push r16
    in r16, ADMUX  
    cbr r16, 15    ;rechten 4 bits löschen
    sbr r16, 0    ;Kanal 0
    out ADMUX, r16  ;ausgabe 
  pop r16
ret

ist es so besser?

Autor: spess53 (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hi

Der ATMega16 hat 5 Mux-Bits

->cbr r16, $1F

>    sbr r16, 0    ;Kanal 0   unnötig.

Warum machst du zum Mux-Setzen nicht ein Unterprogramm.

MfG Spess

Autor: Andy11 (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
>->cbr r16, $1F
was ist das Dollar?

Autor: spess53 (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hi

>was ist das Dollar?

Hexadezimal.

MfG Spess

Autor: Andy11 (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
>Hexadezimal.
hab dacht das schreibt man mit 0h

Autor: Ziegenpeter (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Soweit ich weiss gibt man bei sbr  cbr genauso wie bei sbi  cbi als 
zweiten Operanden die Bitnummer an.
D.h.:

cbr r16, 3

entspricht:

ori r16, 1<<3



Also wäre "sbr r16, 0" => "ori r16, 1". Damit würde man Kanal 1 setzen 
nicht 0.

Autor: spess53 (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hi

>Soweit ich weiss gibt man bei sbr  cbr genauso wie bei sbi  cbi als
>zweiten Operanden die Bitnummer an.

Soweit das Instruction Set richtig ist, kann der 2.Operant einen Wert 
von 0..$FF annehmen.
Entspricht einem ANDI mir dem Komplement des Operanten.

MfG Spess

Autor: Hannes Lux (hannes)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Karl heinz Buchegger schrieb im Beitrag #1665879

> ...

> Wenn
> die Funktion nur einen bestimmten Kanal einstellen soll, dann soll sie
> auch nur das tun! D.h. die restlichen Bits in ADMUX sind für die
> Funktion tabu und dürfen nicht verändert werden.

Das ist generell erstmal richtig und wird von mir nicht angezweifelt.

Bei ADMUX sehe ich das aber anders. Da gehören die Bits einfach 
zusammen. Zu jedem ADC-Kanal gehört auch die Referenzeinstellung und 
auch (sofern es auch in ADMUX liegt) die Formatierung (links/rechts) des 
Ergebnisses (ADLAR). Hier sehe ich Referenz und Resultatformat als 
Bestandteil (Zusatzparameter) des Kanals. Somit ziehe ich das direkte 
Zuweisen des ganzen Bytes vor. Ich bevorzuge dabei ein temporäres 
Register, das nicht gesichert werden muss und undeutsch 
"Scratchregister" genannt werden könnte.

Ich generiere dafür aber keine extra "Funktion". Ist nur ein Kanal 
abzufragen, so wird das im Ini-Bereich eingestellt, sind mehrere Kanäle 
abzufragen, so wird das Setzen von ADMUX Bestandteil der zyklisch 
aufgerufenen Ausleseroutine (ADC-Interrupt oder durch Timer 
synchronisiertes Auslesen).
Dieser zyklisch aufgerufene Job legt das geholte ADC-Ergebnis in ein 
Array (mit oder ohne Mittelwertbildung), zählt den Index hoch (oder 
runter) und begrenzt ihn, holt aus einem weiteren Array (mit demselben 
Index, in ASM durch Zugriff über LDD) den ADMUX-Wert für die nächste 
Wandlung und startet den ADC wieder. Somit erfolgt im Hintergrund reihum 
die Wandlung aller Kanäle mit den zugehörigen Parametern (Referenz, 
Format), ohne dass man sich weiter darum kümmern muss.
Die Mainloop holt sich die Werte dann aus dem Array, da liegt dann immer 
der letzte Wert bzw. der Mittelwert der letzten Messungen. Und das zu 
jeder Zeit für jeden Kanal.

...

Autor: Andy11 (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
>Soweit ich weiss gibt man bei sbr  cbr genauso wie bei sbi  cbi als
>zweiten Operanden die Bitnummer an.
>D.h.:

>cbr r16, 3

>entspricht:

>ori r16, 1<<3



>Also wäre "sbr r16, 0" => "ori r16, 1". Damit würde man Kanal 1 setzen
>nicht 0.

ich habs schon ausgetestet, was ich stehen habe passt


>Ich generiere dafür aber keine extra "Funktion". Ist nur ein Kanal
>abzufragen, so wird das im Ini-Bereich eingestellt, sind mehrere Kanäle
>abzufragen, so wird das Setzen von ADMUX Bestandteil der zyklisch
>aufgerufenen Ausleseroutine (ADC-Interrupt oder durch Timer
>synchronisiertes Auslesen).
>Dieser zyklisch aufgerufene Job legt das geholte ADC-Ergebnis in ein
>Array (mit oder ohne Mittelwertbildung), zählt den Index hoch (oder
>runter) und begrenzt ihn, holt aus einem weiteren Array (mit demselben
>Index, in ASM durch Zugriff über LDD) den ADMUX-Wert für die nächste
>Wandlung und startet den ADC wieder. Somit erfolgt im Hintergrund reihum
>die Wandlung aller Kanäle mit den zugehörigen Parametern (Referenz,
>Format), ohne dass man sich weiter darum kümmern muss.
>Die Mainloop holt sich die Werte dann aus dem Array, da liegt dann immer
>der letzte Wert bzw. der Mittelwert der letzten Messungen. Und das zu
>jeder Zeit für jeden Kanal.

sry is mir im Moment viel zu hoch

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.