Ja ok. Tut mir leid hab einen kleinen Fehler gemacht![]()
Nein, man rechnet es folgendermaßen um:
Zahl = 256*HighByte + LowByte
@kampi: Nimm mal die Zahl 512. Das obere Byte hat dann den Inhalt 2, das untere Byte ist auf Null. Mit deiner Formel gäbe das (0+(255*2))+1=511
kann also nicht sein.![]()
Du kannst das Problem umgehen, indem du im Register ADMUX das ADLAR-Bit setzt. Dann werden die Zahlen linksbündig gespeichert, d.h.
die 8 höchstwertigen Bits in ADCH und die zwei restlichen in ADCL.
Schau mal im Datenblatt auf Seite 215 (untere Hälfte).
Für 8 Bit Auflösung reicht es, das Register ADCH auszulesen. Dann ist die Umrechnung sowieso unnötig.
Ja ok. Tut mir leid hab einen kleinen Fehler gemacht![]()
Hallo!
@ Che Guevara
Wenn dir um Oversampling periodichen, sich wiederholenden Signalen geht, darf der ADC nicht freilaufen, sondern das nächste Sample muss immer um gleiche bestimmte Zeit gegen der voherigen veschoben werden.
Das geht nur mit einer permanenter Samplingfrequenz, die ein bißchen kleiner als vom gesampelten Signal ist. Beispielweise um 20 Samples zu bekommen, muss die Samplefrequenz 0,95 der von gesampelnden Signal sein. Dazu wird oft PLL benutzt um den Takt des ADC's an Signalfrequenz anzupassen.
MfG
Also ich habe gerade ein bischen mit meinem Mega32 experimentiert und dabei festgestellt das du mit deinem Programm nur eine Wandlung machst. Will heißten du flasht den Chip und sobald Spannung anliegt (direkt nach dem Flashen z.B.) beginnt er das Programm abzuarbeiten. Dabei startet er durch das beschreiben der Register eine Wandlung und speichert das Ergebniss ab. In deinem Programm machst du nichts anderes als eine Endlosschleife wo der Controller den Registerinhalt in die Variablen schreibt. Aber selbst wenn du den Spannungswert am ADC änderst wird er keinen neuen Wert in die Register schreiben, weil der Controller keine neue Wandlung beginnen wird da er nicht die nötigen Befehle dazu erhält.
@BMS: Du bist der erste, der versteht was ich meine![]()
Allerdings hab ich ADLAR gesetzt, aber es funktioniert nicht!
@PICture: An das hab ich schon gedacht, ich möchte einfach das ADCh-Register
in einer Timer_isr auslesen, da ich eine Spannungskurve aufnehmen möchte und dann an den PC schicken, der mir das ganze dann zeichnet.
@Kampi: Wenn ich das Prog im Sim. laufen lasse, werden die Werte aber schon bei jederÄnderung des ADCs geändert, bist du sicher, dass du nicht irgendwo einen Fehler drin hast?
Oder wie sollte ich deiner Meinung nach eine Wandlung anstoßen?
Wenn dem aber wirklich so sein sollte, dass ich das immer anstoßen muss, warum nennt sich das dann "Free-Run"? Ich dachte, weils die ganze Zeit selbstständig Messungen durchführt
oder täusche ich mich da?
Gruß
Chris
Naja zum einen ist ein Simulator =/= Realität. Der Simulator checkt es auch nicht das ich das ADC-Enable Bit auf 0 setze.....er macht trotzdem eine Wandlung![]()
Und ja ich bin mir ziemlich sicher. Ich habe dein Programm kopiert und es auf mein RN-Control aufgespielt. Als ich dann mit einem Widerstand eine Verbindung von GND zu ADC.0 gesteckt habe und das Programm aufgespielt habe hat mir TeraTerm eine 0 angezeigt. Sobald ich den Widerstand zwischen Vcc und ADC.0 gesteckt und es nochmal aufgespielt habe kam der maximal Wert vom ADC raus.
Das Problem an deiner Variante ist das es ein bestimmtes Register gibt. Sobald dieses Register auf 1 ist wird eine Wandlung gestartet. Dieses Bit wird nach einer Wandlung hardwarebedingt auf 0 gesetzt d.h. um eine neue Wandlung zu starten muss das Bit wieder auf 1 gesetzt werden. Und dies scheint der Simulator im Bascom auch nicht so zu peilen.
Du hast ja folgende Bitfolge:
Adcsra = &B11000110
Das 7. Bit ist dafür da den ADC zu aktivieren. Sobald das 0 ist ist der ADC aus. Das 6. Bit ist dafür da eine Wandlung zu starten. Sobald es 1 ist wird eine Wandlung gestartet und nach der Wandlung durch die Hardware auf 0 gesetzt.
Sowas kannste am besten live mal ausprobieren, weil ich hab die Erfahrung gemacht das man in solchen Sachen dem Simulator nicht trauen kann. Und wenn du mal genauer drüber nachdenkst ist das auch logisch das er nur eine Wandlung macht, weil das Bit für die Wandlung halt nach der Wandlung 0 wird und nirgends neu gesetzt wird.![]()
Im Free-Run Modus macht der ADC die ganze Zeit Wandlungen. Nur der Unterschied zu dem Single-Shot Modus ist das er bei dem Single-Shot Modus nach jeder Wandlung die, durch die Wandlung erzeugten Bytes umwandelt und evtl. ausgibt. Dieser Vorgang verbraucht vieeeeeeeeeeeeeeel Zeit.
Im Free-Run Modus ist das anders. Da macht er auch die ganze zeit Wandlungen nur er verarbeitet das Ergebniss nicht weiter. Er verarbeitet es nur weiter wenn du es möchtest. Wenn du mal unten im Simulator schaust siehst du wieviele Taktzyklen so eine einfache "Print" Ausgabe braucht (sind glaub ich ein paar 3000 Zyklen wenn ich mich nicht vertan habe heute Mittag). Und wenn du nun ein Hochfrequentes Signal sampeln willst z.B. bei der Digitalisierung von Musik ist es natürlich richtig dumm wenn du nach jeder Wandlung 3000 Zyklen extra brauchst um das Ergebniss zu haben. In so einem Fall lässt du den ADC im Free-Run Modus laufen und nach sag ich mal 1 Minute machst du eine Pause und verarbeitest den ganzen Stabel an Bytes in einem Rutsch weiter.
Danach startest du ein neues Sampling. Der Vorteil ist halt das der ADC quasi seine eigene "Geschwindigkeit" selber vorgibt und nicht durch sowas lästiges wie einen "Print" Befehl behindert wird.
Ach und zu dem Bit ADLAR. Das hier steht in der Doku:
"Das Bit ADLAR legt fest, ob das Ergebnis der AD-Umsetzung linksbündig (ADLAR=1,
xxxxxxxxxx000000) oder rechtsbündig (ADLAR=0, 000000xxxxxxxxxx) im 16-Bit Ergebnis
abgelegt wird".
Und das es nicht funktioniert hat liegt sicher auch am Simulator![]()
So ich hoffe das ist soweit alles schlüssig und verständlich und vorallem richtig! Hab die ganzen Sachen mit Hilfe der Datenblätter und einer netten Doku aus dem Internet über den ADC des Mega32 erarbeitet.
So hier mal die Doku:
http://www.ckuehnel.ch/Download/megaAVR%20ADC.pdf
Und hier mal das "überarbeitete" Programm
Code:'Controller $regfile = "m32def.dat" $crystal = 16000000 $baud = 9600 'Stacks $framesize = 80 $hwstack = 80 $swstack = 80 'Variablen Dim Wertl As Byte Dim Werth As Byte Config Pina.0 = Input Porta.0 = 0 Enable Interrupts Do Admux = &B01100000 Adcsra = &B11000110 'Übergabe der Registerinhalte in Variablen wertl = adcl Werth = Adch 'Ausgabe der beiden Registerwerte Print Wertl print werth Wait 1 Loop End
Es muss noch das ADATE-Bit (Bit 5) in ADCSRA gesetzt werden und außerdem SFIOR=0
Im Datenblatt :
Seite 214
Seite 216Bit 5 – ADATE: ADC Auto Trigger Enable
When this bit is written to one, Auto Triggering of the ADC is enabled. The ADC will start
a conversion on a positive edge of the selected trigger signal. The trigger source is
selected by setting the ADC Trigger Select bits, ADTS in SFIOR.
und auf das bin ich auch noch gestoßen (Seite 203)If ADATE in ADCSRA is written to one, the value of these bits (Anmerkung: ADTS2:0 in SFIOR) selects which source will
trigger an ADC conversion. If ADATE is cleared, the ADTS2:0 settings will have no
effect.
ADTS2 ADTS1 ADTS0 Trigger Source
0 0 0 Free Running mode
...
Das ADSC-Bit muss also wirklich nur 1x gesetzt werdenIn Free Running mode, a new conversion will be started immediately after the conversion
completes, while ADSC remains high.
Dann müsste es wirklich funktionieren![]()
Gruß
Bernhard
Ja gut das macht im Free Run Modus sogar Sinn das er es selber neu setzt![]()
Hab mich da leider selber noch nicht so richtig reingelesen![]()
Hallo
Nee, das verstehe ich wirklich nicht:Verstehst du das nicht?
Bei linksbündigem 8Bit-Ergebniss liest man nur ADCH. Ich dachte zuerst, du hast den falschen Quellcode gepostet ;)...indem ich den ADC im Free-Run Modus laufen lasse und nur die höherwertigen 8 Bits auslese
Naja, "wollte mal versuchen, mit meinem ADC ein eher höher frequentes analoges Signal auszulesen..." hab' ich ja eigentlich schon beantwortet. Ein schnelleres linksbündiges 8bit-ADC-Setup für ' nen Mega32 habe ich bisher noch nicht gesehen. Warum ihr dieses oben schon gezeigte ADC-Setup nicht verwenden wollt ist mir echt schleierhaft.
Gruß
mic
Bild hier
Atmel’s products are not intended, authorized, or warranted for use
as components in applications intended to support or sustain life!
Hi,
Nein, ich wollte mir nur mal zur Sicherheit noch ADCL mit ausgeben lassenIch dachte zuerst, du hast den falschen Quellcode gepostet![]()
Nein, da dein geposteter Link nichts anderes macht, als das, was ich schon selbst hinbekommen habhab' ich ja eigentlich schon beantwortet.Mittlerweile ist mir ein Weg eingefallen, das ganze zu realisieren, allerdings ist das sehr umständlich!
oder aber mittels Overlay:Code:$regfile = "m32def.dat" $crystal = 16000000 config adc = free , prescaler = auto start adc config pina.0 = 0 porta.0 = 0 dim x as word enable interrupts do x = makeint(adcl, adch) x = x / 4 print x loop end
Code:$regfile = "m32def.dat" $crystal = 16000000 config adc = free , prescaler = auto start adc config pina.0 = 0 porta.0 = 0 dim x as word at $60 dim xh as word at $60 overlay enable interrupts do x = makeint(adcl, adch) print xh loop end
Was ich benötige ist also ein vollautomatisierter Prozess:
1. ADCL und ADCH in eine 16Bit Variable (Word) konvertierren
2. Diese dann durch 4 teilen
Wäre natürlich toll, wenn man den ADC so initialisieren könnte, dass das alles selbstständig vom µC gemacht wird und man diese benötigten 8-Bit nur noch aus einem Register auslesen müsste ...
Wenn euch noch was einfällt bitte posten
Gruß
Chris
EDIT: Das mit dem Overlay funktioniert leider doch nicht
Lesezeichen