www.mikrocontroller.net

Forum: Mikrocontroller und Digitale Elektronik Problem mit CAN-Interrupt in der Main-Funktion


Autor: gast (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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

Autor: Fabian B. (fabs)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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

Autor: gast (Gast)
Datum:
Angehängte Dateien:

Bewertung
0 lesenswert
nicht lesenswert
hallo,
anbei die Code

Autor: gast (Gast)
Datum:
Angehängte Dateien:

Bewertung
0 lesenswert
nicht lesenswert
sorry,
anbei das gesamte Programm

Autor: Stefan Kunz (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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

Autor: Stefan Kunz (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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

Autor: Stefan Kunz (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ah und es könnte wieder sein das die Schleife in der Wartefunktion der 
Übertragungsfunktion wegoptimiert wird

Autor: Stefan Kunz (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Okay ich sollte mich wirklich mal Anmelden. ^^ Die while-Schleife wird 
nicht wegoptimiert.

Autor: gast (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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

Autor: Stefan Kunz (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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.

Autor: gast (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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.

Autor: Stefan Kunz (syliosha)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
 void Wait_for_Can_Receive_message_Finished(void)
 {   
    
   double can_timeout2 = TIMEOUT_C; /*Timeout for CAN-communication*/
   while (!( CANSTMOB & (1<<RXOK)) && (--can_timeout2>0)) 
   {
    
     /* do nothing  */

                /*Hier _delay_ einbauen*/
      
   }
  
     
  
   CANSTMOB &= ~(1<<TXOK);  /* reset transmition flag */  
   CANCDMOB &= ~(1<<CONMOB0); /* disable transmition mode */
   
  
  
 }

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

Autor: gast (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
hallo Stefan,
ich werde es probieren. Ich danke Dir.

Autor: Stefan Kunz (syliosha)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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.

Autor: gast (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
hallo Stefan,
die Nachricht mit ID = 384 ist richtig, mit dem kann ich die Temperatur 
des Lüfters(VME-Crate) auslesen.

Autor: gast (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
sorry,
ID = 0x384

Autor: Stefan Kunz (syliosha)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
ah okay sah halt sehr verdächtig nach CANopen aus, daher mein Kommentar 
wußte ja nicht wofür das war.

Dann noch viel Erfolg

MfG
Stefan

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.