hallo zusammen,
ich habe ein Programm geschrieben für die CAN-Kommunikation. Das
Programm ist interrupt gesteuert. Meine Problem ist: Wenn ich das
Programm laufen lasse, wird Can_transmit1(msg1) und Can_transmit2(msg2)
aufgerufen, aber er springt nur einmal in der ISR mit der Funktion
Can_transmit2(msg2).Ich verliere die Daten, die vom esrten Befehl
kommen. Meine Frage ist: wie kann ich Can_transmit1(msg1)und nach einige
Zeit Can_transmit2(msg2) aufrufen und jedesmal ohne die Daten zu
verlieren.So sieht ungefähr mein main-Function aus.
Danke
main.c
volatile unsigned char can_flag;/*variable for can interrupt*/
int main(void)
{
can_flag=0;
cli();
CAN_Init();
UART_Init();
Can_transmit1(msg1);
for(int i = 0; i < 255; i++)
{
b++;
}
Can_transmit2(msg2);
sei();
while(1)
{
if (1 == can_flag) /* of the ISR data has been fully received */
cli();
Convert_pack_canFrame_to_UartFormat(ptr_canStruct);
can_flag = 0; /* restore flag */
sei();
}
}
Danke
Mehr Info bitte!
So kann dir das keiner sagen... was macht can_transmit genau (code!)?
was ist msg1 und msg2 für ein Konstrukt?
Ohne vollständige compilierfähige Version wird das nix...
Gruß
Fabian
Den wichtigen Teil hast du ausgelassen wie die can.h und eventuell
andere Programmteile wo du die Funktionen die du in main benutzt
deklarierst und defenierst ebenso fehlt die Interruptroutine.
Außerdem kann es dir passieren das deine for-Schleife wegoptimiert wird,
außerdem nimm das double von i weg, solche Zählervariablen sind
(meistens) Interger
MfG
Stefan
ah okay.
So auf den ersten Blick scheint es mir ehr so, dass du fertigen Code
benutzt, aber ist ja nun nicht das Thema.
Das Problem ist, dass die Can_transmit() Funktionen eine andere Funktion
aufrufen die Wartet bis der Transmit auf dem CAN-Buss erfolgreich ist
und dazu noch ein Time-Out haben.
Der Wert für den Time-Out ist mit 5000 zu klein angesetzt, da auf dem
CAN-Bus bei 1Mbit Übertragungsrate 1bit 1µs dauert dementsprechen eine
volle Nachricht bis zu 140µs (war zu faul jetzt genau nachzuzählen) aber
innerhalb dieser Zeit dürfte der AVR die Warteschleife trotz wieder
einem double Zählervariablen mehr als 5000 mal durchlaufen haben.
MfG
Stefan
Hallo Stefan,
ich übertrage mit 250kbps, wie groß soll ungefähr Timeout sein?
Ausserdem habe ich die Wartezeit rausgenommen, aber habe ich immer das
selbe Problem.
Danke
Die Wartezeit darf nicht rausgenommen werden. Wenn ich mich recht
erinnere gibt es eine delay funktion für AVRs. Auch wenn es erstmal
nicht sauber ist würde ich das delay in die while-Schleife einbauen.
als delay Zeit sollte 1µs reichen wenn du den Time-Out-Wert bei 5000
beläßt.
Sauber wäre es, wenn du dafür einen Timer benutzt.
Hallo Stephan,
habe ich schon gestern mit Timer(nict in der Warteschlange sondern in
der mainFfunction) probiert, es klappt wunderbar. Die function werden
nach einer gewissen Zeit aufgerufen, aber das ist nicht mein Ziel.
in diesen Teil, wo du in der while-Schleife drauf wartest, dass die
Nachricht gesendet wurde, mußt du entweder ein delay einbauen oder halt
dort den Timer, da eine volle CAN-MSG bei dir bei 250kbits bisschen
weniger als 1 ms braucht, bis sie komplett abgeschickt wurde.
Ich gehe davon aus, dass du warten willst bis jede CAN-Nachricht
verschickt wurde und erst dann im Programm weiter verfahren willst, wenn
nicht solltest du dir nochmal gedanken über die Sendefunktion machen und
dich mit einem FIFO anfreuden für deine CAN-Applikation
Nur als kleine Anmerkung, wenn du, so wie es aussiehst, dich an CAN-Open
halten willst oder so ein Modul benutzt, sollte bei deiner zweiten
Nachricht nicht 0x384 sondern ehr 0x404, da 0x384 die Transmit-Nachricht
von dem Modul mit ID wäre also keine Nachrichtig die ein Master in einem
CANopen system senden würde.
Eine eigene Frage?
Dieser Thread ist über 17 Jahre alt.
Stell sie in einem eigenen Thread – dort lesen mehr Leute mit, und sie wird öfter und schneller beantwortet.