Hallo Zusammen, ich arbeite im Rahmen eines Projektes mit dem AT32UC3C0512C und möchte damit eine CAN-Kommunikation aufbauen. Um in die Thematik näher rein zu finden, habe ich das Beispielprogramm CAN_EXAMPLE21 vom Atmel Software Framework im Atmel Studio 6 in Betrieb genommen. Ich habe lediglich die UART-Anzeige herausgenommen und die Baudrate halbiert. Leider hängt sich das Programm nach einmaligem Senden sofort auf. Dies aber nur, wenn ein Teilnehmer am Bus hängt. Ich konnte den Fehler soweit eingrenzen, dass beim Senden kein Fehler auftritt wenn ich die Funktion CANIF_mob_enable_interrupt(ch,handle) herausnehme. Diese ist in CAN_tx() hinterlegt und sorgt für einen Interruptaufruf des MessageObjects. Ich habe im Anhang das Projekt angehängt und dazu auch noch zwei Screenshots der Initialisierung. In einem anderen Beitrag im Forum habe ich gelesen dass bei dem Bsp. evtl. die Systemtimerinitialisierung fehlen würde, aber ich konnte leider nicht verstehen, was dort gemeint ist. Hier der Link dazu: Beitrag "AT32UC3C0512C - CAN-Probleme" Über Hilfe oder Anregungen wäre ich sehr dankbar. Viele Grüße Simon
>Bildformate...
Ein öffentlicher Pranger in einem Forum/Wiki. Wo gibt's denn so was.
Ist das peinlich. Und da steht er jetzt bin in alle Ewigkeiten drin,
weil die GIFs unscharf sind ?
Ich schäme mich echt für diesen Wikiartikel.
Hallo! Entschuldigt bitte die Bildformate. Hab gestern Abend den Hinweis überlesen. Das tut mir Leid. Wenn ihr wollte lade ich die Bilder nochmal hoch und zwar in einem besseren Format.
Hallo Simon, schön das mein Artikel einmal zitiert worden ist. Ich habe die 2 Beispiele auch schon einmal compiliert und programmiert. Man braucht dazu den VCP-Treiber für den PC, um sehen zu können, was der Controler macht. Die CAN-LIN-Applikation läuft ganz anständig. Da wurde im ASF auch kein Sleep-Modus verwendet. Einzig die Art der Datenhaltung ist gewöhnungsbedürftig. Was willst Du erreichen?
Hallo! Ist ja cool, dass du dich meldest. Mein Ziel ist es Daten von verschiedenen CAN-Teilnehmern zusammen zu sammeln und zu verarbeiten. Zum Test wollte ich das Senden von Daten zu den Teilnehmern und das Anfordern separat ausprobieren. Ich habe den Teil mit der Anzeige über das Hyperterminal rausgemacht. Könnte es schon reinmachen, aber im Prinzip mach ich das gleiche wie die Steuerung über den COM, abgesehen davon dass ich alle 2Sekunden zyklisch etwas senden möchte. Was hast du damals mit der fehlenden Systemtimerinitialisierung gemeint? Was hat konkret gefehlt? Vielen Dank für deine Hilfe!
Moin Simon, das ist mittlerweile ganz schön her. Ich habe noch die Projekte und muß einen Diff drüberlaufen lassen. Aber ich glaube mich noch dunkel daran zu erinnern, dass die einfach den Funktionsaufruf der sys_clock vergessen hatten. Ich hatte CAN-Beispiel 2 gegen die CAN-LIN-Application-Demo verglichen. Und da ist mir das dann aufgefallen. Ja, generell kostet dieser Prozessor mit seinem Framework echt viel Zeit und erst jetzt, wo ich ein paar hundert Seiten des UG vom UC3C gelesen habe, fange ich an zu verstehen, was die da in Norwegen programmiert haben. Da haben die von Infineon mit ihrem DaVE eine bessere Lösung angeboten, um schnell einen Start-up für ihre Prozessoren hinzubekommen. Außerdem habe ich immer noch keine brauchbare Doku gefunden, die mir die Funktionen der Komponenten und Treiber des ASF beschreibt. Das ist eigentlich eine Grundvoraussetzung, um den Vorteil der angebotenen Lösungen zu verstehen und zeitnah nutzen zu können. Ich will ja die ganzen Parameter und Definitionen nicht im reverse Engineering herausfinden müssen. Aber das mache ich gerade. Das Hauptproblem sind die gegenseitigen Abhängigkeiten der einzelen Komponenten. Das Wort "Peripherie" wird dem Funktionsumfang nicht gerecht. Das System - Control - Interface (SCIF) organisiert die vielfältigen Möglichkeiten der Takterzeugung. Dazu gehören auch die PLLs. Der Power Manager (PM) wiederum unterstützt die Takterzeugung für die CPU und verschiedenen Busse. Er wird vom SCIF angetrieben. Nach dem Reset läuft alles irgendwie - aber nur mit 115 kHz RC-Takt. Wenn man beim UC3C irgendeine Komponente benutzen möchte, dann muß man die zielführende taktweiterleitenden Funktion des Power Managers in der SCIF auswählen. Für das CAN-Interface muß man einerseits die Takterzeugung für das Peripherie-Modul selbst aktivieren. Damit meine ich z. B. die Logistik-Logik, die die Ergebnisse in den RAM schreibt oder liest, etc. Dann braucht man noch eine Generic Clock. Und zwar die GCLK1. Sie erzeugt den Takt für die TimeQuanta. Das war beim AT90CAN128 insofern einfacher, weil der Systemtakt sowohl für die Logik als auch für Signalerzeugung herangezogen wurde. Nur so nebenbei. Beide Knoten CAN 1 und CAN 2 laufen dann immer mit der gleiche Zeitbasis. Also das Erzeugen eines Gateways mit unterschiedlichen CAN-Taktraten geht mit diesem Prozessor nicht. Gut ich habe auch noch nicht alles gelesen. Ich will mich da nicht zu weit aus dem Fenster hängen. Aber die Support- Ings. von Atmel bei einem Seminar in Hannover haben mir ausweichend geantwortet. Die GCLK0 bezieht ihren Takt u. a. von den Taktquellen des PMs. D. h. damit bei CAN-Knoten überhaupt etwas rauskommt, muss in dem SCIF die GCLK0 aktiviert sein. Wenn das nicht der Fall ist und man bei Senden auf das "Message ist raus - Bit" in einer While-Schleife wartet, dann hängt sich der Prozessor auf. Eigentlich wartet er auf etwas, was niemals eintreten wird. Das ist im ASF unvorteilhaft gelöst. Aber das ist natürliche eine Philosophiefragen. Ich strebe lieber den schwierigeren aber nachhaltigeren Weg an. In den Beispielen haben die Norweger das fast immer berücksichtigt. Nur in den Quellen ist das bescheiden dokumentiert. Und dann sucht man sich einen Wolf oder legt das Teil entnervt beiseite. Im Grunde bin ich ein Atmel - Fan und deshalb wurmt es mich, dass es nicht läuft. Aus diesem Grund habe ich noch nicht aufgegeben. Aber die grosse Rechenleistung des UC3C konnte ich noch nicht positionieren. Mein Ziel ist es einen lowpower CAN-Data-Logger auf SD-Karte zu programmieren. Außerdem will ich ein Target für den Embedded Coder in Matlab/Simulink aufsetzen. Für den AT90CAN128 und einige ATmegas läuft das bereits. So Simon, vielleicht ist in dem Geschriebenen die Lösung für Dein Problem enthalten. Mach ein paar Diffs mit Projekten, wo es funktiniert. Damit kam ich zum Ziel. Übrigens, was benutzt Du, um Dein gesendetes Signal zu Bestätigen (Acknowledge)? Falls Du nichts benutzt, könnte auch das das Problem sein. Bei CAN sollte ein Sender immer einen Zuhörer haben. Sonst gibt es einen Acknowledge-Fehler. Den kann man ignorieren. Aber das muss man dann auch einstellen. Bis dann. Carsten
Simon schrieb: > Leider hängt sich das Programm nach einmaligem Senden sofort auf. Was bedeutet "aufhängen"? > Ich konnte den Fehler soweit eingrenzen, dass beim Senden kein Fehler > auftritt wenn ich die Funktion CANIF_mob_enable_interrupt(ch,handle) > herausnehme. Diese ist in CAN_tx() hinterlegt und sorgt für einen > Interruptaufruf des MessageObjects. Dann setz doch mal einen Break-Point in die ISR und schau, was dort passiert. Wird das Interrupt-Request-Flag zurückgesetzt? Ansonsten wird die CPU endlos diese ISR anspringen.
Hallo, ich benutze gerade auch der AT32UC3C0512C, um eine CAN-Kommunikation aufzubauen. Der CAN-Netzwerke sollte aus zwei CAN-Knoten bestehen, die Daten untereinander tauschen. Als erste Schritt, habe ich das UC3C CAN and LIN Loopback Beispiel so geändert, dass ein CAN-Kanal Daten periodisch senden und empfangen kann. Die beiden CAN-Kanäle senden und empfangen Nachrichten, aber nach einer gewissen Zeit, hängt das Programm. Das Programm ist im Anhang angehängt. Ich wäre über Ihre Hilfe dankbar. Laura
Laura M. schrieb: > aber nach einer gewissen Zeit, hängt das > Programm. Hallo Laura, wie lange ist den die gewisse Zeit? Wie häufig sendest Du pro Sekunde? Verläuft die Kommunikation fehlerfrei? Kannst Du debuggen? -> Fehlerzähler überprüfen. ...
Hallo, ich habe ein Timer in der Code hinzugefügt und benutzt diesem, um Botschaften jedes 100 ms zu senden. Die Kommunikation verläuft fehlerfrei. Das Programm läuft für ungefähr 1 Minute. Ich könnte debuggen, hatte aber bis jetzt nicht auf der Fehlerzähler geguckt. ich werde es anschauen. Was noch erstaunlich bei der Debugging, war der Tatsache, dass nach der Allokation der 15 MOBs, der Debugger das Debuggen stoppt.
So Laura, habe mal schnell drüber geschaut. 1. Warum kommentiert Du so gar nichts? Damit machst Du das Programm auch für Dich nicht wartbar. Dann habe ich folgendes in der can_task.c gefunden: // Check return if no mob are available if (pCANMOB_message0[0].handle==CAN_CMD_REFUSED) { while(true); } Sollte Deine Programm, warum auch immer in diesen then-Zweig geraten, dann bleibt das Programm stehen, weil es nie wieder aus der while-schleife herauskommen. Außer mit einem Reset natürlich. Was bezweckst Du mit dem Timer? Ja Du willst etwas schedulen. Aber wieso reicht da nicht die Verzögerung (Delay)? Willst Du eine Task-Parallelisierung umsetzen? Wo hast Du 15 Messageobjekte programmiert? Der Entscheider in der Interrupt-Routine switch(msg_to_send) { case 0: can_example_prepare_data_to_send1(); msg_to_send = 1; break; case 1: can_example_prepare_data_to_receive0(); msg_to_send = 0; break; case 2: can_example_prepare_data_to_send0(); msg_to_send = 3; break; case 3: can_example_prepare_data_to_receive1(); msg_to_send = 0; break; default: break; } wird nur zw. 0 und 1 hin und herschalten. Ist das so beabsichtigt? Laura tue Dir den Gefallen und kommentiere mehr. Mann kann nur ahnen was Du vor hast. ...
Hallo cskulkw, vielen Dank für die Tipps, ich habe folgendes kommentiert if (pCANMOB_message0[0].handle==CAN_CMD_REFUSED) { while(true); } die 15Message Object habe ich in der can_task.c datei deklariert(die Deklaration steht ganz oben nach die Include): //! Local Mob Declaration can_msg_t mob_ram_ch0[NB_MOB_CHANNEL]; can_msg_t mob_ram_ch1[NB_MOB_CHANNEL]; eigentlich ich wollte eine CAN-Nachricht jede 100 ms senden oder empfangen und habe mich einfach für einen Timer entschieden. Der Timer soll jeder 100 ms, ein Interrupt auflösen. Ich habe auch inzwischen der ISR so geändert: switch(msg_to_send) { case 0: send1 = true; msg_to_send = 1; break; case 1: rcv0 = true; msg_to_send = 2; break; case 2: send0 = true msg_to_send = 3; break; case 3: rcv1 = true; msg_to_send = 0; break; default: break; } und der can_task void can_task(void) { if(send1) { can_example_prepare_data_to_send1(); send1 = false; } if(rcv0) { can_example_prepare_data_to_receive0(); rcv0 = false; } if(send0) { can_example_prepare_data_to_send0(); send0 = false; } if(rcv1) { can_example_prepare_data_to_receive1(); rcv1 = false; } } Das Programm sollte so verlaufen, dass der CAN-Kanal1 mit der Funktion can_example_prepare_data_to_send1 eine Botschaft an dem CAN-Kanal0 sendet.Die wird dann mit der Funktion can_example_prepare_data_to_receive0()empfangen. CAN-Kanal0 nach Empfang der Nachricht, sendet (can_example_prepare_data_to_send0()) wiederum eine Nachricht an der Kanal1(can_example_prepare_data_to_receive1)). Das Programm läuft für ungefähr eine Minute und danach bleibt hängen. Ich hoffe ich könnte besser erklären, was ich vorhabe Bis dann Laura
Moin Laura, sorry dass ich mich erst jetzt melde. Ich hatte das so verstanden, dass Du 15 (unterschiedliche) Botschaften von Kanal 0 nach Kanal 1 senden wolltest. Aber das machst Du definitiv nicht, weil ich in der Konfiguration nur zwei Botschafts-ID gefunden habe: can_msg_t msg_tx_sot = { { { .id = 0x133, // Identifier .id_mask = 0x1ff, // Mask }, }, .data.u64 = 0x0108LL, // Data }; #endif can_msg_t msg_tx_3C7 = { { { .id = 0x3C7, // Identifier .id_mask = 0x3ff, // Mask }, }, .data.u64 = 0x1987LL, // Data }; Das sind einmal die 0x133 und Deine 0x3C7. Also, in der ASF-Demo steht folgendes: can_mob_t pCANMOB_message2[1] = { ...........................^ {CAN_MOB_NOT_ALLOCATED,&msg_rx_listening,0,CAN_DATA_FRAME,CAN_STATUS_NOT _COMPLETED} }; Und Du hast das hier geschrieben: can_mob_t pCANMOB_message2[5] = { ...........................^ {CAN_MOB_NOT_ALLOCATED,&msg_rx_listening,0,CAN_DATA_FRAME,CAN_STATUS_NOT _COMPLETED} }; Zweites Problem: Wenn Deine State-Machine funktioniert, dann würdest Du immer und immer wieder die can_init aufrufen und versuchen MessageObjekte zu allozieren. Der UC3C hat nur 32. Irgendwann sind die voll. Und genau hier kann es passieren, dass er in die Abfrage meines ersten Kommentars geraten kann. Die Funktion can_out_callback_channelx wird nirgends aufgerufen. Ich wiederhole gern meine Frage, was willst Du erreichen? Was Du hier programmiert hast, zeigt, dass Du weder das CAN-Interface des UC3C noch das ASF mit seiner Implementierung nicht richtig verstanden hast. Bitte fasse das jetzt nicht als Arroganz auf. Aber ein CAN-Interface ist schwierig zu benutzen. Darum verwenden die meisten Hobbyprogrammierer die Bibliothek vom creativen-chaos. Hast Du einen CAN-Loger? Damit Du überhaupt sehen kannst, ob da was aus dem Controler herauskommt? Oder gehst Du davon aus, dass alles richtig sein muß, wenn Du den Empfänger abfragst? ...
Hallo cskulkw, ich habe ein CANcaseXL mit einer CANoe Lizenz. Die Arbeit habe ich in drei Schritte gemacht: 1 Schritt: Ich habe von CAN-Kanal1 die Nachricht 0x133 an der CANcaseXL gesendet. Ich könnte mit CANoe überprüfen, dass die Nachricht tatsächlich gesendet wird. Nach ungefähr 30 Minuten, habe ich dann das Programm abgebrochen. 2 Schritt: Mit dem CAN-Kanal0 habe ich die Nachricht 0x3C7 an der CANcaseXL geschickt. Die wurde auch fehlerfrei von der CANcaseXL empfangen(könnte es mit CANoe bestätigen). 3 Schritt. Da die Übertragung von CAN-Nachrichten durch die beiden Kanäle fehlerfrei lief, wollte ich also der Empfang von CAN-Nachrichten überprüfen. Aus diesem Grund habe ich dann die funktion can_example_prepare_data_to_receive1() und can_example_prepare_data_to_receive0 in der Code hinzugefügt. Ich möchte einfach überprüfen, dass die beiden Kanäle auch CAN-Nachrichten fehlerfrei empfangen können. Deswegen versuche ich CAN-Nachrichten(0x133) von Kanal1 an Kanal 0 zu senden. Ebenso versuche ich die CAN-Nachricht(0x3C7) von Kanal0 an Kanal1 zu senden. Ich versuche nicht 15 verschiedene Nachrichten zu senden. Ich versuche nur zwei Nachrichten zu senden: 0x133 von kanal1 nach Kanal0 und 0x3C7 von Kanal0 zum Kanal1. Ich glaube die Tatsache, dass ich can_mob_t pCANMOB_message2[5] definiere hat hier keinen großen Einfluss auf das Programm, oder??
Moin Laura, hatte gestern keine Lust mehr auf dem Handy zu antworten. Szenario Kanal 0 sendet eine Botschaft mit der CAN-ID 0x3C7 an Kanal 1 1. Ein Messageobjekt (und nur EINS !) in Kanal 0 allozieren und ihm die CAN-ID 0x3C7 zu weisen. Der Modus muss TX für Senden sein. 2 Ein weiteres Messageobjekt (und auch hier nur EINS und keine FÜNF !) in Kanal 1 allozieren und ihm ebenfalls die CAN-ID 0x3C7 zuweisen. Ergänzend dazu die IDM ebenfalls auf 0x3C7 einstellen. Dann ist sichergestellt, dass der FIlter nur CAN-Botschaften mit dieser Adresse zuläßt. 3. Mit jedem Senden der Botschaft auf Kanal 0 veränderst Du im Anschluß die CAN-Daten. Sonst siehst Du nur einen Glücktreffer und kannst ihn nicht unterscheiden. 4. Jetzt muss der veränderte Dateninhalt im Datenspeicher von Mob 1 des Kanal 1 zu sehen sein. 5. Ich habe noch einmal im Datenblatt nachgeschaut, weil ich wissen wollte, ob die Messageobjekte innerhalb eines Kanals priorisiert sind. Das würde bedeuten, wenn man Objekt 0 bis 4 gleichzeit zum Senden aktvieren würde, dann würde die Hardware mit dem niedrigsten oder höchsten Objekt anfangen. Alle weiteren würden der Reihe nach dran kommen. Bei Senden ist das nachvollziehbar. 6. Bei Empfang habe ich nicht herausgefunden, ob die Priorisierung ebenfalls funktioniert, wenn mehrere Objekte des gleichen Kanals die gleiche CAN-ID haben. Das macht man ja eigentlich nicht, weil es Verschwendung wäre, zwei oder mehrer Messageobjekte mit ein und der selben ID zu belegen. Und deshalb reite ich so auf der 5 beim Empfangsspeicher herum. Es könnte sein, dass die Hardware einen Klemmer bekommt, weil 5 MessageObjekte sich gleichzeitig auf den empfangenen Dateninhalt stürzen. Die FOlge könnte der Dead-Lock sein. 7. Also, wenn Du das jetzt änderst und der Klemmer tritt wieder auf. Dann gebe ich mich geschlagen. Dann ist es was anderes. Das mußt Du dann selbst herausfinden. 8. Und da die bei ATMEL einen schlechten Support haben und gern pfuschen, weil alles billig in der Produktion aber teuer im Verkauf sein muß, würde es mich nicht wundern, wenn da noch ein Fehler im CHip vorliegt. 9. Ach und weil Du eine halbe Stunde mit CANoe die Botschaft 0x133 empfangen haben willst, scheint Dein Klemmer ja offensichtlich nicht mehr vorzuliegen. Ich wünsche Dir noch viel Erfolg. Genügend Hinweise habe ich Dir gegeben. ...
Hallo cskulkw, vielen Dank für die Hinweise. Die Habe ich eingesetzt und könnte schon etwas zum Laufen bringen(siehe Abbildung 1 und 2). Jetzt habe ich dann weiter versucht die Kommunikation wie es auf die Abbildung(Abbildung.GIF) zu sehen programmiert. Aber beim Debuggen, habe ich festgestellt, das die beiden Kanäle Daten senden, aber nichts wird empfangen. Ich wäre über Vorschläge sehr dankbar.
Hallo Laura, kannst du bitte dein funktionierendes Projekt hochladen. Brauche auch einen Starthilfe für CAN. Danke!
ich habe zur Zeit auch das Problem mit dem CANIF des UC3C, dass mit jedem Kanal nur die Message Objekte 0-15 gesendet werden können. Danach findet kein weiteres Senden statt. an welcher Stelle müssen die MOB wieder freigegeben werden, damit sie erneut verwendet werden können?
Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.