Hallo,
ich habe an meinem AVR Controller AT90CAN alle 8 Kanäle mit analogen
Messungen belegt. Gleichzeitig möchte ich aber auch debuggen - über JTAG
- blöderweise ist die JTAG Schnittstelle an den Pins der analogen
Eingänge geschaltet, sodass es scheinbar keine Möglichkeit gibt
gleichzeitig zu debuggen und zu messen.
Liege ich falsch, oder ist das wirklich so?
Gibt es eine Möglichkeit die JTAG Schnittstelle während der Messung
vorrübergehend zu deaktivieren und anschließend wieder zu aktivieren?
Hätte man die JTAG Schnittstelle nicht an digitale Pins legen können :(
Vielen Dank für den Hinweis, aber kann ich dann während des debuggens
trotzdem den analogen Pin einlesen?
Gemäß der Abbildung muss man während des programmierens 5V zwischen den
Widerständen anlegen (VCC during programming). OK, aber dann kann ich
definitiv keine analoge Spannung einlesen.
Benötige ich im Debug-Betrieb auch die VCC, dann könnte es u.U
funktionieren.
Welche Bedeutung hat die Bezeichnung JTAG PIN? (TCK+TMS+TDI+TDO ?)
Trotz dieser Application Note kann ich mir meine Frage von oben nicht
erklären?
Haben Sie - oder jemand anders - schon Erfahrung mit dieser Beschaltung
gesammelt?
Ich finde die viel spannendere Frage diese hier:
da benutzt ja nicht einfach so zum Spass die 8 ADC Pins. D.h. da hängt
irgendeine Schaltung drann, welche Spannungen generiert.
Jetzt die Frage: was passiert am JTAG Interface, wenn deine eigentliche
Aussenbeschaltung diese Spannungen auf den dann auf JTAG
umkonfigurierten Anschlüssen nach wie vor anlegt?
Kannst du die Spannungen (ohne Aussenbeschaltung) im Programm nicht
einfach simulieren, während du den Rest des Programms per JTAG debuggst?
Hallo,
ich bins noch einmal. Irgendwie schaffe ich es nicht über JTAG zu
debuggen und zeitgleich die analogen Eingänge auszulesen, was das
debuggen sehr schwer macht.
Im Moment programmiere ich über ISP und habe die JTAG Schnittstelle
abgeschaltet, aber meine AD-Werte stimmen nicht, ich weiß nicht warum.
Im Anhang ist der Code der Schaltung.
Mein Controller: AT90CAN
Aufbau des Programms: eine main.c, eine Datei mit ausgelagerten
Funktionen (function.c/.h) eine Datei für meine definitionen (define.h)
und eine mit globalen Variablen (glob_var.h)
Ich habe den Code auf die Funktionen beschränkt, die benutzt werden. Ich
denke ich habe da einen systematischen Fehler.
Ich lese alle 8 Kanäle mit Interrupt-routinen ein. Der Startschuss fällt
im Timer 3, der alle 2 sekunden die Messung auslöst indem er den ADC und
den ADC Interrrupt einschaltet.
Alle Ergebnisse werden in einem array zwischengespeichert und am ende
des durchlaufs in ein result-array kopiert, aus dem ich meine analogen
Werte auslese.
Mein Hauptaugenmerk liegt im Moment auf drei Werten in den Kanälen 5-7
an dem ich Werte von einem Beschleunigungssensor auslesn möchte. mit
einem Messgerät kann ich alle Werte und deren Änderungen direkt am µC
Eingang messen und nachvollziehen. Im Programm ändert sich leider nur
der Wert des Kanal 7, die Werte in Kanal 5 und 6 sind vorhanden, aber
ändern sich nicht.
meine Kanäle:
_UB_BAT_F 0 //PF0 / ADC0 // Spannung U-Batt an Batterie hinter
Sicherung
_UB_FZ 1 //PF1 / ADC1 // Spannung U-Batt Fahrzeugseite
_CODE1 2 //PF2 / ADC2 // Codierstecker Input 1 - Auto_off
_UB_BAT 3 //PF3 / ADC3 // Spannung U-Batt an Batterie
_BCM_CODE 4 //PF4 / TCK // Codiereingang für BCM-Mode
_ACC_Z 5 //PF5 / TMS // Eingang Beschleunigungssensor Z-Achse
_ACC_Y 6 //PF6 / TDO // Eingang Beschleunigungssensor Y-Achse
_ACC_X 7 //PF7 / TDI // Eingang Beschleunigungssensor X-Achse
==============================================================
Vom Ablauf her, in dem ich Schwierigkeiten vermute:
- Timer 3 (Timer3_comp B) löst ca. alle 15 ms aus, variable wird
heruntergezählt und nach 2 sekunden (definiert durch Messintervall:
Startwert 128) wird der AD-Wandler gestartet
- ADC (ADC_vect) löst nach jeder Wandlung aus und beschreibt ein Array
mit den Kanälen 1-8 (buffer), das ganze wiederhole ich vier mal
(definiert durch rate=4 und aufaddieren im Array), Am ende der letzten
Wandlung schalte ich den ADC aus und update das Result-Register
- update_result (Funktion ausserhalb der ISR, aufgerufen durch ISR): ich
lese das array (buffer), bilde den Mittelwert aus den vier messungen und
speicher dies im result array.
- in der funktion update result, lasse ich mir die werte (kanal 5-7) des
result register nun ausgeben
Ergebnis:
- Wert aus result-register Kanal X (Kanal 7): 560 veränderbar +-200
- Wert aus result-register Kanal Y (KAnal 6): 970 unveränderbar
- Wert aus result-register Kanal Z (Kanal 5): 825 unveränderbar
Vermutung: Es stimmt etwas mit den volatile variablen nicht oder der
definitionen bzw deklarationen (extern, intern, glob_var, global, lokal)
Hi
>Vermutung: Es stimmt etwas mit den volatile variablen nicht oder der>definitionen bzw deklarationen (extern, intern, glob_var, global, lokal)
Mich wundert bei deinem ständigen herumfummeln am ADC eigentlich nichts.
Warum wird der ständig komplett neu initialisiert?
>ADCSRA |=(1 << ADIF);
Passiert automatisch wenn die ISR ausgeführt wird.
MfG Spess
spess53 schrieb:> Warum wird der ständig komplett neu initialisiert?>>>ADCSRA |=(1 << ADIF);>> Passiert automatisch wenn die ISR ausgeführt wird.
Diese Zeile habe ich aus einer App-Note von Atmel und hat mich auch
gewundert. --> AVR126, ADC_Interrupt (doc8444) ADC of megaAVR
Hallo,
ich habe am WE verschiedene Szenarien ausprobiert und diverse Änderungen
vorgenommen.
Das Problem konnte ich einschränken und vermute, dass es an der
Umschaltung der Multiplexer liegt. Die Umschaltung dauert zu lange bzw.
die internen Kapazitäten der S&H Schaltung sind noch teilweise geladen.
Folgende Änderungen habe ich durchgeführt:
* Den Kanal für den Mux ändere ich in der ISR an erster Stelle
* Ich starte den ADC nicht mehr im Free Running Mode, weil ich nicht
genau wusste, wann die nächste Messung startet.
- direkt nach Abschluss der aktuellen Messung, also während der
Verarbeitung der ISR?
- nachdem das ADIF-Flag zurückgesetzt wurde, also nachdem die ISR
abgearbeitet wurde?
* Ablauf jetzt (in der ISR)
- ADMUX - Kanal wechseln
- Werte im buffer speichern
- AD -Messung starten: Setzen des ADSC-Bit
Ich habe in diversen Foren (natürlich auch hier) gelesen, dass bei einem
Kanalwechsel kein Dummy-Read-Out erforderlich sein soll. So wie es
aussieht, komme ich aber nicht darum herum.
Wie bereits oben erwähnt, möchte ich alle 8 Kanäle meines µC
nacheinander Abfragen, das ganze 4x wiederholen und anschließend den
jeweiligen Mittelwert bilden. Bei meinem letzten Versuch habe ich am
Ablauf der Routine nichts verändert, aber mich nur auf die Abfrage von
zwei Kanälen beschränkt. D.h. in mein Array, Größe 8, habe ich vier mal
hintereinander Kanal 1 gemessen und die Werte in das Array Platz 0...3
gespeichert.
Anschließend habe ich den Multiplexer auf Kanal 2 umgeschaltet, wieder
vier Messungen gemacht und die Werte in das Array Platz 4...7
gespeichert.
Feststellung: Ab dem jeweils zweiten Wert stimmten die Messergebnisse
mit meinen Erwartungen überein.
Muss ich jetzt nach dem Umschalten, den ersten Wert verwerfen? Oder habe
ich an meinem Ablauf ein Problem? Kann ich an den Zeiten bzw. der ADC
Frequenz etwas ändern, damit ich das Problem umgehe?
CPU läuft auf 4MHz
ADC läuft mit Teiler 32 auf 125 kHz
Für einen Hinweis bin ich dankbar
Den Code von oben beschriebenen Vorgehen habe ich noch einmal angehängt
Ich möchte gerne noch eine Rückmeldung geben, bezüglich der Lösung:
Das Problem war, wie oben vermutet, die Umschaltung der Kanäle nach
jeder Messung.
Im aktuellen Code nutze ich nicht mehr den Free-Runnig Mode, sondern
stoße nach jeder Messung, die im Interrupt ausgewertet wird, neu an.
Ich mache zunächst einen Dummy-Read und anschließend die richtige
Messung, deren Ergebnis ich verwerte. Und erst danach wechsel ich den
Kanal, um den nächsten Eingang zu messen.