Hallo,
ich habe im Rahmen einer wissenschaftlichen Arbeit eine Bibliothek
geschrieben, mit der es möglich ist den CAN-Controller des AT90CAN128
relativ schnell und komfortabel ansprechen zu können.
Eine ausführliche Anleitung und Beispielcodes sind auch vorhanden.
Bei Fragen einfach melden
MfG
Marco
Sorry, aber sollte man nicht im Rahmen einer wissenschaftlichen Arbeit
das h-File nur für Deklarationen und die Funktionen in ein c-File
auslagern?
Ansonsten sieht das echt gut aus. Vor allem, dass du die Docu dazu
gelegt hast. Danke
Werner
Ok, hier nochmal die Version mit ausgelagerten Funktionen.
Ich würde mich über Anregungen, Verbesserungen oder einfach nur eine
Rückmeldung freuen...
Gruß Marco
Hallo Marco,
der klare Stil des Programms gefällt mir. In dem pdf File gehen aber set
und get durcheinander.
Welchen Compiler verwendest Du? Wie sieht main() aus? Wo sind die
Interrupt Service Routinen? Z.B. wartest Du bei CAN_sendData(...) bis
TXOK in CANSTMOB.
Dieses Bit kann nur durch "read modify write" geklärt werden und nicht
durch clearbit.... Ich würde gern auf Deinem Ansatz aufbauen!
Gruß Gerhard
Hallo Gerhard,
zuerst einmal vielen Dank für die Rückmeldung.
Es freut mich zu lesen, dass der Stil des Programms dir gefällt.
Bei welcher Funktion genau sind get und set durcheinander?
Ich habe für diese Bibliothek den WinAVR Compiler zusammen mit dem
AVRStudio verwendet.
Die Hauptfunktion main() kann sehr einfach aussehen. Um zum Beispiel
Daten zu senden:
1
main(){
2
CAN_init(1000,TX);
3
4
// Zu sendende Daten
5
CAN_messagemsg;
6
msg.id=0x12345678;
7
msg.idm=0xffffffff;
8
msg.data[0]=0x11;
9
msg.data[1]=0x22;
10
msg.data[2]=0x33;
11
msg.data[3]=0x44;
12
msg.data[4]=0x55;
13
msg.data[5]=0x66;
14
msg.data[6]=0x77;
15
msg.data[7]=0x88;
16
17
// Objekt 0 auf Empfang setzen
18
CAN_enableMOB(0,RECEIVE_DATA,msg);
19
20
// Daten ¨uber Objekt 0 senden
21
CAN_sendData(0,msg.data);
22
23
while(1){}
24
}
Eine ISR zum Empfang von Daten ist am Ende der CAN.c angehängt. Diese
kann ggf. individuell angepasst werden.
Beim Senden von Daten über CAN_sendData() wird gewartet, bis das TXOK
Flag gesetzt wird und erst dann die Funktion beendet.
Das mit dem read-modify-write beim TXOK stimmt so wie du es geschrieben
hast. Komischerweise funktioniert es aber auch mit dem clearbit() Makro
(zumindest bei meinem Board und Debugger).
Wenn du willst kann ich dir ein paar fertige Programme zukommen lassen,
die die CAN-Funktionalität ausnutzen...
Wenn du noch Fragen hast werde ich sie dir gerne beantworten.
Viele Grüße Marco
hallo zusammen,
mal vorweck:die bibliotek ist klasse und die dokumentation ist auch der
hit. habe versucht das bei mir einzubinden. hat leider nicht geklappt,
würde mich interressieren, wie ein hauptprogramm aussieht, bzw wie genau
ich das einzubinden habe, damit ich auf die bibliotek zugreifen kann.
danke und gruß von
timo
// Index des MOB ermitteln, der den Interrupt ausgelöst hat
47
uint8_tmob=CAN_getMOBInterrupt();
48
49
// Falls es kein gültiges MOB war abbrechen
50
if(mob==NOMOB){
51
return;
52
}
53
54
// Objekt das den Interrupt ausgelöst hat holen
55
CAN_getMOB(mob);
56
57
// Daten des MOBs aus CANMSG auslesen
58
message=CAN_getData();
59
60
// Id der Nachricht holen
61
message.id=CAN_getID();
62
63
64
//////////////////////////////////
65
// Daten verarbeiten / ausgeben //
66
//////////////////////////////////
67
68
// Hier verarbeitest du deine empfangenen Daten
69
// Wären deine LEDs auf Port A dann steuerst du sie so an
70
71
PORTA=message.data[0];// Nutzdaten aus 1. Byte verarbeiten
72
73
//////////////////////////////////
74
// Daten verarbeiten / ausgeben //
75
//////////////////////////////////
76
77
78
// RXOK-Flag löschen
79
clearbit(CANSTMOB,RXOK);
80
81
// MOB auf Empfang und CAN 2.0B Standard setzen
82
CAN_setMode(RECEIVE_DATA);
83
84
// CANPAGE wiederherstellen
85
CANPAGE=save_canpage;
86
}
Das ist jetzt eine Anregung wie man es machen kann. Du kannst natürlich
deinen Controller so programmieren, dass er sowohl senden als auch
empfangen kann.
Wie gesagt, ich habe im Moment keine Boards mehr um den Code zu testen.
Aber prinzipiell müsste es so gehen.
Falls etwas unklar ist oder du sonst noch Fragen hsat stehe ich dir
gerne weiter zur Verfügung
Viele Grüße
Marco
hi marco,
ja mensch, der perfekte formteilnehmer kann nur sagen. ich habs gestern
mal mit meinem eigenen hauptprogramm ausprobiert (sah so ähnlich aus wie
deins) und hat hingehauen. trozdem danke für die bespielhafte hilfe!!
ich werde immer mehr zum atmel fan.
Hallo Marco,
so, ich hab jetzt auch endlich mein CAN Board und konnte deine LIB
testen.
Das Senden hat auf Anhieb funktioniert. Ich habe auf der anderen Seite
des Busses eine CAN Box/XL mit CAN-OE hängen und der zeigt mir die
Nachricht auch richtig an.
Wenn ich allerdings Nachrichten empfangen möchte, klappt das irgendwie
nicht.
Ich habe in der Interruptroutine erstmal eine LED blinken lassen.
1
SIGNAL(SIG_CAN_INTERRUPT1){
2
uint8_tsave_canpage;
3
staticCAN_messagemessage;
4
5
// Aktuelle CANPAGE sichern
6
save_canpage=CANPAGE;
7
8
// Index des MOB ermitteln, der den Interrupt ausgelöst hat
9
uint8_tmob=CAN_getMOBInterrupt();
10
11
12
if(LED2)
13
LED2=0;
14
else
15
LED2=1;
16
...
Im main.c habe ich mit
1
CAN_messagemsg0,msg1;
2
CAN_init(83,RX);
3
msg1.idm=0xffffffff;// Es kommt nur genau dieselbe ID durch
4
msg1.id=0x0B;// Selbe ID wie im Sender
5
CAN_enableMOB(1,RECEIVE_DATA,msg1);// Muss der auch aktiviert werden?
Leider wird meiner Meinung nach der Interrupt gar nicht aktiviert.
Ich hab mal das ganze Projekt angehängt.
Mir ist nicht ganz klar, wie das mit dem Aktivieren von MOBs ist. So wie
ich das verstanden habe, definiere ich die Message, aktiviere den MOB
und kann dann diese Nachricht senden. Was ist denn, wenn ich mehrere
Nachrichte schicken will? Bzw. wie kann ich mehrere verschiedene
Nachrichten empfangen?
Vielleicht kannst du ja mal drüber schauen, wo da mein Denkfehler ist?
Danke schonmal
Werner
OK, den ersten "Fehler" hab ich gefunden.
Du hattest die extended ID aktiviert. Ich sende aber ein 2.0A
Identifier.
Das empfangen einer Nachricht klappt jetzt (den Inhalt hab ich noch
nicht betrachtet)
Allerdings habe ich festgestellt, dass bei msg0 jetzt die ID verloren
geht. Habt ihr mal probiert gleichzeitig zu senden und zu empfangen?
Danke schonmal
Werner
So,
jetzt gehts. Das Problem war noch, dass auch das Einstellen der ID und
der Maske an den Standart Identifier angepasst werden musste.
Hier der "universell" anwendbare Code:
Hi Leute,
bin ganz neu auf diesem Gebiet und habe mir natürlich auch die lib
runtergeladen...
die ist echt toll, die doku ist auch sehr ausführlich und leicht zu
durchblicken...
Trotzdem habe ich es nicht geschafft nachrichten zu empfangen...
ich habe irgendwie das gefühl, dass die Interrupts nicht gehen...
hat jemand mal einen funktional Code, womit ich es testen kann...?
Gruß
Hallo Marco,
sehr übersichtlich und gut programmiert, Habe nur noch eine Frage:
Du aktivierst den MOb mit RECEIVE_DATA obwohl du ihn versenden willst.
Funktioniert bei mir auch. Als ich es umstellen wollte auf TRANSMIT_DATA
wurde irgend etwas versendet nur nicht das was ich unter msg1.data
definiert hatte.
// Objekt 0 aktivieren und Daten übergeben
CAN_enableMOB(0, RECEIVE_DATA, msg1);
// Daten senden
CAN_sendData(0, msg1.data);
Hallo Leute,
ich hab die Bibliothek fuer meine Zwecke angepasst und will meine Arbeit
gerne wieder dem Autor und der Allgemeinheit zurueckgeben.
Veränderungen:
* Die Version ist deutlich entschlackt, was aber auch auf Kosten der
Kommentare geht. Aber auch an anderer Stelle liess sich gut Code
einsparen.
* Die Baudrate-Einstellung funktioniert nur noch bei 16 MHz. Wer eine
andere Taktrate fährt, muss sich die entsprechenden Zeilen Code aus der
ursprünglichen Version vom Marco kopieren.
* Es werden nicht nur extended IDs (mit 29-Bit-Identifier; CAN 2.0B)
unterstuetzt, sondern auch die mit nur 11-Bit (CAN 2.0A). Dazu habe ich
im Prinzip nur die Patches von Werner eingebaut.
* Es können Nachrichten mit variabler Länge verschickt werden.
* Die API hat sich etwas geaendert. Siehe auch Beispiel. Das war für
mein Projekt notwendig.
Hier ein Beispiel, um Daten mit variabler Laenge und extended ID zu
verschicken:
1
#include<avr/io.h>
2
#include<avr/interrupt.h>
3
#include<inttypes.h>
4
#include<stdbool.h>
5
6
#define F_CPU 16000000ULL
7
#include<util/delay.h>
8
9
#include"can.h"
10
11
voidsleep(uint32_ti)
12
{
13
while(i--)
14
_delay_ms(1);
15
}
16
17
18
intmain(void)
19
{
20
int8_tdata[8];
21
uint8_ti;
22
23
data[0]='H';
24
data[1]='i';
25
data[2]=' ';
26
data[3]='t';
27
data[4]='h';
28
data[5]='e';
29
data[6]='r';
30
data[7]='e';
31
32
// baudrate: 250K, keine Interrupts, extended Id
33
can_init(3,0,1);
34
35
// mob: 0, modus: senden, id 3, idm 0xffffffff
36
can_enable_mob(0,1,3,0xffffffff);
37
38
for(i=1;i<=8;i++)
39
{
40
sleep(1000);
41
can_send_data(0,i,data);
42
}
43
44
while(1);
45
46
return0;
47
}
Code, das Beispiel und Makefile sind angehaengt, so dass man eigentlich
(bei richtiger Taktfrequenz von 16MHz) gleich durchstarten kann.
Ich wuerde mich ueber Kommentare/Kritik freuen. An dieser Stelle nochmal
herzlichen Dank an Marco Glietsch fuer die urspruengliche Version und
seine sehr, sehr, sehr gute Dokumentation. :)
Hallo Michael,
dein Beispielprogramm hat sofort funktioniert, super....
gibts auch noch Beispiele für den Empfang bzw. gleichzeitiges Senden und
Empfangen? Ich hab damit Probleme, manchmal werden Messages nicht
korrekt
übertragen und der PCAN-Adapter zeigt Busfehler an.
Hallo Wolfgang,
ich hab die Bibliothek wieder etwas modifiziert. Nur die ganzen
enum-Konstanen in die Header-Datei verlagert, so dass man sie jetzt auch
in main.c nutzen kann. Es macht den Code wesentlich uebersichtlicher,
wenn man aussagekraeftige Konstanten wie z.B. CAN_BAUDRATE_250K
verwenden kann und nicht eine einfache Zahl wie 3.
Nun zu deinem Problem. Ich hab mom. nichts hier zum testen, hab aber die
main.c mit Beispielen erweitert, wie es eigentlich funktionieren sollte.
Wenn es nicht geht, dann ist es wahrscheinlich ein Bug. ;-)
Das Problem ist, dass ich mich auch erst seit ein paar Tagen mit dem
CAN-Bus befasse und daher durchaus noch Fehler schlummern koennte.
Probier es einfach mit den Beispielen aus und sag, was geht und was
nicht.
Ich habe mit der Bibliothek heute erfolgreich Senden, Empfangen und
automatische Antworten getestet. Allerdings immer nacheinander und nie
gleichzeitig. Muss ich am Montag mal genauer untersuchen.
Wenn ihr Fehler seht, dann sagt mir Bescheid. Danke! 2*n Augen für n>1
sehen eben einfach mehr als nur 2. ;-)
--Michael
Hallo Michael,
es freut mich, dass du die Bibliothek funktionell erweiterst.
Aber die Baudrate hättest du drin lassen können. Der Präprozessor sorgt
dafür, dass nur der zur Taktrate passende code compiliert wird.
F_CPU wird übrigens im AVR-Studio in den Projekteinstellungen
eingestellt und muss nicht extra im Quellcode angegeben werden.
Gruß Marco
Hallo Marco,
die Makros fuer die Baudrates habe ich rausgenommen, weil ich sie nicht
brauche und ich sie unuebersichtlich finde, weil sie so lang sind. Wenn
man etwas im Code sucht, dann stoert mich sowas und bei meinem Projekt
weiss ich, dass es nur mit 16MHz laeuft. Dass das nicht mit weniger
Belegung von Flash oder schnelleren Code zu tun hat, ist mir klar.
In der angehaengten Version hab ich es jedenfalls wieder angehangen,
weil es fuer andere vielleicht nuetzlich sein koennte.
Zu F_CPU im AVR-Studio kann ich nichts sagen. Ich nutze avr-gcc unter
Linux mit vim und wenn ich F_CPU nicht angebe, beschwert sich avr-gcc.
Ich lass mich aber gerne eines besseren belehren.
Kann es sein, dass man Autoreply und Empfangen nicht gleichzeitig fuer
zwei unterschiedliche MOBs nutzen kann oder ist im Code noch irgendwo
ein Fehler?
--Michael
Hallo Michael,
hab leider Probleme mit deiner neuen Version....
Senden funktioniert, aber beim Empfang tut sich überhaupt nichts...
Er springt nicht in die Interruptroutine, übrigens egal welche ID ich
benutze und die idm komplett öffne. PCAN zeigt auch weiterhin Busfehler
an....
Ich werde heute auch mal suchen, vielleicht entdecke ich etwas...
muß das bei Autoreplay nicht id 5 heißen?
Gruß Wolfgang
Hallo Michael,
ich hab entdeckt daß der Empfang funktioniert wenn man die
Interrupts global mit "sei" freigibt. Aber ich denke das ist doch nicht
richtig, denn die IR's des CAN-Controllers sind doch unabhängig davon,
oder nicht?
Hallo Wolfgang,
das globale Interrupt Flag (GIE) im Status Register muss mit sei()
gesetzt werden, da sonst überhaupt kein Interrupt bearbeitet wird. Im
CAN General Interrupt Register (CANGIT) werden dann die Interrupts für
den CAN-Controller freigegeben.
Gruß Marco
Hallo Marco,
danke für die Info, aber wann muß daß passieren?
Vor der CAN Initialisierung oder egal wann?
Ich hab einfach noch Probleme daß der Empfang mal geht, mal nicht.
Momentan kann ich nichts feststellen, es ist einfach wahllos wann....
Senden klappt komischerweise konstant immer...
Gruß Wolfgang
Hallo Wolfgang,
die Interrupts sollten aktiviert werden bevor du ein MOB in den
Empfangsmodus setzt. Somit wird sichergestellt, dass jede Nachricht
ankommt bzw. einen Interrupt auslöst. Würdest du zuerst dein MOB auf
Empfang setzen und dann die Interrupts aktivieren kann es passieren,
dass eine Nachricht zwischen diesen beiden Aktionen ankommt, die dann
aber keinen Interrupt auslöst und du nichts davon mitbekommst...
Gruß Marco
Hi Marco,
ich habe die Interrupts jetzt vorher aktiviert, und es läuft jetzt
zufriedenstellend.
Eine kleine Unschönheit habe ich durch Zufall gefunden, ich werde mal
versuchen sie zu beseitigen.
Wenn man
"can_enable_mob(0, CAN_MODE_TRANSMIT_DATA, 3, 0xfffffff);"
( stammt zwar von Michael, ist aber bei deiner Routine sehr ähnlich)
aufruft wird sofort ein 'Signal' auf den CAN-Bus gesendet, allerdings
mit null Datenlänge und demzufolge keinem Dateninhalt. Es wurde ja noch
nichts definiert.. Es hat keine Auswirkungen, sieht nur nicht gut aus.
Übrigens, bist du noch in KA?
Gruß Wolfgang
Hallo,
dass Datenpakete mit der Laenge 0 geschicht werden, ist mir auch
aufgefallen. Ich dachte allerdings, dass das von einem anderen Problem
kommt. Naemlich hatte ich das Problem, die Datenlaenge fuer die Pakete
richtig einzustellen (siehe auch Kommentar um Zeile 620 in can.c). Aber
gut zu wissen, ich werde mir das mal genauer anschauen.
Ich habe noch eine Frage zum Auto-Reply: Ist es normal, dass nur auf das
erste Remote-Frame ein Auto-Reply geschickt wird und danach nicht mehr?
Ich weiss noch nicht, ob dass ein Bug ist oder nicht. ;-)
Ich schau dann auch mal, dass ich funktionierende Beispiele anhaenge.
Die Beispiele mom. sind ja alle ungetestet und nur schnell
zusammengeschustert, damit man sich vorstellen kann, wie es
funktionieren sollte.
Gruss.
--Michael
Hallo an alle,
ich bin etwas weiter gekommen.....
Die Nachrichten mit Datenlänge 0 werden durch setbit(CANCDMOB, CONMOD0)
in
der Funktion can_set_mode ausgelöst.
Ich vermute mal der der Ablauf irgendwie noch nicht korrekt ist, da beim
Enable des Mob normalerweise kein Senden ausgelöst werden darf.....
Ich habe bei einem anderen Projekt die Atmel-Beispiele verwendet, da war
das nicht der Fall, also muß es auch funktionieren. Leider hab ich erst
morgen Abend wieder Zeit mich darum zu kümmern, vielleicht ist jemand
schneller.... :-)
Die Frage mit dem Auto-Replay kann ich nicht beantworten, ich hab diese
Funktion bisher nicht verwendet und so lange beschäftige ich mich noch
nicht mit dem CAN-Bus. Ich stecke da auch noch in den Anfängen...
Gruß Wolfgang
Hi Marco,
ich wohne direkt nebenan...., deswegen die Frage.
Ich habe leider nur etwas weiter machen können an dem Problem des
Sendens bei Can_send_mode mit Null Datenlänge. Die erste Initialisierung
mit CAN_enablemob ist beim Senden nicht notwendig, es werden trotzdem
die Daten gesendet.
Man könnte demzufolge Can_set_mode aus Can_enablemob weglassen, bräuchte
dann aber eine zweite Funktion alleine für das setzen des Filters und
der ID, den die beiden müßen ja initialisiert werden.
Wenn ich die nächsten Tage dazu komme werde ich es mal entsprechend
probieren.....
Grüße Wolfgang
Hallo an alle,
hab mir von Marco die CAN-Bibliothek angeschaut und stoße auf ein
Problem das ich nach langem nicht allen lösen kann.
Habe zwei Knoten an dem Can-bus sowie einen USB-Can-Sniffer von PEAK.
Wenn ich vom PEAK aus eine Nachricht auf den BUS schicke sollte es wie
folgt ablaufen.
Beide Knoten sollen mir mit verschiedenen ID Antworten. Erste der mit
der höheren Priorität dann der mit der niedrigen. Wenn ich bei einem ein
delay einbau funktioniert das tadellos.
Problem:
1.
Wenn ich einen RESET von den Knoten mache und über den PEAK eine
Nachricht versende, bekomme ich gleich von jedem Knoten 2 zurück.....?
wie kommt’s....?
2.
Wenn ich eine weitere Nachricht vom PEAK sende, bekomme ich von der
höheren Priorität ID eine Nachricht zurück......soweit schön....das
klappt auch immer.
Jedoch bekomme ich von dem 2ten Knoten beim 2ten Senden keine Nachricht
und beim 3ten Senden gleich 2 zurück....das geschieht alternierend.
Habe im Projekt bei den Mops für beide Knoten lediglich die ID geändert.
Das die nicht auf der gleichen ID Antworten....
Würde mich um eine Lösung SUPER freuen.
Gruß Arno
Hat jemand mal ein fertiges und übersichtliches beispiel wo daten
zwischen zwei Controllern per CAN hin und her gesendet werden?
Ich versuche mich nun schon seit ein paar tagen mit dieser Bibliothek
aber bekomme ganz und gar keine funktion hin.
Ob die Daten gesendet sind überprüfe ich mit der UART schnittstelle
ich hoffe mir kann jemand helfen.
Im fall ihr habt eine bessere Bibliothek so würde ich auch die nehmen.
hauptsache es funktioniert und die Lib ist gut zu verstehen.
Danke Martin
ja hab ich aber die ist nicht wirklich so gut.
ich suche eigentich auch eher mehr ein beispiel füe einen empfänger und
einen sender...
aber danke für die hilfe ;-)
Hallo wir veruschen hier gerade die Message "Blinken" von einer S-Klasse
auszulesen. Haben einen Modelaufbau mit 2 Steuergeräten und CANOE. Der
CAN läuft die Initaliesrung des MC funktioniert auch. Allerdings springt
er nicht in den Interrupt, was er tun sollte sobald eine Message
empfangen wurde. könnt ihr uns vielleicht irgendwie weiterhelfen z.b was
hierbei typische Fehlerquellen sind?
dankeschön
typische fehlerquellen sind die globalen interuppts einfach mal sei();
ausführen um die interrupptabfrage zu starten.
ich habe allerdings ein anderes problem mit dieser bibliothek... das
senden und empfangen funktioniert. leider sendet er aber nur einmal.
obwohl ich das senden innerhalb der endlosschleife habe. falls einer da
ne idee hat worann es liegen könnte wäre ich sehr verbunden. ich habe
auch noch mal mein komplettes C-Programm mit source datein angehängt. in
diesem fall das für knoten 1.
ich glaube das mein problem ist das can_send_data auf das TXOK wartet es
aber nie bekommt. ich schließe das auch bei mir das clearbit nicht
funktioniert wie bereits von Gerhard (Gast) am 04.05.2008 19:30 gepostet
wurde. gibt es eine möglichkeit das bit anders zu setzen beziehungsweise
zu übergeben? ansonsten klappt eigentlich alles perfekt. aslo schon mal
danke für die routine.
sobalt ich die txok abfrage in der can_send_data und das clearbit rxok
im empfangsinterrupt entferne sendet mein system reibungslos. bei
geschalteter abfrage des txok hängt sich der sende controller an der
stelle auf. ich habe auch überbrüft ob es ein bitfehler ist der zu einem
bus-off führt, dem ist nicht so, da der sender fleißig weiter sendet
ohne irgendwann abgeschaltet zu werden. hatte jemand bereits dasselbe
problem und kann mir helfen?
Mit dem Stand bis zum 11.03.2009 haben wir die CAN-Lib überarbeitet und
Fehler und Unschönheiten korrigiert.
Haben die Lib in einem System mit drei gleichen AT90CAN128 eingesetzt
und die Kommunikation mit einem CANAlyzer verifiziert.
Durch senden eines Zeichens über den UART wird abhängig vom Zeichen eine
unterschiedliches CAN-Message versendet.
Auto-Reply und Remote-Frames sind ebenfalls eingerichtet und getestet.
Wird wohl noch nicht ganz perfekt sein, stellt aber einen ganz guten
Stand dar. g
Wir wünschen viel Erfolg mit weiterer Verwendung...
Grüße
MatMar
Hallo
Im Anhang: meine Send-Remote-Funktion.
Und in meiner main-Funktion eine while-Schleife mit folgendem Inhalt:
1
while(1)
2
{
3
can_send_remote(0,8);
4
led_blinken();
5
// Die LEDs blinken, damit ich weiß, wann die Schleife zu Ende ist...
6
}
Komsicherweise sendet er mir beim einen Durchgang den Remote-Request wie
gewünscht.
Beim nächsten Durchgang sendet er mir ein Daten-Frame.
Und dann wieder Remote, dann Data, ....
Ich komm einfach nicht dahinter warum das so ist.
Ich will eigentlich nur den Remote-Request.
Könnt ihr mir weiterhelfen????
VIelen dank !!
Gruß
Nob Ge. schrieb:
> Hallo>> Im Anhang: meine Send-Remote-Funktion.> Und in meiner main-Funktion eine while-Schleife mit folgendem Inhalt:>
1
>while(1)
2
>{
3
>can_send_remote(0,8);
4
>led_blinken();
5
>// Die LEDs blinken, damit ich weiß, wann die Schleife zu Ende ist...
6
>}
>> Komsicherweise sendet er mir beim einen Durchgang den Remote-Request wie> gewünscht.> Beim nächsten Durchgang sendet er mir ein Daten-Frame.> Und dann wieder Remote, dann Data, ....>> Ich komm einfach nicht dahinter warum das so ist.> Ich will eigentlich nur den Remote-Request.>> Könnt ihr mir weiterhelfen????> VIelen dank !!> Gruß
Habe jetzt doch noch die Antwort gefunden:
Die Reihenfolge der Flags beim Setzen des Modus ist entscheidend..
Verdammt und jetzt erst schau ich in die "CAN-Lib.rar".. da stehts ja
auch drin...
Naja
Gute nacht ;-)
Jetzt habe ich doch noch eine Frage:
Im Datenblatt steht doch:
Das RTRTAG und das RPVL-Tag werden im Auto-Reply Modus automatisch
zurückgestellt.
--> Somit wird 1x die Auto-Reply Funktion ausgeführt.
Wie macht man es jetzt am besten, dass beim nächsten mal (wenn ein
Remote-Request "angefragt" wird), dieser RTR-TAG und RPVL-Tag wieder
gesetzt ist?
Gibts da ne besonders clevere Lösung? Geht das denn nicht automatisch??
Weil bis jetzt mache ich es immer so, dass ich am Anfang der
while-Schleife wieder den MOb explizit "initialisiere" und dabei den
Auto-Reply-Modus setze.. Ich finde diese Methode aber nicht besonders
gelungen !!!!
Vielen Dank für Anregungen und Antworten :-)
Gruß
Nob Ge. schrieb:
> Im Datenblatt steht doch:> Das RTRTAG und das RPVL-Tag werden im Auto-Reply Modus automatisch> zurückgestellt.
Das ist auch korrekt so. Diese müssen explizit wieder gesetzt werden,
wenn ich das richtig in Erinnerung habe.
Du stellt damit quasi explizit nur ein Frame bereit, wenn beispielsweise
neue Daten zum Versenden bereit sind. Wieso auch gleiche Infos immer
wieder versenden...
Wir hatten das so gemacht, dass wir nen Sensor abgefragt hatten und wenn
sich dessen Zustand geändert hat, haben wir das Auto-Reply CAN_message
Objekt
mit neuen Daten befüllt und danach die Funktion CAN_enableMOB()
aufgerufen. Die anderen Mikrocontroller haben zyklisch Auto-Reply
messages versendet und ne entsprechende Antwort erhalten, wenn sich was
getan hat.
Weitere Anregungen habe ich leider grade nicht.
Hoffe, ich konnte helfen.
Grüße,
ein Teil von MatMar ;)
Hallo MatMar !!
Vielen Dank für die Antwort.
Das hilft mir sehr weiter.
Hatte bis jetzt leider keinen Kontakt mit Autp-Reply und
Remote-Requests, deswegen wusste ich nicht, wie das "normalerweise" so
gehandelt wird.
Vielen Dank nochmal!
Schöne Weihnachten !!
Hallo euch allen,
ich bin schon seit einiger Zeit auf der Suche nach einem CAN-Bootlader
für den AT90CAN. Leider konnte ich dazu aber kein fertiges Projekt
finden.
Genauere Informationen gibt es unter fogendem Link:
Titel - Beitrag "CAN BUS Bootloader AT90CAN"
Ich hoffe es finden sich einige um dieses Projekt zu realisieren oder
die dabei helfen können.
Grüße martin
Hallo zusammen...
Ich verzweifel gerade! Nachdem mein Treiber für den AT90CAn nicht
funktioniert habe ich jetzt schon 5 andere die funktionieren sollen
getestet. Es klappt mit keinem.
Mit dem Oszi bin ich dem ganzen mal etwas näher gekommen. Sobald ich ein
MOb aktiviere hab ich auf dem Can ein unidentifizierbares Störsignal was
meine bisher eingesetzten MCP2515 komplett taub macht. Also sprich das
ganze Can Netzwerk bricht zusammen sobald ich beim AT90CAn ein MOb
aktiviere.
Hat jemand eine Idee was falsch sein könnte? extrem verzweifelt ist
Versuch mal die Lib von Fabian Greif.
Habe ich sowohl für den AT90CAN128 als auch SJA1000 genommen.
Funktioniert superklasse.
Das schöne daran ist, dass man sein Hauptprogramm unverändert lassen
kann und nur die entsprechenden Routinen entweder für den MCP2515,
SJA1000 oder AT90CAN128 dazu compiliert.
Auf der Homepage ist auch eine ausführliche Anleitung bzgl. Filter. Dies
wär nämlich ein Problem von mir.
Grüße
Andreas
Die Hab ich auch schon probiert... Ich werd wohl einfach nochmal 10 Euro
investieren und ein neuen AT90CAN128 kaufen. Ich ermute einfach das der
innen drin kaputt ist. Leiterbahnen hab ich alle geprüft. Das isses ned.
Hat jemand evtl. mal ein hex-file womit ich das bei mir testen kann? Es
langt wenn das Programm 1:1 den ankommenden Datenstrom per UART ausgibt.
(Verwende den UART Port 1, NICHT den 0er)
Meine MCP2515 haben die Baudrate auf 125kbit
(Glaub ich zumindest - Zur Kontrolle hier meine Einstellungen)
write_Reg_MCP2515(CNF3, (1<<PHSEG21));
write_Reg_MCP2515(CNF2, (1<<BTLMODE)|(1<<PHSEG11));
write_Reg_MCP2515(CNF1, (1<<BRP2)|(1<<BRP1)|(1<<BRP0));
Hat da jemand mal was parat? :)
Ich habe mal ne anmerkung zur Dokumentation.
Hast du schon mal was von Doxygen gehört?
Das ist ein Werkzeug zur Automatisierten Code Dokumentation. Dabei wird
dein Code und zusätliche die Dokuzeilen (welche sich im Code befinden)
analysiert und daraus eine sehr gute Code Doku erstellt.
Dabei können verschiedene Ausgabe Vormate erstellt werden. unter anderem
HTML und LaTeX.
Der Grund warumn ich das erwähne ist der das die Doku Köpfe zu den
Funktionen schon genauso aufgebaut sind wie es in Doxygen gern gemacht
wird, eben nur die entsprechenden Befehlswörter fehlen.
Man spart sich mit Doxygen einen Haufen Arbeit weil der Code nicht zwei
mal dokummentiert werden musss.
Hallo Tobias,
Doxygen ist mir sehr wohl ein Begriff. Für andere Projekte habe ich es
auch schon eingesetzt. Daher auch die Strukturierung der Kommentare in
diesem Programmcode.
Für dieses Projekt habe ich aber auf Doxygen verzichtet.
Hallo,
ich versuche z.Z. meine PC über eine Vector Karte (CANcaseXL) mit der
AT90CANx zu kommunizieren. Meine Frage: Kann man direkt das CAN Kabel an
den AT90CANx anschließen? oder braucht man noch ein Inteface zwischen
Vector und der AT90CANx?. Das ist nämlich, was nirgendwo erwähnt wird,
und für einen Anfänger wie ich ist das noch unklar.
Falls diese Interface gebraucht wird, hat vielleicht jemand eine
Schaltung?
Ich danke für alle Antworten.
Abel
(Grüsse aus Bolivien)
Hallo zusammen!
Ich habe ein Problem mit dem Auto-Reply-Mode. Auf eine RTR Msg mit der
ID 0x099 soll folgende Antwort kommen: ID=0x099, DLC=2, DATA[0]=0x12 und
DATA[1]=0x34.
Das passiert auch, allerdings erhalte ich noch eine zweite Msg:
ID=0x099, DLC=0.
Sprich auf jede RTR-Msg erhalte ich zwei CAN-Nachrichten zurück. Einmal
die Richtige und eine Leere.
Ich habe meine CAN.C mit dem letzten Stand hier aus dem Forum
abgeglichen und auch schon komplett getauscht, aber beides liefert das
gleiche Resultat. Hat jemand eine Idee woran das liegen könnte?
Ich setze das Auto-Reply Mob in der Endlosschleife immer wieder neu:
Hallo,
ich habe ein Problem beim senden einer CAN Nachricht.
und zwar läuft sich mein Prgramm immer in dieser while -Schleife fest!
while (!getbit(CANSTMOB, TXOK));
währe sehr dankbar für eine Hilfestellung.
Danke
Hi,
für mich hat sich das Problem mehr oder weniger erledigt. Du brauchst
neben dem Sender, mindestens einen Empfänger, sonst kommt es du dem
beschriebenen Problem.
Mein nächstes Problem ist allerdings das der Interrupt
"SIG_CAN_INTERRUPT1" nicht beim Empfänger aufgerufen wird, sondern in
einer Endlosschleife beim Sender. Aus "/usr/avr/include/avr/iocanxx.h":
/* CAN Transfer Complete or Error */
#define CANIT_vect _VECTOR(18)
#define SIG_CAN_INTERRUPT1 _VECTOR(18)
Da der Interrupt immer wieder beim Sender aufgerufen wird, geh ich mal
davon aus das beim senden etwas schief läuft ... bin noch an der
Fehlersuche.
@Tobias
Ich konnte meine Probleme (siehe oben) lösen. Dein Problem dürfte sein
das in der Funktion "CAN_setInterrupt" der TXOK Interrupt aktiviert
wird. Dadurch ergibt sich folgende Situation:
"CAN_sendData" sendet die Daten und wartet danach darauf das das "TXOK"
Bit gesetzt wird. Da der TXOK Interrupt aktiv ist, wird beim setzen
dieses Bits der Interrupt "SIG_CAN_INTERRUPT1" aufgerufen. Jetzt gibt es
zwei Möglichkeiten:
1) Das Bit TXOK wird innerhalb der Interrupt-Behandlungsroutine nicht
zurückgesetzt (so wie in der aktuellen Implementierung). In dem Fall
wird der Interrupt immer und immer wieder aufgerufen, die Funktion
"CAN_sendData" wird nicht weiter ausgeführt (hat also auch keine
Möglichkeit zu prüfen ob das TXOK Bit gesetzt ist).
2) Das Bit TXOK wird innerhalb der Interrupt Behandlungsroutine
zurückgesetzt. In diesem Fall wird die Funktion "CAN_sendData" zwar
weiterausgeführt, da das TXOK-Bit aber innerhalb der ISR zurückgesetzt
wurde bleibt diese in der Schleife "while(!getbit(CANSTMOB, TXOK))"
stecken.
Lösung:
In der Funktion "CAN_setInterrupt" den TXOK Interrupt NICHT aktivieren:
int CAN_setInterrupt(uint8_t mode)
{
switch(mode)
{
[...]
case TX:
setbit(CANGIE, ENIT);
clearbit(CANGIE, ENRX);
ALT: setbit(CANGIE, ENTX);
NEU: // setbit(CANGIE, ENTX);
return 1;
[...]
Hallo Leute,
ich habe die Bib von Marco gelesen und habe mich für meine Arbeit
orientiert.Ich muss die Kommunikation zwischen PC und AT90CAN128 mitteln
den Protokoll CANopen(MicroCANopen)Realisieren.die Node_ID muss mitteln
7-DIP-Schalter ( ist am PORT C den) und Baudrate mit 4-DIP-Schalter(PORT
A) eingestellt werden.kann biztte Jemand tip geben wie ich das mache
kann. Am ende muss in der lage sein mitteln den Schalter Node_ID und
Baudrate ändern können.
MFG
Danke
Hallo patnze,
du driftest etwas vom ursprünglichen Thema ab! Ich gebe dir aber gern
ein kleinen Denkanstoß, wie du dein DIP-Schalter Problem lösen kannst:
// ...wie das Senden und Empfangen funktioniert, hat Marco ja bereits gut beschrieben!
55
// Dann kannst du ja einfach dein CANopen Protokoll umsetzen :)
56
}
Ich hab das gerade mal kurz im Editor runtergetippt, kann daher nicht
sagen, obs komplett fehlerfrei ist, aber es geht ja vielmehr um einen
möglichen Lösungsansatz!
Bei weiteren Fragen oder Problemen mit OpenCAN, die nicht Marcos CAN-Bib
betreffen, würde ich dir den Rat geben einen Thread aufzumachen!
Gruß,
Sven
Hallo,
ich wollte man ein test Programm schreiben um mein Board die
DIP-Schalter testen zu können.wollte vom Schalter in PORT A ein LED in
PORTB anschalten.das Programm sieht aus:
#include <avr/io.h>
#include <avr/interrupt.h>
#include <util/delay.h>
#include <inttypes.h>
#include <stdbool.h>
int main (void) {
DDRA = 0x00;
PORTA = 0xFF;
DDRB = 0xFF;
PORTB = 0xFF;
while(1) {
if(PINA &(1 <<PINA0)){
_delay_ms(100);
PORTB=PORTB|(1<<PB5);
}
else
{
_delay_ms(100);
PORTB &= ~(1<<PB5);
}
}
return 0;
}
Beim kompieleren bringt keine Fehler aus aber es passiert einfach
nichts.
kann Jemand mir sagen wo das Problem ist oder einfach ein andere
beispiel oder tips geben.danke.
mfg
Hallo Zusammen,
kann mir jemand den Code von CAN_Test erklären, was da passiert?? Wäre
super nett..............................
Ausserdem würde ich gerne verstehen, warum das Programm nicht in die ISR
springt? Versteh ich net......................
Kann man die Daten auch über TXCAN die Daten schicken bzw. wohin gehen
die versendten Daten??
Grüße und vielen Dank........
Hallo zusammen,
hat schon mal Jemand die Bibliothek mit dem Display3000 Modul ans laufen
bekommen?
At90CAN128 mit PCA82C250
Kompilieren klappt aber bekomme keine Nachricht mit egal welchen
Testdemos die ich hier schon gefunden habe, über den Bus raus.
Logge mit dem Canalyzer, aber es tut sich nichts?!
Grüße
Hello alle,
Dieses Bericht ist für mich als CAN neuling sehr nutzvoll.
Aber eine Frage habe ich: Wo wird der CRC geschrieben. Ich siehe kein
CRC Berechnung in der Code....oder habe ich was üversehen?
BD
Hi,
ich sitze gerade daran die vorhandene Bibliothek auf meine Bedürfnisse
anzupassen.
In der Funktion "CAN_getMOBINTERRUPT()" stoße auf ein Problem.
Die Abbruchbedingung in der for-schleife verstehe ich nicht. Ich gehe
davon aus, dass in der Variable "maske" nur ein Bit = 1 ist. Somit
müsste doch die Abbruchbedingung "(maske & 0x01)==1" heißen, damit man
den richtigen "mob" rauszieht, oder? Meinem verständnis nach, bricht die
schleife ab, sobald eine "0" an der ersten stelle der "maske" ist ->
quasi sofort.
uint8_t CAN_getMOBInterrupt()
{
uint8_t mob;
uint16_t maske;
maske = (((uint16_t)CANSIT1) << 8) | CANSIT2;
// Wenn alle 32 Bit der Bitmaske 0 sind dann ist ein Fehler
aufgetreten
if(maske == 0)
{
return NOMOB;
}
// Die Bitmaske wird so lange nach rechts geschoben, bis Bit0 eine 1
hat.
// Die Anzahl der Schiebeoperatoren gibt somit die Nummer
// Des MOBs zurück
for( mob=0; (maske & 0x01)==0; maske >>= 1, ++mob);
// Kontrolle: Wenn mob größer als die Anzahl der verfügbaren
// Message Objects ist das Ergebnis falsch
if ( mob > 14 )
{
return NOMOB;
}
else
{
return mob;
}
}
Für nen kleinen Tip wäre ich dankbar!
Grüße,
Sven
hallo,
ich habe die lib eingebunden, sehr übersichtlich und gut dokumentiert
hut ab :-)
habe ein programm(main) entwickelt, wobei ein sender realisiert werden
soll. dazu hab ich das oben stehende beispiel genommen. nun wird aber
beim can send gewartet das die nachricht vollständig versendet wurde
(TXOK)... leider tut sich da sonst garnichts. mit dem tipp von sinotech,
den txok interrupt deaktivieren hatte ich leider auch keinen erfolg :(
verwenden tue ich das avr-can entwicklerboard von olimex mit fertigen
at90can128 und mcp2551 drauf. am sub-d liegen saubere 2,5V an, jedoch
ist keine kommunikation festzustellen.
ich hoffe mir kann jemand vllt helfen
danke im voraus
liebe grüße
ps: verbesserungsvorschlag:
can.c benötigt einen include von can.h
und im header file sollten headerguards also ifndef zb benutzt werden um
compilierungsfehler zu vermeiden(das war auch eins meiner
anfangsprobleme)
Hallo,
mit der CAN-Lib.rar kann ich ja anhand des RS232 Schnittstelle mein
Datentransfer beobachten und auch was senden können?
Wenn ich das richtig verstanden habe, sollte ich mit "b" oder "B" eine
Nachricht an Modul B mit der Message ID 0x316 senden?
Wenn ich das Programm starte erscheint auf dem Hyperterminal
"Controller A online, yes we CAN........und der Compilier-Datum usw. "
was ja auch alles richtig ist, aber Senden mit dem Hyperterminal
funktioniert nicht.
Ich logge mit dem Peak Dongle mit und bekomme keine CAN Nachricht?
CAN-Baustein ist aber "wieder" 100% in Ordnung und funktioniert.
Kann mir da Jemand weiter helfen?
Grüße
Ich habe noch immer das Problem zwischen dem AT90CAN128 und dem MCP2515
das sobald der AT90CAN128 aktiv geht das Netzwerk der funktionierenden
MCP2515-er zusammenbricht...
Hat jemand eine Idee woran es liegen könnte?
Ich wage mich auch an ein CAN Projekt. Durch diesen Thread spare ich mir
sehr viel Zeit.
Nochmal ein Dankeschön an Marco Glietsch und alle Leute die diese
Bibliothek optimiert und verbessert haben.
Ich finde das Klasse von euch! Gute Arbeit!
Beste Grüsse
Dominik
@Tim R.
ich hatte das selbe Problem und habe es mit einem Timeout und einem Flag
für den Timeout gelöst.
.
.
.
// Warten bis die Datenübertragung beendet ist (TXOK-Flag von
CAN-Controller
// gesetzt)
Timeout(0, 1, 50);
//while (!getbit(CANSTMOB, TXOK));
while(Timeout(0, 0, 50) == 0)
{
if (!getbit(CANSTMOB, TXOK))
{
CAN_ERR = 1;
}
else
{
CAN_ERR = 0;
break;
}
}//end while
// TXOK-Flag von Hand löschen
clearbit(CANSTMOB, TXOK);
.
.
.
/*********** TIMEOUT
************************************************************************
*********************************/
uint8_t Timeout (uint8_t timeout_array, uint8_t set_Timeout, uint16_t
Timeout)
{
if (set_Timeout == 1)
{
tmp_systemtime[timeout_array] = systemtime;
}//end if
if (systemtime >= (tmp_systemtime[timeout_array] + Timeout)) //An
Funktion "1" zurückgeben, wenn Timeout erreicht wurde
{
return 1;
}//end if
else //(millisekunden < Timeout_erreicht) //An Funktion "0"
zurückgeben, wenn Timeout nicht erreicht wurde
{
return 0;
}//end else
}//end Timeout
Anbei noch ein paar Bugfixes um mehrere, gleichzeitig ausgelöste RX IRQ
MOBS zu handeln (bisher wurde immer nur das höchst priorisierte MOB
behandelt):
//Anzahl der ausgelösten MOB IRQ's ermitteln
uint8_t get_mob_irqs(void)
{
uint8_t n, mobirqs;
uint16_t bitpos, mobirqreg;
bitpos = 1;
mobirqs = 0;
mobirqreg = CANSIT2 | (uint16_t)(CANSIT1<<8);
//Anzahl der ausgelösten MOB IRQ's ermitteln
for (n=0; n<15; n++)
{
bitpos<<=1;
if ((mobirqreg & bitpos) == bitpos) mobirqs++;
}//end Anzahl der ausgelösten MOB IRQ's ermitteln
return mobirqs;
}
// Rückgabe: uint8_t mob: Nummer des Objekts
// Funktion ermittelt, welches Objekt Interrupt ausgeloest hat
uint8_t can_get_mob_interrupt(uint8_t lastmob)
{
uint8_t mob, n;
uint16_t maske, filter_maske;
maske = CANSIT2 | (uint16_t)(CANSIT1 << 8);
filter_maske = 1;
//Filtermaske erstellen, um das vorhergegangene MOB nicht erneut
abzurufen
for(n=0; n<lastmob; ++n)
{
filter_maske <<= 1;
}
//Vorheriges ausgelöstes MOB löschen
maske &=~filter_maske;
// Wenn alle 32 Bit der Bitmaske 0 sind dann ist ein Fehler
aufgetreten
if(maske == 0)
{
return NOMOB;
}
// Die Bitmaske wird so lange nach rechts geschoben, bis Bit0 eine 1
hat.
// Die Anzahl der Schiebeoperatoren gibt somit die Nummer des MOBs
zurück
for(mob=0; (maske & 0x01)==0; maske >>= 1, ++mob);
//Prüfen, ob das
// Kontrolle: Wenn mob größer als die Anzahl der verfügbaren
// Message Objects ist das Ergebnis falsch
if(mob > 14)
{
return NOMOB;
}
return mob;
}
// Interrupt für Empfang einer Nachricht
ISR (CANIT_vect)
{
uint8_t save_canpage, n, i, cnt_mobirq, mob, lastmob;
// Aktuelle CANPAGE sichern
save_canpage = CANPAGE;
lastmob = 0;
// Index aller MOB ermitteln, welche den Interrupt ausgelöst haben
cnt_mobirq = get_mob_irqs();
// MOB Daten holen und abspeichern
for(n=0; n<=cnt_mobirq; n++)
{
mob = can_get_mob_interrupt(lastmob);
// Falls es kein gültiges MOB war, Daten holen abbrechen
if(mob != NOMOB)
{
// Objekt das den Interrupt ausgelöst hat holen
can_get_mob(mob);
// XXX hier eintragen, was bei einem interrupt passieren soll XXX
// Id der Nachricht holen und Daten des MOBs aus CANMSG auslesen
//id = can_get_id();
can_get_data(receive_can);
//Daten aus aktuellem MOB
for (i = 0; i < 8; i++)
{ /* 15 Zeilen, 8 Spalten */
can_byte_by_mob[mob][i] = receive_can[i];
//Daten aus RX MOB in can byte schreiben
}//end send_can füllen
}//end Falls es kein gültiges MOB war, Daten holen abbrechen
lastmob = mob;
//Ausgelesenes MOB updaten
}//MOB Daten holen und abspeichern
// RXOK-Flag löschen
clearbit(CANSTMOB, RXOK);
// MOB auf Empfang und CAN 2.0B Standard setzen
can_set_mode(CAN_MODE_RECEIVE_DATA);
// CANPAGE wiederherstellen
CANPAGE = save_canpage;
//IRQ_CAN_RX = 1;
}//end CAN_Interrupt handle
Zudem war im Modul disable MOB noch ein kleiner Fehler, hier die
Korrektur:
// Parameter: uint8_t mob: Nummer des Objekts (0-14)
// Funktion löscht den Interrupt für das jeweilige Objekt
void can_clear_mob_interrupt(uint8_t mob)
{
if (mob < 8) { clearbit(CANIE2, iemob[mob]); }
else { clearbit(CANIE1, iemob[mob]); }
}
Hallo Miteinander!
Ich bin soeben zu folgendem Ergebnis gekommen. Ich habe Marco Glietsch's
Bibliothek auf verschiedenen IDE's getestet.
AVR-Studio 5.0 -> mit Erfolg CAN Nachrichten senden/empfangen
AVR-Studio 5.1 -> ohne Erfolg keine CAN Nachrichten senden/empfangen
AVR-Studion 6 -> ohne Erfolg keine CAN Nachrichten senden/empfangen
Ich habe dieses Bibliothek 1 zu 1 in den jeweiligen Studio's kompilieren
lassen und die Hex-File übertragen (JTAGICE mkII).
Die Übersetzung erfolgt bei allen IDE's ohne Probleme nur nach dem
übertragen auf den AT90CAN64 kommt es zu dem o.g. Ergebnis.
Kann von Euch dieses Problem noch jemand bestätigen. Wenn ja, dann
sollte man dies als BUG weitermelden.
Besten Dank im Voraus für die Antworten!
Gruß
Hallo Schorsch,
ich konnte bisher mit allen AT-Studios meine gemoddete CAN-lib
compilieren.
Ich hatte nur das Prob, dass mein JTAG ICE 3 nicht so richtig wollte (is
immer ab einer gewissen Stelle im Run-Mode geblieben).
Anbei mal meine libs.
Viele Grüße
Hallo,
wir benutzen die Bibliothek von Marco Glietsch und wollten diese mit der
standart ID (11 bit 2.0a) verwenden. Mit den Patches von Werner A sind
wir leider nicht weiter gekommen. Der At90can128 (in Kombination mit PCA
82C250) sendet immer noch mit der extended ID (29 bit).
Hat jemand eine fertige lib für die standart ID?
Über Hilfe würden wir uns sehr freuen,
viele Grüße
Guten Tag
@garphi
Ich würde gerne deine gemoddete Lib testen...
jedoch sagt der compiler das folgende h. fehlen
#include "Globals.h"
#include "Timer.h"
sind diese wichtig für das programm?!
ich habe folgende Problem:
das versenden von Datensätze zwischen µC (A) und µC (B) funktioniern
ganz gut, sobald ich eine 3. µC (C) dazu schalte, bricht die
kominiklation zwischen A und B ab. sobald ich das C ausschalte steht die
kominikation wieder da.
Hallo garphi,
vielen Dank für Deine Antwort (03.08.12) und Deiner Library. Ich hätte
noch eine Bitte an Dich.
Könntest Du bitte noch die "Global.h" und Deine "Timer.h" mit zur
ZIP-Datei anfügen.
Besten Dank im Voraus!
Gruß
Hi Schorsch,
die Global.h brauchst du nicht da sollte nichts drin sein was für die
lib wichtig ist. So wie ich das sehe wird nur das array
uint8_t can_byte_by_mob[15][8];
benutzt.
in der Timer.h ist die Funktion timeout und rx_timeout
kan man sich sehr einfach nachbauen.
z.B.
/***********************************************************************
*/
/* tiemerNum ist die Position im array für die Softtimer
*/
/* timeout ist der einzuhaltende Timeout (abhängig von mscounter)
*/
/* wenn die Variable Timeout einen Wert größer 0 hat wird dieser zum
*/
/* laden des timers genutzt bei Wert = 0 wird abgetragt
*/
/* millis ist ein Variable die in der Timer0 ISR hochgezählt wird
*/
/***********************************************************************
*/
bool timeout (uint8_t timerNum, uint16_t Timeout)
{
static uint64_t timeout_array[NO_MOBS];
if (Timeout != 0)
{
timeout_array[timerNum] = Timeout + millis;
return false;
}
else if (timeout_array[timerNum] > millis)
{
return false;
}
else
{
return true;
}
}//end Timeout
in der ISR für Can Nachrichten wird die Schleife:
---
// MOB Daten holen und abspeichern
for(n=0; n <= cnt_mobirq; n++)
---
zu oft durchlaufen da muss ein < hin, denke ich.
In den can_send_data sollte noch ein Parameter für die id mit drin sein,
würde es schlanker machen. Diese ID muss alldrings genauso wie der mode
wieder hergestellt werden.
Meine Version:
Autor: garphi (Gast)
Datum: 03.08.2012 14:07
VG Thomas
Hallo zusammen
kann mir jemand helfen?
Habe aktuell 2 Probleme einmal sendet mein Board immer eine leere und
eine richte Botschaft. Hatte ich weiter oben schon gelesen hat aber
nicht funktioniert.
So sende ich die Daten:
can_init(4, 0, 0);
can_enable_mob(0, 1, 0x70E, 0xffffffff);
sleep(1000);
can_send_data(0, 8, data);
Wenn ich die beiden letzten Zeilen umdrehe kommen zwei leere Botschaften
can_init(4, 0, 0);
can_enable_mob(0, 1, 0x70E, 0xffffffff);
can_send_data(0, 8, data);
sleep(1000);
Wie ich oben gelesen habe kommt es vom can_enable_mob.
Die Can Botschaften prüfe ich mit CanOe.
Über Hilfe würd ich mich tierisch freuen.
Gruß
Daniel
Ich versuche es mal mit Hilfe. ;)
can_init initialisiert alles mit (0) also msg und length.
can_enable_mob setzt den mode dabei wird leider, warum auch immer, eine
Nachricht verschickt. Ist bei mir auch so, wenn ich da mehr weiß werde
ich es posten.
can_send_data verschickt die eigentliche Nachricht.
das heißt jedes init baut eine leere Nachricht und das en_mob schickt
los.
Generell init und can_enable_mob nur einmal und nicht in der while !!!
Für dich als Lösung 1:
####################
can_init(4, 0, 0);
// mob: 0, modus: senden, id 3, idm 0xffffffff
can_enable_mob(0, 1, 0x70E, 0xffffffff);
while(1){
while ( !(PINE & (1 << PE5)) ) {
can_send_data(0, 8, data);
sleep(1000);
}
}
####################
Jetzt wird die "leere" Nachricht nur einmal geschickt (in Zeile 3) und
anschließend nur noch data.
Wenn du das auch nicht möchtest.
Lösung 2
(nimm alles aus der en_mob ausser das can_set_mode)
####################
can_init(4, 0, 0);
// mob: 0, modus: senden, id 3, idm 0xffffffff
// can_enable_mob(0, 1, 0x70E, 0xffffffff);
uint8_t mob = 0;
uint32_t id = 0x70E;
uint32_t idm = 0xffffffff
// Objekt wählen
can_get_mob(mob);
// Interrupt für dieses Objekt aktivieren
can_set_mob_interrupt(mob);
// ID-Maske setzen
can_set_id_mask(idm);
// ID setzen
can_set_id(id);
while(1){
while ( !(PINE & (1 << PE5)) ) {
can_send_data(0, 8, data);
sleep(1000);
}
}
####################
Habe ich nicht getestet aber sollte so gehen.
Gruß Thomas
Hallo Thomas
danke für die Hilfe.
Habe es mit der letzten LIB auch hinbekommen da macht es es nicht.
can_init muss in die Schleife da ich knapp 80 id anspreche in knapp 9
sec da ich theoretisch 80 stg anspreche um einen Dienst auszuführen.
Hab schon das zweite Projekt am laufen.
Da hab ich aber das Problem wie schon von
Autor: SinoTech (Gast)
am
Datum: 10.01.2011 01:46
mit der Lösung beschrieben, das wenn kein Empfänger da ist man in ner
schleife hängen bleibt.
Beim mir hilft diese Lösung aber nicht.
Hat jemand noch ne Lösung dazu?
Gruß
Daniel
Hi Daniel,
can_init hat nichts mit den ids zu tun.
can_init wird einmal aufgerufen und initialisiert den can controller.
can_enable_mob setzt die mob id.
wenn du zeit sparen willst kannst du in der while anstelle von
can_enable_mob => can_set_id nutzten.
das hängenbleiben beim send ohne Empfänger ist richtig geht mit einen
timeout für die while zu lösen.
while (!getbit(CANSTMOB, TXOK)); <= ohne Empfänger endlos.
Gruß Thomas
Hallo Thomas
danke für die Hilfe, hat bei dem Problem geholfen.
Was ich noch sagen muss ich finde das Forum klasse und es wird immer
einem geholfen.
Die Can Lib find ich genial, simpel und gut erklärt.
So macht der Proggen Spaß.
Gruß
Daniel
Hallo,
ich habe mal ein paar Verständnisfragen.
Laut Datenblatt (S.261 Register: CANSTMOB Bits: TXOK und RXOK) wird ein
MOB nach dem Senden oder Empfangen wieder disabled.
Also muss ich es vor jedem Senden wieder auf Senden stellen bzw. nach
dem Empfangen wieder auf Empfang (CAN_setMode()).
Beim Senden sehe ich so etwas in der Art in der Funktion CAN_sendData(),
beim Empfangen sehe ich es nicht... Müsste ja irgendwo im Interrupt zu
finden sein denke ich.
Bleiben denn die anderen Einstellungen der MOBs beim Disablen erhalten?
Wenn ich etwas empfange, wird doch die Filter-ID mit der Empfangenen ID
überschrieben. Also muss ich danach wieder die Filter-ID neu setzen,
wenn ich filtern möchte, oder?
Im Beispiel werden leider keine ID-Filter verwendet.
Wie wirkt sich das mit der MOB Priorität aus, wenn ich mehrere MOBs auf
den Empfang unterschiedlicher IDs konfiguriere?
Kann es passieren, dass ein höher priorisierter MOB ein anderes lahm
legt?
Danke für Hinweise!
Hi Horst,
Welche Version nimmst du ? Also von wann.
Meine Anmerkungen beziehen sich auf :
---
Autor: garphi (Gast)
Datum: 03.08.2012 14:07
Angehängte Dateien:
Clibs.zip (5,2 KB, 76 Downloads)
---
Horst schrieb:> Hallo,>> ich habe mal ein paar Verständnisfragen.>> Laut Datenblatt (S.261 Register: CANSTMOB Bits: TXOK und RXOK) wird ein> MOB nach dem Senden oder Empfangen wieder disabled.> Also muss ich es vor jedem Senden wieder auf Senden stellen bzw. nach> dem Empfangen wieder auf Empfang (CAN_setMode()).> Beim Senden sehe ich so etwas in der Art in der Funktion CAN_sendData(),> beim Empfangen sehe ich es nicht... Müsste ja irgendwo im Interrupt zu> finden sein denke ich.
Ist auch enthalten in der ISR vorletzter Befehl
// MOB auf Empfang und CAN 2.0B Standard setzen
can_set_mode(CAN_MODE_RECEIVE_DATA);
> Bleiben denn die anderen Einstellungen der MOBs beim Disablen erhalten?
Jop.
>> Wenn ich etwas empfange, wird doch die Filter-ID mit der Empfangenen ID> überschrieben. Also muss ich danach wieder die Filter-ID neu setzen,> wenn ich filtern möchte, oder?
Richtig.
> Im Beispiel werden leider keine ID-Filter verwendet.>> Wie wirkt sich das mit der MOB Priorität aus, wenn ich mehrere MOBs auf> den Empfang unterschiedlicher IDs konfiguriere?> Kann es passieren, dass ein höher priorisierter MOB ein anderes lahm> legt?
Die Filter werden der Reihe nach durchlaufen wenn du mit MOB 14 nur die
ID 100 haben willst und mit MOD 1 die ID's 50..200 dann ist der letzt
nutzlos.
Wenn eine ID von einem Filter angenommen wird gilt die Nachricht als
abgearbeitet.
>> Danke für Hinweise!
Gruß Thomas
Thomas Schulz schrieb:> Welche Version nimmst du ?
Ich beziehe mich auf:
_____________________
Autor: MatMar (Gast)
Datum: 02.12.2009 21:25
Angehängte Dateien:
CAN-Lib.rar (8,2 KB, 794 Downloads)
_____________________
Hatte den Beitrag nach .rar durchsucht und nicht nach .zip
Bei dem von dir genannten Code ist es in der Tat drin.
Ich hatte ja vermutet, dass es rein muss.
Der von mir angesehene Code scheint wohl sehr auf das Beispiel
zugeschnitten zu sein (ohne ID-Filterung).
Ok, danke.
Das erklärt dann vermutlich, warum es bei mir mit anderen CAN Funktionen
noch nicht richtig geht.
Hatte den Effekt, das beim zweiten Senden einer Nachricht die Filter
wieder wirkungslos waren.
Muss dann wohl die Filter-ID wieder neu setzen.
Das ist bei dem von dir genannten Code dann aber auch nicht drin...
Gruß
Horst
Hi Horst,
ich habe es so gemacht das ich ein MOD nur zum senden nutzte und mit den
anderen empfange. ich brauch aber auch lange keine 14 MOB's.
Gruß Thomas
Was macht das IDEMSK Bit im Page Register CANIDM4 eigentlich?
Mein Problem ist, dass ID 0x00000202 als 29Bit ID und ID 0x202 als 11Bit
ID beide meinen Filter passieren und dann in Software anhand des IDE
Bits in CANCDMOB unterschieden werden müssen.
Wie kann ich festlegen, dass nur 11Bit IDs meinen Empfangsfilter
passieren?
Ok, ich kann meine Frage jetzt selber beantworten.
Beim Konfigurieren eines MOB sage ich mit
1
CANIDM4=(1<<IDEMSK);
dass es mir nicht egal ist, was (11 oder 29Bit-ID) ich empfangen möchte.
Was ich empfangen möchte wird mit dem IDE Bit angegeben.
1
CANCDMOB|=(1<<IDE);
Sagt, dass ich eine extended Nachricht (29Bit-ID) empfangen möchte.
1
CANCDMOB&=~(1<<IDE);
Sagt, dass ich eine Standard Nachricht (11Bit-ID) empfangen möchte.
Oder ich lasse diese Zeile weg, wenn CANCDMOB vorher mit 0 initialisiert
wurde.
Wenn ich sowohl extended als auch Standard Nachrichten empfangen möchte,
ist es mir also egal und ich kann den Vergleich auf TRUE zwingen mit:
1
CANIDM4&=~(1<<IDEMSK);
Also indem ich sicher stelle, dass das IDEMSK Bit nicht gesetzt ist.
Das ist also das gleiche Prinzip wie bei den Filter-IDs.
Die empfangene Nachricht überschreibt die Konfiguration (CANIDT1 bis
CANIDT4, setzt ggf. das IDE Bit, usw.) und danach muss man das MOB neu
konfigurieren.
Das ist aus dem Datenblatt schwer heraus zu lesen.
Und auch aus Beispielcode hat es eine ganze Weile gedauert.
Geholfen hat mir letztendlich die Lib von KreativesChaos
(at90can_set_dyn_filter.c):
Hallo zusammen,
nach mehrmaligem Lesen dieses Beitrages habe ich das Problem, welches
schon von Arno Schulz am 11.03.2009 mit der Lib von Marco Glietsch
beschrieben wurde:
1. Nach RESET wird jedes MoB bei Erstbenutzung doppelt gesendet
2. Wenn zwei CAN-Knoten zeitgleich eine Nachricht senden, kommt die
höhere Priorität ID auf den Bus und vom den anderen Knoten kommen die
Nachrichten sporadisch bzw. altenieren und dann doppelt durch.
Wenn ich richtig gelesen habe, liegt es wohl an der folgenden Funktion:
void CAN_sendData(uint8_t mob, uint8_t * data, uint8_t length){
uint8_t mode;
CAN_getMOB(mob); // Objekt wählen
mode = CAN_getMode(); // Aktuelle Betriebsart sichern
CAN_setData(data, length); // Nutzdaten in Register schreiben
CAN_setMode(TRANSMIT_DATA); // Datenübertragung starten
while (!getbit(CANSTMOB, TXOK)); // Warten bis die Datenübertragung
beendet ist (TXOK-Flag von CAN-Controller gesetzt)
clearbit(CANSTMOB, TXOK); // TXOK-Flag löschen
CAN_setMode(mode); // Alte Betriebsart wiederherstellen
}
Gibt es hierfür eine Lösung? Die im Beitrag beschriebenen Lösungsansätze
haben nicht leider funktioniert.
Vielen Dank für eure Unterstützung!
Hi Sebastian,
das Problem hatte ich auch, bei mit war es der Ablauf beim setzten für
senden oder empfangen.
CAN_setMode(TRANSMIT_DATA);
setzten das Register des MOB's.
CANCDMOB wird das Register beschrieben hat es zur Folge das ein
Nachricht senden angestoßen wird.
Schau dir mal den Ablauf an im Debugger und dann kannst du zuschauen das
gesendet wird und an welche Stelle.
Wenn das nicht Hilft kann ich dir auch meine Version von CAN_setMode
geben. (habe ich nur gerade nicht auf diesen Rechner)
Gruß Thomas
Hallo Thomas,
Danke für Deine Unterstützung.
Ich bin in der Zwischenzeit auf die Lib vom Roboterclub Aachen e.V.
umgestiegen. Dadurch haben sich die Probleme erledigt. Bei Start werden
keine Nachrichten doppelt gesendet, wenn mehrere CAN-Knoten zeitgleich
senden kommen alle Nachrichten richtig auf den Bus (das war ja mein
Hauptproblem). Zusätzlich ist mir positiv aufgefallen, dass nun die
Interrupts bei fehlender Quittierung nicht mehr blockiert werden. Denn
ich hatte auch das Problem, dass dann die RS232 blockiert war.
Gruß, Sebastian
Hi zusammen
Ich bin neu auf dem Gebiet der can/Microcontroer und habe desshalb eine
sehr grundegende Frage: Funktioniert die Lib von Marco auch mit CANOpen?
Bisher habe ich nur versucht zu senden, doch mein CanOpenMaster findet
gar keine Box bzw. sieht nicht was sie ist/sendet...
hat von euch ev jemand ein AVR Projekt das er mir zur verfügung sten
würde um zu testen ob s an meinem Programm liegt?
Hallo zusammen,
ich verwende die CAN-Bibiliothek von Marko Glitsch um ein einfaches
Signal zu senden, allerdings wird auf meinem CAN-analyzer weder ein
Signal angezeigt noch leuchtet die TX,RX LED zum senden und empfangen.
Den Programmcode habe ich als Zip-Datei hinzugefügt. Vielleicht weis
irgendjemand hier eine Lösung oder einen Programmvorschlag wie ich am
besten ein einfaches Signal senden kann.
verwendeter Mikrokontroller: At90CAN128
Mfg Woifi
Hi Manuel,
habe die lib noch nicht benutzt aber ist der Fehler manchmal hier ?
// CAN initialisieren
CAN_init(250,RX);
TXRX - Daten gesendet und/oder empfangen
Gruß Thomas
Hallo zusammen
ich brauche dringend Hilfe!!!!!
Als erstes die Bibliothek ist toll aber ich habe ein kleines Problem.
Hatte letztes Jahr ein kleines Projekt gemacht (immer schön versioniert)
und dann das Projekt erfolgreich beendet.
Leider musste ich jetzt doch ne Kleinigkeit ändern in der Anzeige (2x16
Display). Wirklich nur ein Wort und der Rest blieb wie erst ist.
Kein Problem also kurz geändert und gut.
Aber nach dem Kompilieren das große Staunen es kommen keine CAN
Botschaft mehr, der Rest geht LED Kontrolle, Display usw.
Da ich sauber Versioniert hatte, hatte ich zu jeder Version den immer
den gesamten Projektordner archiviert (also Flachfiel und Sourcecode).
Flashe ich das alte File zum passenden Code gehts.
Compiliere ich den passenden Code zum Flachfile kommen keine Can
Botschaften.
Ich habe in der Zeit meinen Rechner neu Installiert von XP (ich weiss
ziemlich alt) auf WIN 7 Pro 64 bit und von AVR Studio 6.1 beta auf 6.1
normal gewechselt.
Habe übrigens noch mehr CAN Projekte ebenfalls gut versioniert ist
überall das gleiche, neu dompiliert keine CAN Botschaften, altes File
und es geht.
Was mache ich falsch? AVR Studio 6.2 beta habe ich auch schon
probiert!!!
Muss ich irgendwas einstellen an das ich mich nicht mehr erinnern kann
in AVR Studio benutze das Olimex CAN Board.
Bitte helft mir ich verzweifle noch!!!!
Gruß
Daniel
Hallo Daniel,
mit welcher Version von AVR-Studio hast du denn deine "alten" Versionen
compiliert? Ich kenn das auch mit dem neuen AVR-Studio 6. Nun benutzte
ich weiterhin unter Win7, wie vorher unter XP, die Version 4.18. Aber
auch mit den neuen Versionen von AVR-Studio geht es normalerweise. Du
musst schauen das alle Bibs richtig eingebunden werden und die Angaben
zu den Header-Files passen.
Viel Glück!
Hallo,
ich habe die Can Library auf einem Olimex AVR CAN board ausprobiert,
aber es scheint keine Nachricht gesendet zu werden.
In senddata läuft das program bis zu dem Punkt, wo es auf das TOXK Flag
wartet, dies wird jedoch nie gesetzt. Wenn ich die Zeile auskommentiere
funktioniert es auch nicht.
Habe den Code von Marco Glietsch probiert und stundenlang Fehler gesucht
oder Änderungen vrsucht.
#define _AVR_AT90CAN128_ 1
#define OSCSPEED 16000000 /* in Hz */
#include <avr/io.h>
#include "can.h"
#define SIG_CAN_INTERRUPT1 _VECTOR(18)
void LedAn()
{
PORTE=(0<<4);
}
void LedAus()
{
PORTE=(1<<4);
}
main()
{
PORTE=0b00010000;
DDRE=0b00010000; //PE4 LED Ausgang
CAN_init (1000 , TX );
// Zu sendende Daten
CAN_message msg ;
msg.id = 1 ;
msg.idm = 1 ;
msg.data [0] = 0x11 ;
msg.data [1] = 0x22 ;
msg.data [2] = 0x33 ;
msg.data [3] = 0x44 ;
msg.data [4] = 0x55 ;
msg.data [5] = 0x66 ;
msg.data [6] = 0x77 ;
msg.data [7] = 0x88 ;
while(1)
{
// Objekt 0 auf Empfang setzen
CAN_enableMOB (0, RECEIVE_DATA , msg );
// Daten ¨uber Objekt 0 senden
CAN_sendData(0, msg.data);
LedAn();
_delay_ms(1000);
LedAus();
_delay_ms(1000);
}
}
Hat jemand den Code auf einem Olimex board zum Laufen bekommen, oder hat
jemand ein Beispiel Code?
Danke
hari
Hast du dein Programm auf deinem Olimex Board zum laufen gebracht? um
mit meinem board zu spieeln suche ich einen guten beispielcode welcher
sicher auf dem olimex läuft.
Hy zusammen,
ich habe mich auch mit dem CAN-Bus beschäftigt, aber am ATMega16M1.
Es "läuft" auch, es sind noch kleine Fehler drin bzw. habe ich da noch
ein paar Verständniß fragen.
Wieso speicher wird die CANPAGE zwischen gespeichert?
Wer die ISR ausgelöst wird ist doch klar wenn man die CANSIT2 ausliest
und in der mainloop verarbeitet und dann wieder auf Empfang stellt.
Wenn Nachrichten (von PCAN) eingehen im Intervall von 1ms und der AVR
diese durch einen Daten-Frame quittiere funktioniert dies auch und wenn
vom AVR noch alle 100ms eine Nachricht gesendet wird zu PCAN. Werden im
PCAN ACK-Fehler angezeigt und nach einer Zeit schaltet sich PCAN in
BUSOFF.
Aber laut meiner Rechnung sollte das von der zeit ausreichen. CAN-Frame
max 111+19 bits bei 1000kbps sollte pro 1ms 7 Frame ohne Problem klappen
und sich nicht bei 2-3 Frames.
Habt ihr vielleicht eine Idee woran das liegen könnte?
Dickes danke im voraus.
mfg Ben
Moin zusammen.
Ich beschäfitge mich jetzt seit längerer Zeit mit der
Mikrocontrollerprogrammierung an einem AT90CAN128. Ich habe schon einige
Funktionen geschrieben und versuche nun, in meinem Projekt den CAN-Bus
zu implementieren.
Dazu verwende ich die Bibliothek, wie sie von Marco Glietsch oben
hochgeladen wurde.
Bei der Ausführung stoße ich immer auf folgendes Problem, dass auch
schon oben am 28.12.2010 angesprochen wurde.
Die programmausführung des Mikrocontrollers bleibt bei CAN_sendData in
der Zeile
while (!getbit(CANSTMOB, TXOK));
hängen.
Mit dem Lösungsvorschlag, dass mindestens ein Teilnehmer als Empfänger
am Bus sein soll, komme ich nicht weiter.
Zu meinem Aufbau:
Derzeit habe ich den gesamten Aufbau auf einem Steckboard realisiert.
Der CAN-Bus ist an beiden Enden mit 120Ohm terminiert.
Neben dem Sender befindet sich ein AT90CAN128 als Empfänger am Bus,
zusätzlich ein PCAN-USB-Adapter, der die Daten auf dem Bus mitloggen
soll.
CAN_HIGH und CAN_LOW werden gleichzeitig mit einem Oszilloskop überwacht
und zeigen dauerhaft einen Signalpegel von ca. 2,4V.
Ich bin derzeit überfragt und komme absolut nicht weiter.
Kann mir jemand helfen?
Danke und Gruß,
Michael.
Ich habe heute noch einiges ausprobiert, aber komme partout nicht
weiter.
In der besagten Schleife hängt der Controller fest und auf dem Bus
ergibt sich keine Pegeländerung.
Hat jemand noch Tipps oder Ratschläge, wonach ich suchen könnte?
Hallo Michael,
Wie sieht deine Hardware aus? Hast du einen passenden CAN-Transiver
richtig angeschlossen?
Wenn deine Schleife an der beschriebenen Stelle hängen bleibt, ersetze
es doch testweise mal mit einem kleinen delay zB 10ms.
Viel Glück!
Hallo,
ok das sollte passen. Hast du den PCAN so eingestellt das er alle
Nachrichten quittiert?
Hat das mit dem delay statt dem Befehl im Code nicht funktioniert?
Die Einstellung des PCAN muss ich kontrollieren, das weiß ich so nicht
auswendig.
Das Delay hat nichts gebracht. Der Controller wartet dann nur, auf den
Bus wird aber trotzdem nichts gesendet.
So, ich bin etwas weiter, aber keinesfalls schlauer.
Beim PCAN kann ich nur Message Filter auswählen, aber keine Quittierung.
Oder übersehe ich etwas?
Ich betreibe den AT90CAN128 nun mit einem JTAG ICE 3 und bin das
Programm mal im Einzelschrittmodus durchgegangen.
Es ist so, dass einzelne Codezeilen scheinbar nicht ausgeführt werden.
Beispielsweise wird die Funktion CAN_setBaudrate nicht ausgerufen. Somit
wurden die Baudrate-Register garnicht beschrieben, das lässt sich ja
über JTAG auslesen.
Später werden einzelne setbit bzw. clearbit-Befehle nicht ausgeführt.
Ich bin gerade echt überfragt.
Woran kann es liegen, dass einzelne Zeilen nicht ausgeführt werden?
Beim Compilieren erscheinen keine Fehler.
Michael H. schrieb:> Woran kann es liegen, dass einzelne Zeilen nicht ausgeführt werden?> Beim Compilieren erscheinen keine Fehler.
weg optimiert. - de facto werden sie (bzw. zu diesem Zeitpunkt WURDEN
sie) schon ausgeführt. Wenn Du jeden Befehl genau so wie beschrieben
abgearbeitet haben willst, kannst Du probehalber in den Einstellungen
mal die Optimierung auf Null stellen. Wird aber auf den fehlerhaften
Ablauf Deines Programms keinen Einfluss haben
Michael H. schrieb:> Beim PCAN kann ich nur Message Filter auswählen, aber keine Quittierung.> Oder übersehe ich etwas?
Die PEAK CAN-USB Geräte senden meines Wissens immer ein ACK. Listen-Only
habe ich noch nirgends gefunden.
Michael H. schrieb:> Kannst du mir sagen, wo ich in PCAN View die Einstellung finde?
Wie gesagt, ich habe auch noch keine Einstellung gefunden.
Sobald das CAN-Gerät über den Blitz verbunden wurde, wird immer ein ACK
gesendet.
Hallo Michael,
wichtig für dich wäre ist doch ein Code der erstmal überhaupt eine
CAN-Nachricht schickt, oder? Ich arbeite immer noch mit dem Atmel-Studio
4. Der Umstieg auf die neueren Versionen hab ich irgendwann mal
aufgegeben da der funktionierende Code übersetzt mit Atmel-Studio 4 z.B.
mit Atmel-Studio 5 aus nicht nachvollziehbaren Gründen nicht mehr lief.
Welches IDE hast du? Vielleicht liegt es bei dir auch daran. Ich hab
aber, wie weiter oben mal beschrieben, die Bibliothek gewechselt. Das
lag aber nicht an der grundsätzlichen Funktion der Bibliothek von Marco.
Hallo Sebastian.
Genau so ist es. Ich suche einen Code, der zunächst ohne Modifikationen
irgendwas per CAN verschickt.
So kann ich zumindest Fehlerquellen ausschließen.
Ich arbeite mit Atmel Studio 6 in der Version 6.2.1548, Service Pack 2.
Habe ich auch nochmal alles auf den neusten Stand gebracht, aber
vielleicht liegt es daran?
Zudem setze ich den JTAG ICE 3 ein.
Kannst du mir für das Studio 4 einen Code zur Verfügung stellen, der so
(plug und play) funktioniert?
Wäre echt klasse!
Es muss ja nicht der vom Themenstarter hier sein.
Danke und Gruß,
Michael.
Hallo Michael,
ich hab für dich gerade mal ein Beispiel-Code erstellt der aller 100ms
eine CAN-Nachricht sendet. Jedoch würde ich das vorher gern testen. Das
kann ich erst morgen in Laufe des Tages erledigen da ich die Hardware
nicht da habe. Also etwas Geduld!
Viele Grüße
Sebastian
Hallo Sebastian.
Danke für deine Hilfe.
Ich werde in der Zwischenzeit mal das Atmel Studio 4 installieren,
sodass ich damit dann testen kann.
Gruß,
Michael.
Hallo,
ich möchte mit der Bibliothek von Marco Glietsch CAN Botschaften senden.
Vielen Dank erstmal für diese Bibliothek!
Allerdings komme ich nicht voran.
Bisher möchte ich nur eine Botschaft senden.
Ich verwende:
- AT90CAN128 (auf einem Board von Olimex)
- STK600
- Atmel Studio 6.2
Im Anhang habe ich die Header Datei sowie mein Hauptprogramm
Das Programm läuft durch bis zu diesem Punkt:
PORTB = 0b00001000; //LED 1 blinkt
_delay_ms(1000);
PORTB = 0b00000000;
while (!getbit(CANSTMOB, TXOK));
clearbit(CANSTMOB, TXOK);
PORTB = 0b00000100; //LED 2 blinkt
_delay_ms(1000);
PORTB = 0b00000000;
Dadurch, dass die erste LED blinkt die zweite allerdings nicht weiß ich,
dass ich wohl nicht über die while Schleife hinaus komme.
Das bedeutet doch das er darauf wartet fertig zu senden, dies aber nicht
passiert. Oder?
Kann mir jemand sagen wo in meinem Programm der Fehler ist?
Vielen Dank schon mal im Voraus!!
Viele Grüße
Tobias
Die Bilbliothek nutze ich nicht.
Aber TXOK sollte erst nach einer erfolgreichen Übertragung des CAN
Telegramms kommen. Was hast Du als Gegenstelle? Hast Du dort etwas
empfangen?
Kann mir jemand dabei helfen die Kommunikation über CANoe darzustellen?
Welche Vorkehrungen muss ich da treffen?
Bzw könnt ihr mir eine Alternative nennen, wie ich mir die gesendeten
Nachrichten ansehen kann?
Michael schrieb:> Hallo Wolfgang,>> ich hab die Bibliothek wieder etwas modifiziert. Nur die ganzen> enum-Konstanen in die Header-Datei verlagert, so dass man sie jetzt auch> in main.c nutzen kann. Es macht den Code wesentlich uebersichtlicher,> wenn man aussagekraeftige Konstanten wie z.B. CAN_BAUDRATE_250K> verwenden kann und nicht eine einfache Zahl wie 3.>> Nun zu deinem Problem. Ich hab mom. nichts hier zum testen, hab aber die> main.c mit Beispielen erweitert, wie es eigentlich funktionieren sollte.> Wenn es nicht geht, dann ist es wahrscheinlich ein Bug. ;-)>> Das Problem ist, dass ich mich auch erst seit ein paar Tagen mit dem> CAN-Bus befasse und daher durchaus noch Fehler schlummern koennte.> Probier es einfach mit den Beispielen aus und sag, was geht und was> nicht.>> Ich habe mit der Bibliothek heute erfolgreich Senden, Empfangen und> automatische Antworten getestet. Allerdings immer nacheinander und nie> gleichzeitig. Muss ich am Montag mal genauer untersuchen.>> Wenn ihr Fehler seht, dann sagt mir Bescheid. Danke! 2*n Augen für n>1> sehen eben einfach mehr als nur 2. ;-)>> --Michael
Hallo MIchael,
deine Bib funktioniert bei mir bisher am besten.
Habe nur eine frage zum empfang.
du sagst ja, dass der interrupt ausgelöst wird, sobald eine nachricht
mit der id 4 von einem anderen busteilnehmer ankommt.
was muss ich in der main (außer sei();) noch hinzufügen,damit der
interrupt auch ausgelöst wird.
im moment sende ich nämlich eine nachricht von canoe mit der id 4 und es
passiert leider nichts.
Hi. Please help me. I have to use 2 different CAN_id to send data. Can i
use your library?
Hallo. Bitte hilf mir. Ich muss 2 verschiedene CAN_id verwenden, um
Daten zu senden. Kann ich deine Bibliothek benutzen?
alter Thread, habe aber dazu eine Frage:
Kann ich mit dem AT90CAN128 irgendwie das Reservierte Bit im
Controllfeld auf Dominant setzen ?
Also: Bit: Request
Bit: IDE
BIT: Reserviert <<<---- das hier
Bit: DL3
usw.
Habe da einen AT90CAN128 mit der oberen Lib (Mischung)
Normale 11Bit Adressierung und 8 Daten Bytes
Ich habe da eine Hardware, die sendet mir bei dem Reservierten Bit ein
Dominates Bit.
Ich möchte mit dem AVR diese Hardware nachbilden
Der AVR sendet dort aber nur ein Recessives Bit.
Normal sollte dieses Bit unwichtig sein, möchte aber mit dem AVR ,genau
das so nachstellen.
Darum müsste ich dieses Reservierte Bit auf Dominant bekommen !
Geht das irgendwie ?
Hat jemand dazu bitte einen Tipp ?
DANKE :-)
l.G. Robert