Hallo,
versuche gerade einen Hardware SPI für ein späteres Projekt zum laufen
zu bringen.
Habe mir schon das originale Datenblatt durchgelesen und sämtliche
Beispielprojekte ausprobiert, aber der SPI will nicht gehen.
MOSI ist dauernd auf High
CK ist auch nur auf HIGH
UND SS pulsiert wie gewollt.
Ist evtl. einfach mein uC kaputt?
uC = ATMega328P
Code:
Maci M. schrieb:> DDRB = (1<<5) | (1<<3) | (1<<2);
Das ist unschön. Besser wäre es:
1
#define SPI_SS PB2
2
#define SPI_MOSI PB3
3
#define SPI_SCK PB5
4
5
DDRB|=(1<<SPI_SCK)|(1<<SPI_MOSI)|(1<<SPI_SS);
> MOSI ist dauernd auf High> CK ist auch nur auf HIGH> UND SS pulsiert wie gewollt.
Kann sein, daß SPI_MasterTransmit(0xAB); vom Compiler wegoptimiert
wurde.
Du kannst in Simulator Assembler-Code ankucken, dort siehst du das
genau. Ansonsten arbeitet so ein Programm oft anders als vollwertige.
Compiler ist klug. Er sieht, daß hier nichts gemacht wird. Deshalb
optimiert er vieles weg.
Maci M. schrieb:> SS pulsiert wie gewollt.
Mit welchem zeitlichen Ablauf?
> Ist evtl. einfach mein uC kaputt?
Bei mir waren das in 99,9% irgendwelche Programmfehler. Ich probiere in
so einem Fall einfach mal einen anderen µC aus...
Maxim B. schrieb:> Compiler ist klug. Er sieht, daß hier nichts gemacht wird.
Natürlich wird da was gemacht. Das Programm soll aussen am Controller
einen Pegelwechsel erzeugen. Den darf er niemals wegoptimieren.
Bestenfalls eine Codefolge, die keinerlei Aussenwirkungen hat, darf
weggelassen werden. Eine Änderung des zeitlichen Ablaufs gilt hier nicht
als Auswirkung, weil ein C-Programm keine Zeit "braucht" oder innehat.
Lothar M. schrieb:> Das Programm soll aussen am Controller> einen Pegelwechsel erzeugen. Den darf er niemals wegoptimieren.> Bestenfalls eine Codefolge, die keinerlei Aussenwirkungen hat, darf> weggelassen werden.
Bei TO wird ja SS-Pegel geändert, nur ISP sendet nichts. So haben Sie
recht: was außen am Controller einen Pegelwechsel erzeugt, das bleibt.
Anders mit SPI. Deshalb war meine erste Gedanke: wegoptimiert.
Wenn das Programm etwas größer würde und SPI mit verschiedenen Daten
hantierte oder mindestens mit Variablen, die sich im Laufe ändern, dann
wäre Wegoptimieren weniger wahrscheinlich.
Maci M. schrieb:> /* Set MOSI and SCK output, all others input */> DDRB = (1<<5) | (1<<3) | (1<<2);
Du setzt außer MOSI und SCK noch einen Pin. Wahrscheinlich SS. Nur mal
so als Idee, lass SS oder benutze einen anderen Pin. Vielleicht gibt es
da Probleme. Sollte es eigentlich nicht, aber wer weiß.
Dussel schrieb:> Nur mal> so als Idee, lass SS oder benutze einen anderen Pin.
Gerade für AVR wäre das schlecht: wenn SS als Eingang bleibt und
zufällig (z.B. durch Störungen) "0" bekommt, dann schaltet SPI
automatisch auf Slave. Deshalb Fausregel für AVR-SPI: SS sollte immer
Ausgang bleiben, es sei denn, Slave wird gewünscht.
Lothar M. schrieb:> Den darf er niemals wegoptimieren.> Bestenfalls eine Codefolge, die keinerlei Aussenwirkungen hat, darf> weggelassen werden.
Es gibt noch ein Moment: TO hat das ganze Programm hier gezeigt. Kein
Fragment. Das ist das Ganze. Hier wird Compiler mehr optimieren, als das
ein größeres Programm wäre.
Maxim B. schrieb:> wenn SS als Eingang bleibt und> zufällig (z.B. durch Störungen) "0" bekommt, dann schaltet SPI> automatisch auf Slave.
Meine Befürchtung war, dass durch irgendein Zusammenspiel SPI in den
Slavemodus schaltet.
Dussel schrieb:> Maxim B. schrieb:>> wenn SS als Eingang bleibt und>> zufällig (z.B. durch Störungen) "0" bekommt, dann schaltet SPI>> automatisch auf Slave.> Meine Befürchtung war, dass durch irgendein Zusammenspiel SPI in den> Slavemodus schaltet.
TO sollte Assembler-Code ankucken. Erst dann gibt es mehr Klarheit.
Meine Erfahrung: so kurze Prüfabschnitte bringen nichts. Man sollte
etwas mehr einprogrammieren, um keine realitätsfremden Ergebnisse zu
bekommen. Oder auch Optimieren vollständig abschalten.
Dussel schrieb:> Maci M. schrieb:>> /* Set MOSI and SCK output, all others input */>> DDRB = (1<<5) | (1<<3) | (1<<2);> Du setzt außer MOSI und SCK noch einen Pin. Wahrscheinlich SS. Nur mal> so als Idee, lass SS oder benutze einen anderen Pin. Vielleicht gibt es> da Probleme. Sollte es eigentlich nicht, aber wer weiß.
Habe es sogar schonmal komplett ohne ss versucht, geht auch nicht.
Gehe immer mit dem oszi an die Ports aber sehe nichts
Maci M. schrieb:> Ist evtl. einfach mein uC kaputt?
Auch wenn das hier von manchen nicht gerne gehört wird, nimm die Arduino
IDE, die Arduino SPI Library und eines der Beispiele.
Dann siehst du innerhalb von 3 Minuten, ob dein µC ok ist.
PB2 ist der Chipselect vom Atmega328. Wird der angeknusbert denkt der
Atmega328, dass er ein Slave ist und wartet, dass der Pseudo-Master mal
was sagt ;)
Ist jetzt nur so das, was mir beim Überfliegen auffiel und ist IMO ne
beliebte "Falle" bei Atmega328 und seinen Freunden ;)
Hier mal ein Ausschnitt aus dem Datenblatt des Atmega328PB dazu:
If SS is configured as an input, it must be held high to ensure master
SPI operation. If the SS pin is driven low by peripheral circuitry when
the SPI is configured as a master with the SS pin defined as an input,
the SPI system interprets this as another master selecting the SPI as a
slave and starting to send data to it. To avoid bus contention, the SPI
system takes the following actions:
Aus dem Kapitel 23.3.2 des aktuellen Datenblatts
Maxim B. schrieb:> Compiler ist klug. Er sieht, daß hier nichts gemacht wird. Deshalb> optimiert er vieles weg.
Klar.
Nur bedarf es jemanden mit bisschen Gehirnschmalz, um das zu merken.
Dass erst nach 7(sieben) Posts von dir das Problem erkannt wurde,
zeigt überdeutlich wer in diesem Thread derjenige mit Gehirn ist...
Marc V. schrieb:> Dass erst nach 7(sieben) Posts von dir das Problem erkannt wurde
Ich habe darüber in meinem Post 1. geschrieben:
"Kann sein, daß SPI_MasterTransmit(0xAB); vom Compiler wegoptimiert
wurde."
In unserer schweren Zeit gibt es immer mehr Schriftsteller und immer
weniger Leser. Schade...
Klar, ein Compiler nacht nur, was seine Schöpfer wollten. Die Fehler
macht immer der das Programm schreibt.
Daß Compiler zu einfache Programm-Proben wegoptimiert, das habe ich
früher oft erlebt.
Arduino Fanboy D. schrieb:> Also sind sie von Optimierungen ausgeschlossen.
Das sagt Theorie. Praxis sieht aber etwas anders aus...
Wären wir die Compiler schreiben, so wäre hier eine Diskussion nützlich.
Solange aber wir Compiler nur verwenden, müssen wir einfach das Werkzeug
lernen.
Falk B. schrieb:> Maci M. schrieb:>> Danke funktioniert war wirklich ein Optimierungsfehler.>> Sicher nicht.
Wenn ich ein bisschen nachdenke, glaube ich auch, daß du Recht
hast...
Ein Byte muß auf jeden Fall gesendet werden, egal ob dies später
irgendwo gebraucht wird oder nicht...
Vielleicht wird mit diesem Byte ein Gerät aktiviert, es ist nicht
der Compiler, der darüber entscheiden soll...
M. K. schrieb:> PB2 ist der Chipselect vom Atmega328. Wird der angeknusbert denkt der> Atmega328, dass er ein Slave ist und wartet, dass der Pseudo-Master mal> was sagt ;)
Aber doch nur, wenn der SS-Pin als Eingang konfiguriert ist.
Falk B. schrieb:> Maci M. schrieb:>> Danke funktioniert war wirklich ein Optimierungsfehler.> Sicher nicht.
Ich glaube, der Compiler hatte einfach statt des C-Codes den falschen
Kommentar in Code umgesetzt:
1
/* Set MOSI and SCK output, all others input */
2
DDRB=(1<<5)|(1<<3)|(1<<2);
Denn dann wäre der SS-Pin ein Eingang gewesen und die SPI-Einheit hätte
das gemacht, was sie halt macht, wenn der SS-Pin als Eingang deklariert
ist.
Maci M. schrieb:> Danke funktioniert war wirklich ein Optimierungsfehler.
Wie hast du festgestellt, dass das ein Optimierungsfehler war?
Was hast du denn geändert, dass es jetzt läuft?
Marc V. schrieb:> Vielleicht wird mit diesem Byte ein Gerät aktiviert, es ist nicht> die Sache des Compilers, darüber zu entscheiden...
Das Problem liegt nicht nur daran, daß vorgegebene Byte und keine
Variable geschickt würde. Das Problem liegt daran, daß das ganze
Programm nichts macht. Das erkennt Compiler.
Meine Erfahrung: wäre in main() und in der Schleife etwas mehr, auch
andere Funktionen, andere Aufgaben, so würde auch SPI-Sendung nicht
wegoptimiert.
Ich denke, Compiler ist wirklich klug. Er analysiert keine einzelnen
Funktionen. Er analysiert das ganze Programm.
Deshalb, wenn ich eine mir unbekannte IC mit einer Versuchsplatine
erproben möchte, mache ich auch viel anderes: beschreibe CLKPR zum
Beispiel, initialisiere TWI usw. Das alles nur um zu viel Wegoptimieren
zu vermeiden. Anders gesagt, es sollte ein Programm sein, das etwas
macht, was Compiler nicht gleich als "nichts" erkennt.
Lothar M. schrieb:> Was hast du denn geändert, dass es jetzt läuft?
Er hat nach meinem Tipp statt einer Konstante eine Variable geschickt,
die während der Laufzeit geändert wird.
Maxim B. schrieb:> Das Problem liegt daran, daß das ganze> Programm nichts macht. Das erkennt Compiler.
Warum macht es nichts? Es ist ja klar, dass es etwas machen soll,
nämlich eben Daten an die Außenwelt senden. Wo ist der Fehler, dass es
mit dem Code nichts macht?
Unabhängig davon, ob es am Oszilloskop lag.
Maci M. schrieb:> Ok, habe nochmal bisschen rumgetestet.>> Ist kein Optimierungsfehler sondern mein Oszilloskop ist kaputt.
Du hast aber ein komisches Oszilloskop: SS-Pin-Änderungen hat er
gezeigt, MOSI und SCK dagegen nicht. Ist Optimieren vielleicht auch in
dein Oszilloskop eingebaut? :)
Dussel schrieb:> Wo ist der Fehler, dass es> mit dem Code nichts macht?
Ich bleibe bei meiner Meinung: Compiler hat erkannt, daß das Programm
nichts macht, und hat alles, was er als überflüssig sieht, wegoptimiert.
Ich glaube daran einfach deshalb, weil mit mir das auch mehrmals
passierte. Ein Blick in Assembler reichte gewöhnlich.
Solch kurze Programme, wenn man wirklich nur und ausschließlich eine
Konstante kontinuierlich zu schicken braucht, so was schreibt man lieber
auf dem Assembler. C ist zu klug dafür, zu unübersichtlich.
Maxim B. schrieb:> Das Problem liegt nicht nur daran, daß vorgegebene Byte und keine> Variable geschickt würde. Das Problem liegt daran, daß das ganze> Programm nichts macht. Das erkennt Compiler.> Meine Erfahrung: wäre in main() und in der Schleife etwas mehr, auch> andere Funktionen, andere Aufgaben, so würde auch SPI-Sendung nicht> wegoptimiert.> Ich denke, Compiler ist wirklich klug. Er analysiert keine einzelnen> Funktionen. Er analysiert das ganze Programm.
Was für ein Quark.
Die Register sind volatile aus gutem Grund – derartige Zugriffe darf der
Compiler nicht wegoptimieren. So ist volatile definiert – alles andere
wäre ein Compilerbug.
Einem Compiler ist es auch egal, ob du einer Funktion eine Konstante
oder eine Variable übergibst – sollte eine Funktion vom Compiler leer
hinterlassen werden, kann maximal noch der Linker den Aufruf entfernen.
Maxim B. schrieb:> Marc V. schrieb:>> Vielleicht wird mit diesem Byte ein Gerät aktiviert, es ist nicht>> die Sache des Compilers, darüber zu entscheiden...>> Das Problem liegt nicht nur daran, daß vorgegebene Byte und keine> Variable geschickt würde. Das Problem liegt daran, daß das ganze> Programm nichts macht. Das erkennt Compiler.
Sagt wer?
Was, wenn mit diesem Programm wirklich irgendetwas ein- oder
ausgeschaltet werden soll?
Das kann (und soll) der Compiler nicht entscheiden.
> Ich denke, Compiler ist wirklich klug. Er analysiert keine einzelnen> Funktionen. Er analysiert das ganze Programm.
Und ich wiederum glaube das nicht.
Variable aus Loop oder unbenutzte Variablen wegoptimieren ist eine
Sache, aber das ganze Programm analysieren?
Ausserdem ist jede Ausgabe, egal ob SPI, I2C oder UART von optimieren
ausgenommen - wie schon Arduino Fanboy D. schrieb.
Maxim B. schrieb:> Compiler hat erkannt, daß das Programm> nichts macht, und hat alles, was er als überflüssig sieht, wegoptimiert.>> Ich glaube daran einfach deshalb, weil mit mir das auch mehrmals> passierte. Ein Blick in Assembler reichte gewöhnlich.
'Glaubt erkannt zu haben'. Die Annahme, dass das Programm (im Quelltext)
nichts macht, ist ja eindeutig falsch. Erst nachdem der Compiler eine
Fehler gemacht hat, tut es wirklich nichts mehr.
Unter der Annahme, dass es wirklich am Compiler lag.
Maxim B. schrieb:> Arduino Fanboy D. schrieb:>> Also sind sie von Optimierungen ausgeschlossen.>> Das sagt Theorie. Praxis sieht aber etwas anders aus...
Das mit der Optimierung ist alles blödes Gelaber.
Ohne Hand und Fuß.... auch ohne Hirn.
Zwischenzeitlich mit 1/2 Dutzend AVR Toolchains getestet.
Das tuts perfekt, ohne jede Ausnahme.
Sowohl als C als auch C++
Maxim B. schrieb:> Ich bleibe bei meiner Meinung: Compiler hat erkannt, daß das Programm> nichts macht, und hat alles, was er als überflüssig sieht, wegoptimiert.
Ist klar!
Bedeutung von volatile vielleicht noch mal nachlesen...
Bitte.
Ich habe nun das Programm von TO mit AVR Studio compiliert.
Der Grund war wirklich anders.
Das Programm beginnt
1
voidSPI_MasterTransmit(charcData)
2
{
3
/* Start transmission */
4
SPDR=cData;
5
8a:8ebdout0x2e,r24;46
6
/* Wait for transmission complete */
7
while(!(SPSR&(1<<SPIF)));
8
8c:0db4inr0,0x2d;45
9
8e:07fesbrsr0,7
10
90:fdcfrjmp.-6;0x8c<SPI_MasterTransmit+0x2>
11
}
12
92:0895ret
Und bleibt auf 090: auch hängen. Weil noch ein Befehl fehlt: IN reg,0x2e
!!! :)
D.h. TO hat die Funktion für Übertragung nicht korrekt geschrieben.
Richtig wäre z.B. so:
1
unsignedcharSPI_MasterTransmit(charcData)
2
{
3
/* Start transmission */
4
SPDR=cData;
5
/* Wait for transmission complete */
6
while(!(SPSR&(1<<SPIF)));
7
returnSPDR;
8
}
Ohne Lesen von SPDR nach der Übertragung funktioniert das alles nicht.
Und auch wichtig: in Init sollte man einmal dummi-Byte schicken, damit
SPDR einmal gelesen wird. Sonst wird die Mechanik hängen.
So einfach ist das...
Maxim B. schrieb:> Solch kurze Programme, wenn man wirklich nur und ausschließlich eine> Konstante kontinuierlich zu schicken braucht, so was schreibt man lieber> auf dem Assembler. C ist zu klug dafür, zu unübersichtlich.
Was für ein Gesülze!
Also, es fehlte in der Funktion SPI_MasterTransmit einiges:
1. kein void sondern unsigned char
2. return SPDR; am Ende.
Das noch in Programm zu geben, und dann wird schon alles laufen.
Jetzt erinnere ich: einmal habe ich gleiche Fehler gemacht. Ich dachte:
wozu muß ich noch die Zeit vergeuden, und SPDR lesen, wenn ich nur
senden möchte? Und ich habe zwei Funktionen gemacht: eine mit Lesen,
andere ohne Lesen. Das hat aber nicht funktioniert.
Maxim B. schrieb:> Ohne Lesen von SPDR nach der Übertragung funktioniert das alles nicht.
Auch das ist Unfug.
Du gibst nicht auf, oder?
Eine rege Fantasie hast du ja....
Nur hilft dir das bei solchen Fragen nicht.
Da sollte man besser Fakten bemühen.
Arduino Fanboy D. schrieb:> Auch das ist Unfug.
Vielleicht ist das in Arduino Unfug? Weil man dort immer "Lib" verwendet
und genau Code von SPI sieht man selber nie.
Wenn man aber alles selber macht, ohne Mama zu rufen, dann muß schon
return SPDR stehen. Ich bin sicher, in Arduino-Lib ist das auch so, nur
sieht man das nicht.
Du könntest mal Assembler-Listing von einem Arduino-Programm kucken;
steht dort in reg, 0x2e oder nicht
Arduino Fanboy D. schrieb:> Du gibst nicht auf, oder?
habe ich schon doch! Ich sage nun: das war kein Wegoptimieren. Das war
nur eine nicht korrekt geschriebene Funktion. Compiler hat keine Schuld,
er machte alles richtig. Schuldig ist Programmierer (was ich auch früher
behauptete).
Maxim B. schrieb:> Wenn man aber alles selber macht, ohne Mama zu rufen, dann muß schon> return SPDR stehen.
Muss es weder nach C-Standard noch nach Programmlogik.
Ich zitiere aus dem Datenblatt von "ATmega48A ATmega48PA ATmega88A
ATmega88PA ATmega168A ATmega168PA ATmega328 ATmega328P":
1
voidSPI_MasterTransmit(charcData){
2
/* Start transmission */
3
SPDR=cData;
4
/* Wait for transmission complete */while(!(SPSR&(1<<SPIF)))
5
;}
Aber Atmel hat wahrscheinlich einfach keine Ahnung.
Dussel schrieb:> Aber Atmel hat wahrscheinlich einfach keine Ahnung.
Ich kenne Menschen aus Atmel nicht. Ich kann deswegen nichts sagen.
Aber bei mir arbeitete Funktion ohne Lesen von SPDR nicht. Und, wie ich
noch erinnern kann, hat jemand hier auf dem Forum über den Fehler
gesagt. Ich habe korrigiert - und alles wurde gut.
Aber macht wie ihr wollt, mir ist das eigentlich egal.
Maxim B. schrieb:> Vielleicht ist das in Arduino Unfug? Weil man dort immer "Lib" verwendet
Nein.
> ... dann muß schon> return SPDR stehen.
Nein.
Bitte hoer einfach auf Schwachsinn zu posten. Bleib bei deinen Tasten
und gut.
leo
Dussel schrieb:> Aber Atmel hat wahrscheinlich einfach keine Ahnung.
Sehe ich auch so!
Nur der Maxim B. (max182) der hats voll auf dem Schirm.
Maxim B. schrieb:> Wenn man aber alles selber macht, ohne Mama zu rufen, dann muß schon> return SPDR stehen.
Selbst nach dem Hinweis darauf, dass du falsch liegst, machst du
unbeirrt weiter.
Du bist ein Denunziant
Ein Lügner
Und hast offensichtlich keine Ahnung, von dem, was du da blubberst.
Arduino Fanboy D. schrieb:> Selbst nach dem Hinweis darauf, dass du falsch liegst
Wo liege ich falsch?
Arduino Fanboy D. schrieb:> Du bist ein Denunziant> Ein Lügner
Ich habe dich aber noch nie beleidigt.
nach solchen deinen Worten existierst du für mich nicht mehr. Deine
Posten werde ich in der Zukunft nie mehr beantworten.
P.S. Wer die Wahrheit sehen will, der hat immer noch die Möglichkeit,
selbst AVR Studio starten, Text von TO eingeben und compilieren. Dann
return SPDR dazu schreiben, noch mal kompilieren und vergleichen.
Das bedeutet aber ein bißchen mehr Bewegung, als einfach "Lügner" zu
schreiben, wie? :)
Maxim B. meint vermutlich diesen Mechanismus, aus dem Datenblatt zu
'SPSR – SPI Status Register, • Bit 7 – SPIF: SPI Interrupt Flag':
"Alternatively, the SPIF bit is cleared by first reading the SPI Status
Register with SPIF set, then accessing the SPI Data Register (SPDR)."
Maxim B. schrieb:> Aber bei mir arbeitete Funktion ohne Lesen von SPDR nicht. Und, wie ich> noch erinnern kann, hat jemand hier auf dem Forum über den Fehler> gesagt. Ich habe korrigiert - und alles wurde gut.
Stimm ja auch. Nur klingen deine Beiträge so, als läge der Fehler im
Quelltext. Das stimmt aber nicht. Der Fehler liegt im Compiler. Und dass
man korrekten Quelltext ändert, um einen Fehler zu umgehen, ist eben
keine Fehlerkorrektur, sondern eine Umgehungslösung ("workaround").
Dussel schrieb:> Stimm ja auch. Nur klingen deine Beiträge so, als läge der Fehler im> Quelltext.
Wo sonst, wenn nach Quelltext-Korrektur alles funktioniert, wenigstens
bei mir?
Man sagt: man sollte Menschen so lieben wie sie sind. Das Gleiche
betrifft auch Compiler: man sollte Compiler so lieben, wie der ist. :)
Wir dürfen den Compiler verwenden oder nicht verwenden. Sein Verhalten
zu ändern können wir ihn nicht zwingen.
Maxim B. schrieb:> Wo liege ich falsch?Maxim B. schrieb:> Ohne Lesen von SPDR nach der Übertragung funktioniert das alles nicht.
Du bist jetzt mehrfach darauf hingewiesen worden, dass das Unsinn ist.
Bearrst aber darauf.
Damit ist das für mich eine Lüge.
Auch meinst du mich anhand meines Arduino Bekenntnis beurteilen zu
dürfen.
z.B. ich würde ohne die Arduinolibs verhungern, oder so..
Oder könnte nicht exakt den Code aus dem Eingangsposting probefahren und
das Resultat im generierten Code sehen.
Das ist Denunziantentum, oder Verleumdnung.
Such dir das schönste davon aus aus.
Maxim B. schrieb:> Wo sonst, wenn nach Quelltext-Korrektur alles funktioniert, wenigstens> bei mir?
Im Compiler. Wenn der Compiler korrekten Quelltext falsch übersetzt, ist
es ein Fehler des Compilers. Daran ändert sich auch nichts, wenn man
einen anderen korrekten Quelltext findet, den der Compiler fehlerfrei
übersetzt.
S. Landolt schrieb:> Maxim B. meint vermutlich diesen Mechanismus, aus dem Datenblatt zu> 'SPSR – SPI Status Register, • Bit 7 – SPIF: SPI Interrupt Flag':>> "Alternatively, the SPIF bit is cleared by first reading the SPI Status> Register with SPIF set, then accessing the SPI Data Register (SPDR)."
Ja, wahrscheinlich genau das. Ich habe mir seit dem Fall einfach als
Regel festgelegt: SPI immer voll anzusprechen (Schreiben und Lesen) und
dummi-byte am Anfang schicken, bei Init. Solange ich das mache, bekomme
ich kein Problem. Wozu sollte ich was besseres suchen, wenn das gut
arbeitet?
Auch jetzt bei dem Experiment: das Programm blieb auf SPSR-Prüfung
hängen. Ich habe return SPDR geschrieben - und alles läuft. So einfach.
Dussel schrieb:> Wenn der Compiler korrekten Quelltext falsch übersetzt, ist> es ein Fehler des Compilers.
Ja, aber ich benutze, wie auch TO, diesen Compiler. Ich habe keinen
anderen. Ich muß also den Text so schreiben, daß Compiler mich versteht.
Schreibe ich so, daß Compiler mich nicht versteht, dann ist absolut
egal, wer von uns Recht hat: ich oder Compiler. Ich brauche das
Programm, für Compiler ist das egal.
Dussel schrieb:> Der Fehler liegt im Compiler.
Nein, das ist nicht wahr.
Das Oszi war/ist kaputt.
Maxim B. schrieb:> Auch jetzt bei dem Experiment: das Programm blieb auf SPSR-Prüfung> hängen. Ich habe return SPDR geschrieben - und alles läuft. So einfach.
Auch hier unterstelle ich dir eine dreiste Lüge.
Da im Beispiel keine ISR/InterruptFlag zum Einsatz kommt, kann ein
solcher Fehler auch nicht auftreten.
Wie schon gesagt...
Mit einem halben Dutzend AVR Gcc Toolchains getestet.
Arduino Fanboy D. schrieb:> Dussel schrieb:>> Der Fehler liegt im Compiler.> Nein, das ist nicht wahr.> Das Oszi war/ist kaputt.
Stimmt anscheinend.
Wenn der Compiler sich so verhalten würde, wäre es ein Fehler des
Compilers. ;-)
Dussel schrieb:> Wenn der Compiler sich so verhalten würde, wäre es ein Fehler des> Compilers. ;-)
Einen Fußgänger, von LKW überfahren, ist kaum nützlich, wenn er auch
Recht hatte :)
Maxim B. schrieb:> nach solchen deinen Worten existierst du für mich nicht mehr. Deine> Posten werde ich in der Zukunft nie mehr beantworten.
Höre einfach auf die Leute zu verarschen, dann kommen auch wir beide
bestens klar.
Ich habe doch den selben Code wie vom Anfang ausprobiert und es
funktioniert.
Also kann es ja doch nicht daran liegen, dass ich das Datenregister
nicht auslese.
Maxim B. schrieb:> Jetzt erinnere ich: einmal habe ich gleiche Fehler gemacht. Ich dachte:> wozu muß ich noch die Zeit vergeuden, und SPDR lesen, wenn ich nur> senden möchte?
Bei SPI gibt es kein "nur senden". Bei einem Transfer über SPI wird vom
Master immer ein Byte über MOSI raus geschoben und gleichzeitig eins
über MISO eingelesen.
>Also kann es ja doch nicht daran liegen, dass ich das Datenregister>nicht auslese.
Im Datenblatt steht ja auch nicht dass man das Register "Lesen" muss.
Dort steht dass man auf SPDR zugreifen muss um SPIF zu löschen.
Schreiben ist auch ein Zugriff, und das machst du ja auch.
> ... Schreiben ist auch ein Zugriff ...
Genau; deshalb funktioniert das von Dussel gezeigte
Atmel-Programmbeispiel ja auch, für sich betrachtet. Allerdings bleibt
außerhalb der Routine das SPIF gesetzt (was wohl bei Maxim B. irgendwann
zu Problemen geführt hatte).
Maci M. schrieb:> Ich habe doch den selben Code wie vom Anfang ausprobiert und es> funktioniert.
Das war mein Verdacht.
> Also kann es ja doch nicht daran liegen, dass ich das Datenregister> nicht auslese.
Und was hast du sonst noch gemacht?
Oder eher: was hast du gemacht, dass es nicht funktioniert hat?
Lothar M. schrieb:> Ich glaube, der Compiler hatte einfach statt des C-Codes den falschen> Kommentar in Code umgesetzt:
Ich hatte tatsächlich nur den Kommentar gelesen und mir den Code nicht
genau angeschaut ;)