Hallo zusammen,
ich kenne mich mit Bitoperationen noch nicht so gut aus.
Folgendes Problem:
Über SPI sollen mit einem Atmega32 3 Integer-Variablen gesendet werden.
Damit die jeweils in das SPDR passen, habe ich folgende Operationen
programmiert (SPI_send ist die Sendefunktion. Die funktioniert!):
1
for(i=0;i<4;i++)
2
{
3
// Low-Byte senden
4
send_SPI(((unsignedchar)(control[i]&0x00ff)));
5
// High_Byte senden
6
send_SPI(((unsignedchar)(control[i]>>8)));
7
}
Der Slave-Controller (ebenfalls Atmega32) geht mit dem empfangenen
Ergebnis wie folgt um:
Hallo,
irgendwie verstehe ich Bahnhof...
SIGNAL(SIG_SPI)
{
// count zählt die empfangenen Bytes (0-5)
letter[count] = SPDR;
if (count == 5)
{
count = 0;
}
}
wer oder was ist count, wer ändert count und wo und warum?
Gruß aus Berlin
Michael
count wird außerhalb von der Endlosschleife ein Mal auf Null gesetzt und
ist dann dafür da, die Anzahl der empfangenen Bytes zu senden.
Da 3 Int-Werte geschickt werden, muss 6x gesendet werden, bis die SPI
alles verschickt hat. Und count zählt durch und steuert das Schreiben
der Werte in das Feld letter...
Dennis schrieb:
> Hallo zusammen,
Ja hallo.
> Über SPI sollen mit einem Atmega32 3 Integer-Variablen gesendet werden.> Damit die jeweils in das SPDR passen, habe ich folgende Operationen> programmiert (SPI_send ist die Sendefunktion. Die funktioniert!):>>
1
>for(i=0;i<4;i++)
2
>{
3
>// Low-Byte senden
4
>send_SPI(((unsignedchar)(control[i]&0x00ff)));
5
>// High_Byte senden
6
>send_SPI(((unsignedchar)(control[i]>>8)));
7
>}
8
>
Du sendest aber 4 Integer raus !
> Der Slave-Controller (ebenfalls Atmega32) geht mit dem empfangenen> Ergebnis wie folgt um:>>
1
>SIGNAL(SIG_SPI)
2
>{
3
>letter[count]=SPDR;
4
>SPDR=0x44;
5
>if(count==5)
6
>{
7
>TIMSK&=(~(1<<TOIE0));
8
>}
9
>else
10
>{
11
>count++;
12
>}
13
>}
14
>
Ziemlich unklar, warum läuft da nen Timer und wofür ?
>
Wasn dat. Das kann gar nit gehen du packst ständig irgend etwas in deine
tolles Array gap. Zeige mal deinen ganzen aktuellen Code mit dem Mist
kann keiner was anfangen !
Gruß
> Ja hallo.> Über SPI sollen mit einem Atmega32 3 Integer-Variablen gesendet werden.> Damit die jeweils in das SPDR passen, habe ich folgende Operationen> programmiert (SPI_send ist die Sendefunktion. Die funktioniert!):>>> for (i = 0; i < 4; i++)> {> // Low-Byte senden> send_SPI(((unsigned char) (control[i] & 0x00ff)));> // High_Byte senden> send_SPI(((unsigned char) (control[i] >> 8)));> }>> Du sendest aber 4 Integer raus !
Is klar! Die Schleife läuft solange kleiner 4 und es werden pro
Schleifendurchlauf 2 Bytes gesendet. Also werden drei Durchläufe gemacht
mal zwei Bytes sind sechs Bytes, also drei Integer.
>> int main()> {> // Laufvariable auf null> a = 0;>> // gesendete Abstände wieder zusammensetzen...> for (i = 0; i < 6; i = i + 2)> {> // gesendet wurde erst Low-Byte dann High-Byte> gap[a] = (((unsigned int) (letter[(i + 1)] << 8)) | ((unsigned int)> letter[i]));> a++;> }>> Wasn dat. Das kann gar nit gehen du packst ständig irgend etwas in deine> tolles Array gap. Zeige mal deinen ganzen aktuellen Code mit dem Mist> kann keiner was anfangen !
Ah so. Nur weil etwas ständig gemacht wird, geht es also nicht.
Und überhaupt: Was gibst Du hier für nen Mist von Dir? Du musst ihm
nicht helfen, und wenn Du es nicht kannst, dann brauchst Du hier auch
nicht so nen Senf von Dir zu geben, OK?
Stefan schrieb:
>> for (i = 0; i < 4; i++)> Is klar! Die Schleife läuft solange kleiner 4 und es werden pro> Schleifendurchlauf 2 Bytes gesendet. Also werden drei Durchläufe gemacht
Au weh. Noch keinen Kaffee gehabt? Versuch's lieber nochmal.
Schlechte Stimmung am Montagmorgen? :)
Vielen Dank, das mit der FOR-Schleife ist der Fehler.
Sollte i<3 heissen! Also wird auch immer einer zu viel gesendet, was
begründet, warum die Karre nicht so tut wie sie soll!
Danke an ALLE Beteiligten ;) Und das nächste Mal poste ich besser den
ganzen Code!
Viele Grüße!
D.
Lothar Miller schrieb:
> Angenommen letter wäre ein char-Array, dann ergibt
1
(letter[(i+1)]<<8)
> immer 0.
Keineswegs. Nur wenn sich der Compiler nicht an den Standard hält. Der
schreibt nämlich vor, dass alle ganzzahligen Rechnungen mindestens als
"int" oder "unsigned" durchgeführt werden.
Folglich darf man das in korrektem C auch so schreiben:
1
gap[a]=(letter[i+1]<<8)|letter[i];
Es gibt allerdings ein paar Compiler für 8-Bitter, die in einer
bestimmten Compilereinstellung diese Regel verletzen um besseren Code
erzeugen zu können.
>Zuverlässiger (und beabsichtigt) ist das wohl eher so:>gap[a] = (((unsigned int) letter[i+1]) << 8) | ((unsigned int) letter[i]);
Also die runden Klammern bei letter[i+1] weglassen?
Ich programmiere mit AVR Studio 4.0 ... falls die Info zur Lösung des
Problems beiträgt!
Btw: In Deiner Main bearbeitest Du bereits Eingaben, ohne zu prüfen, ob
alle Daten angekommen sind. Du solltest erst dann loslegen, wenn count
die 6 (!) erreicht hat - erst dann sind alle benötigten Daten da.
Was Du in SIGNAL(SIG_SPI) mit dem Timer-Interrupt machen willst, ist mir
dabei immer noch unklar. Oder wolltest Du den SPI-Interrupt abschalten?
Wenn nein, könnte es sein, dass letter einen Speicherüberlauf ergibt,
falls noch weitere Daten per SPI folgen.
Also zumindest SPI-Interrupt abschalten und nach der Datenverarbeitung
count auf 0 sowie SPI-Interrupt wieder einschalten.
Beachte aber auch, dass SPI-Eingaben verschwinden können, wenn wärend
der Datenverarbeitung mehrere Daten eingehen.
> Was Du in SIGNAL(SIG_SPI) mit dem Timer-Interrupt machen willst, ist mir> dabei immer noch unklar. Oder wolltest Du den SPI-Interrupt abschalten?
Nein, da wird und soll tatsächlich der Timer abgeschaltet werden. Das
Programm macht noch mehr, als ich hier geschrieben habe. Das nächste Mal
lege ich einfach alles ab.
> Wenn nein, könnte es sein, dass letter einen Speicherüberlauf ergibt,> falls noch weitere Daten per SPI folgen.
Ich frage ab, ob sechs Bytes angekommen sind:
1
SIGNAL(SIG_SPI)
2
{
3
letter[count]=SPDR;
4
SPDR=0x44;
5
if(count==5)
6
{
7
TIMSK&=(~(1<<TOIE0));
8
}
9
else
10
{
11
count++;
12
}
13
}
> Also zumindest SPI-Interrupt abschalten und nach der Datenverarbeitung> count auf 0 sowie SPI-Interrupt wieder einschalten.
Wenn ich den SPI-Interrupt abschalte, sendet der Master ja trotzdem
weiter, oder? Also könnten doch Daten verloren gehen, bzw in der
falschen Reihenfolge eintreffen, korrekt?
> Beachte aber auch, dass SPI-Eingaben verschwinden können, wenn wärend> der Datenverarbeitung mehrere Daten eingehen.
Das musst Du mir bitte erklären!