Forum: Mikrocontroller und Digitale Elektronik AD-Wandlung und Nutzung JTAG möglich?


von Mike (Gast)


Lesenswert?

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 :(

von Thomas E. (thomase)


Lesenswert?


von Mike (Gast)


Lesenswert?

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?

von Karl H. (kbuchegg)


Lesenswert?

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?

von Mike (Gast)


Angehängte Dateien:

Lesenswert?

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)

von spess53 (Gast)


Lesenswert?

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

von Walter T. (nicolas)


Lesenswert?

Thomas Eckmann schrieb:
> 
http://www.atmel.com/images/atmel-2521-avr-hardware-design-considerations_application-note_avr042.pdf
>
> mfg

OT: Werden jetzt alle AVR-Appnotes so häßlich und ausdruckfeindlich? 
Dann sollte man schnell noch alle herunterladen.

von Mike (Gast)


Lesenswert?

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

von Mike (Gast)


Angehängte Dateien:

Lesenswert?

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

von mike (Gast)


Lesenswert?

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.

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.