Hallo ich bin neu auf dem Gebiet Mikrocontroller
Ich bin gerade an einem 4x4x4 RGB LED Cube am basteln, jetzt habe ich
eine Platine angefertigt mit einem ATMEGA 32 16PU. Jetzt wollte ich Ihn
programmieren aber das Problem ist, dass der Mikrocontroller an den PINS
PC2(TCK)und PC3(TMS) trotz PORTC=0x00; ein High Signal liefert. Weis
zufällig jemand an was dies liegen könnte ???
JTAG ist eine Schnittstelle für Debugging Zwecke.
Beim Programmieren eines AVR Mikrocontrollers können bestimmte Flags
gesetzt werden (Fuses) welche verschidene Einflüsse auf den
Mikrocontroller haben.
Wenn diese Schnittstelle aktiv ist, dann werden die Ports davon belegt
und das Setzen des Ports im Programm wird ignoriert.
Siehe auch hier: https://www.mikrocontroller.net/articles/AVR_Fuses
MichaelS schrieb:> Wie meinst du das mit Fuses gesetzt??
"FUSE" (das englische Wort für "Sicherung") bezeichnet
Konfigurationsbits der AVR Mikrocontroller. Mit diesen Bits kann man
z.B. festlegen, mit welcher Taktquelle der AVR nach dem Reset losläuft,
und ob bestimmte Programmierschnittstellen aktiv sein sollen oder nicht.
Beim ATmega32 ist die JTAG-Schnittstelle standardmäßig aktiviert (ja,
per Fuse) und belegt dann die Pins PC2 und PC3. Du mußt sie
deaktivieren, dann kannst du die Pins auch aus deinem Programm heraus
verwenden.
Details findest du im Artikel AVR Fuses
es gibt keinen Code, das muss per ISP gemacht werden, womit
programmierst du den µC denn (welche Software und welchen
Programmieradapter?).
Dann können wir dir auch sagen wo du die Fuses ausliest und wieder
setzen kannst.
Moin,
K. S. schrieb:> es gibt keinen Code,
Das glaube ich nicht, Tim.
Probiers mal damit, irgendwann recht "frueh" im Programm (obacht, nicht
dass in r28 schon irgendwas wichtiges steht...):
1
in r28, 0x34
2
ori r28,0x80
3
out 0x34,r28
4
out 0x34,r28; enable port C lines; disable JTAG
Also das MSB im MCUCSR Register setzen und zwar 2x direkt
hintereinander, sollte JTAG abschalten.
Steht auch im Datenblatt bei der Beschreibung des MCUCSR Registers.
Gruss
WK
>> out 0x34,r28; enable port C lines; disable JTAG
>> oder eben>
1
>uint8_ttmp=MCUCSR|(1<<JTD);
2
>MCUCSR=tmp;
3
>MCUCSR=tmp;
4
>
> Die tmp Variable sorgt dafür, daß die Regel "2x in 4 Takten" eingehalten> wird.
Nein, tut sie nicht, jedenfalls NICHT garantiert. Denn: keine einzige
Stelle im C-Standard garantiert dies, es wird überhaupt niemals
irgendein konkretes Timing garantiert.
Übrigens: auch der Asm-Code vom guten Weka garantiert dies nicht unter
allen Umständen, nämlich dann nicht, wenn gerade im falschen Moment ein
Interrupt ausgelöst wird. Wenn man allerdings das Nicht-Vorkommen eines
Interrupts im Initialisierungsteil eines Programms als gegebene
Randbedingung ansieht (weil sinnvoll), dann GARANTIERT der
Assemblercode tatsächlich die Einhaltung des timing constraint.
Warum sollte man also den Code so verfassen, dass das Timing nicht
garantiert ist, wenn man ihn auch so schreiben kann, dass das der Fall
ist?
Nur merkbefreite C-only-Apologeten kommen auf so einen Unsinn.
c-hater schrieb:> Nur merkbefreite C-only-Apologeten kommen auf so einen Unsinn.
Die anderen kennen ihren Compiler und verlassen sich zu Recht auf
gewisse Eigenschaften. Der avr-gcc implementiert nicht nur den C
Standard, sondern auch einige Dinge, die ganz spezifisch für AVR sind.
Dies hier ist so ein Punkt.
K. S. schrieb:> es gibt keinen Code, das muss per ISP gemacht werden, womit> programmierst du den µC denn (welche Software und welchen> Programmieradapter?).> Dann können wir dir auch sagen wo du die Fuses ausliest und wieder> setzen kannst.
Natürlich geht das auch bequem per Code solange über ISP programmiert
wird.
Stefanus F. schrieb:> Die anderen kennen ihren Compiler und verlassen sich zu Recht auf> gewisse Eigenschaften. Der avr-gcc implementiert nicht nur den C> Standard, sondern auch einige Dinge, die ganz spezifisch für AVR sind.> Dies hier ist so ein Punkt.
Aha, und wo genau kann man in der avr-gcc-Doku nachlesen, dass genau
diese Eigenschaft garantiert wird?
Im Übrigen: selbst wenn sich (wider Erwarten) so eine Stelle finden
sollte, macht es immer noch keinen Sinn, das in C zu schreiben. Könnte
ja einer auf die Idee kommen, einen anderen Compiler verwenden zu
wollen. Soll's geben...
Ja mehr noch: das soll ja sogar gerade der ultimative Vorteil von C
sein, dass genau das möglich ist, die allzeit hochgelobte
"Portabilität"...
Natürlich ist auch der Assemblercode nicht portabel. Aber da knallt's
dann wenigstens schon beim Compilieren/Assemblieren, wenn's nicht
passt...
S. Landolt schrieb:> es scheint doch immer irgendwie Spaß zu machen, darauf> zu reagieren, nicht wahr?
Ja, solange es nicht in Beleidigungen ausartet. Momentan geht es noch.
Carl D. schrieb:> oder eben uint8_t tmp = MCUCSR | (1<<JTD);> MCUCSR = tmp;> MCUCSR = tmp;> Die tmp Variable sorgt dafür, daß die Regel "2x in 4 Takten" eingehalten> wird.
Und der würde nicht einen der beiden Befehle wegoptimieren? Logisch ist
es ja erstmal sinnlos (es sei denn er erkennt, dass es z.B. im Fall des
MCUCSR Sinn macht).
Ich setze dann lieber
#pragma opt-
.
.
#pragma opt+
ein
c-hater schrieb:> Nein, tut sie nicht, jedenfalls NICHT garantiert. Denn: keine einzige> Stelle im C-Standard garantiert dies, es wird überhaupt niemals> irgendein konkretes Timing garantiert.
Allerdings müsste ein Compiler schon sehr ungünstig implementiert sein,
damit das nicht klappt. Ich würde hier aber tatsächlich auch ein in
inline-Assembler implementiertes Makro schreiben.
Für den Fall von Timings, wo man wirklich einzelne Taktzyklen zählen
muss, halte ich C auch nicht für geeignet.
H.Joachim S. schrieb:> Carl D. schrieb:>> oder eben uint8_t tmp = MCUCSR | (1<<JTD);>> MCUCSR = tmp;>> MCUCSR = tmp;>> Die tmp Variable sorgt dafür, daß die Regel "2x in 4 Takten" eingehalten>> wird.>> Und der würde nicht einen der beiden Befehle wegoptimieren?
Nein, darf er nicht. Alle Zugriffe auf MCUCSR müssen durchgeführt
werden, da MCUCSR volatile ist. Das ist garantiert.
> Logisch ist es ja erstmal sinnlos (es sei denn er erkennt, dass es z.B.> im Fall des MCUCSR Sinn macht).
Wie gesagt: Wenn etwas volatile ist, dürfen Zugriffe darauf niemals
wegoptimiert werden.
> Ich setze dann lieber> #pragma opt-> .> .> #pragma opt+> ein
Das könnte auch nach hinten losgehen. Wenn dadurch noch zusätzliche
eigentlich überflüssige, aber nicht wegoptimierte Instruktionen drin
bleiben, die dir dann das Timing zerhauen.
c-hater schrieb:> Aha, und wo genau kann man in der avr-gcc-Doku nachlesen, dass genau> diese Eigenschaft garantiert wird?
Kann ich Dir nicht sagen, aber ich weiss wo das Datenblatt des ATmega328
einen ähnlichen Fall beschreibt. Siehe Anhang.
Wenn so etwas im Datenblatt steht, dann kann man sich darauf verlassen.
Eigentlich wollt ich ja nur die Assemblerzeilen für den offenbar in C
schreibenden TO aufbereiten. Aber auf die(/den) ganz speziellen
Spezialisten kann man sich verlassen.
Stefanus F. schrieb:> c-hater schrieb:>> Aha, und wo genau kann man in der avr-gcc-Doku nachlesen, dass genau>> diese Eigenschaft garantiert wird?>> Kann ich Dir nicht sagen, aber ich weiss wo das Datenblatt des ATmega328> einen ähnlichen Fall beschreibt. Siehe Anhang.>> Wenn so etwas im Datenblatt steht, dann kann man sich darauf verlassen.
Das Datenblatt (Mega32, der Mega328 hat ja kein JTAG) beschreibt nur,
welches Timing eingehalten werden muß.
Meine "Garantie" fußt eher auf dem volatilen Register (wie schon weiter
oben von jemand bemerkt, sowie der Beobachtung über mehrere
Compilergenerationen hinweg, daß das AVR-Compilerbackend des GCC kein
Problem damit hat, eine Zuweisung auf ein Register mit Io-Adresse unter
0x40 in das passender eine Assemblerstatement umzuwandeln. Deshalb auch
eine doppelte Zuweisung und kein doppeltest verOdern.
c-hater schrieb:> Nur merkbefreite C-only-Apologeten kommen auf so einen Unsinn.
Haty, ich wünsche dir ein Frohes Neues Jahr. Halt die Ohren und das,
worauf es noch ankommt, steif und lass dich von den bösen
C-Programmierern nicht unterkriegen. Du schaffst es. Ich zähl auf dich.
PS: Enttäusch mich nicht. Ich hab einen 5er gesetzt, daß du auch 2019
keinen Herzinfarkt bekommst.