Bumbum
12.07.2013, 18:11
Hallo Leute,
ich möchte von einem ATmega8 zu einem ATmega644 Daten übertragen. Es geht dabei um 4 Byte, die ich etwa 10x die Sekunde aktualisieren möchte. Also kein Geschwindigkeits-Rekord. Ich habe am ATmega8 direkt an zwei Portpins eine Buchsenleiste. In dieser steckt ein ca. 5m langes Kabel. 4x dünn, ich schätze 0,34mm². Darüber gehen über zwei Adern die Versorgungsspannung (5V) und über die anderen zwei Adern die Daten (Data und Clk). Zum senden verwende ich folgenden Code:
U8 i1;
for (i1 = 0; i1 < 4; i1++)
{
U8 sendByte = sendData[i1];
U8 i2;
for (i2 = 0; i2 < 8; i2++)
{
if ((sendByte & 0b10000000) == 0)
Data0;
else
Data1;
_delay_ms (1);
Clk1;
_delay_ms (1);
Clk0;
_delay_ms (1);
}
}
Im ATmega644 habe ich einen Interrupt (PCINT22) auf die steigende Flanke des Clk-Signals programmiert und schiebe die Daten dort wieder in die 4 Datenbytes. Das ganze funktioniert ein paar Sekunden und dann ist der Bus durcheinander. Mir ist klar, dass da noch Start- und Stop-Bedingungen, und eine Prüfsumme, etc. dazu kommen sollten, aber grundsätzlich dachte ich sollte es vorher so zumindest fast gut funktionieren, sonst sind die Controller mehr mit Fehlerbehandlung beschäftigt wie mit Datenaustausch.
Ein verlängern der Delays in der Sende-Schleife auf bis zu 20ms zum testen hat keine Besserung gebracht. Ich habe hier mal gelesen, dass es auch gar nicht daran liegt, sondern daran wie schnell der Sender den Ausgangspin wechselt. Der ATmega8 läuft am internen RC-Oszillator, also ca. mit 1MHz.
Leider verstehe ich nicht viel von solchen Datenbussen und die dabei entstehenden Reflektionen bei schnellem Wechsel der Pegel und den dafür nötigen Abschluß. Ich habe zum testen auf die Empfängerseite jeweils von Data auf Masse und von Clock auf Masse 4k7 Widerstände verbaut, aber das hat leider nichts gebracht.
Auf der Empfängerseite muss ich mit Interrupts arbeiten, da der Controller viele Aufgaben gleichzeitig abbarbeiten muss und auch in der Hauptprogramm-Schleife recht beschäftigt ist. Ein pollen der Daten nach dem erkennen einer Start-Bedingung kann ich also nicht umsetzen. Die 3 Timer sind wegen dem Multitasking leider auch schon alle belegt. Zur Not müsste ich mal schauen, ob ein Timer grob im benötigten Clk-Frequenz-Bereich liegt und dann das Delay auf dem ATmega8 anpassen.
Aber das wäre alles ein Workaround und nicht die Ursache des Problems behoben. Also: Wer hat einen Tipp für mich, wie ich den Bus abschließen muss, damit die Übertragung gut funktioniert?
Viele Grüße
Andreas
ich möchte von einem ATmega8 zu einem ATmega644 Daten übertragen. Es geht dabei um 4 Byte, die ich etwa 10x die Sekunde aktualisieren möchte. Also kein Geschwindigkeits-Rekord. Ich habe am ATmega8 direkt an zwei Portpins eine Buchsenleiste. In dieser steckt ein ca. 5m langes Kabel. 4x dünn, ich schätze 0,34mm². Darüber gehen über zwei Adern die Versorgungsspannung (5V) und über die anderen zwei Adern die Daten (Data und Clk). Zum senden verwende ich folgenden Code:
U8 i1;
for (i1 = 0; i1 < 4; i1++)
{
U8 sendByte = sendData[i1];
U8 i2;
for (i2 = 0; i2 < 8; i2++)
{
if ((sendByte & 0b10000000) == 0)
Data0;
else
Data1;
_delay_ms (1);
Clk1;
_delay_ms (1);
Clk0;
_delay_ms (1);
}
}
Im ATmega644 habe ich einen Interrupt (PCINT22) auf die steigende Flanke des Clk-Signals programmiert und schiebe die Daten dort wieder in die 4 Datenbytes. Das ganze funktioniert ein paar Sekunden und dann ist der Bus durcheinander. Mir ist klar, dass da noch Start- und Stop-Bedingungen, und eine Prüfsumme, etc. dazu kommen sollten, aber grundsätzlich dachte ich sollte es vorher so zumindest fast gut funktionieren, sonst sind die Controller mehr mit Fehlerbehandlung beschäftigt wie mit Datenaustausch.
Ein verlängern der Delays in der Sende-Schleife auf bis zu 20ms zum testen hat keine Besserung gebracht. Ich habe hier mal gelesen, dass es auch gar nicht daran liegt, sondern daran wie schnell der Sender den Ausgangspin wechselt. Der ATmega8 läuft am internen RC-Oszillator, also ca. mit 1MHz.
Leider verstehe ich nicht viel von solchen Datenbussen und die dabei entstehenden Reflektionen bei schnellem Wechsel der Pegel und den dafür nötigen Abschluß. Ich habe zum testen auf die Empfängerseite jeweils von Data auf Masse und von Clock auf Masse 4k7 Widerstände verbaut, aber das hat leider nichts gebracht.
Auf der Empfängerseite muss ich mit Interrupts arbeiten, da der Controller viele Aufgaben gleichzeitig abbarbeiten muss und auch in der Hauptprogramm-Schleife recht beschäftigt ist. Ein pollen der Daten nach dem erkennen einer Start-Bedingung kann ich also nicht umsetzen. Die 3 Timer sind wegen dem Multitasking leider auch schon alle belegt. Zur Not müsste ich mal schauen, ob ein Timer grob im benötigten Clk-Frequenz-Bereich liegt und dann das Delay auf dem ATmega8 anpassen.
Aber das wäre alles ein Workaround und nicht die Ursache des Problems behoben. Also: Wer hat einen Tipp für mich, wie ich den Bus abschließen muss, damit die Übertragung gut funktioniert?
Viele Grüße
Andreas