mikrocontroller.net

Forum: Mikrocontroller und Digitale Elektronik Probleme mit CAN Controller (SJA1000)


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

Bewertung
0 lesenswert
nicht lesenswert
Hallo!

Zur Zeit bin ich gerade dabei den SJA1000 über die LPT
(Win2000)anzusprechen.Die LPT kann ich ohne Probleme ansteuern.
Ich habe den SJA1000 zuvor mit einem ATMEL COntroller angesteuert.
Funktioniert einwandfrei. Nur über die LPT funktioniert es nicht so wie
ich es will.
Wenn ich z.B. die Adresse 0 mit dem Wert 0x05 lade, dann bekomme ich
den reingeschriebenen Wert nicht zurück. Es erscheint immer 0.

In Borland Builder C++ habe ich versucht diesen C-Code zu benutzen.
Das Timing habe ich genau so gemacht. Vielleicht liegt es an der
Funktion Pause.
Kann mir dabei jemand helfen?

Autor: Andreas (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo Joe,

sieh mal hier: http://private.addcom.de/horo/can200/

nach. Da gibt es Beispiele dazu

Grüße
Amdreas

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

Bewertung
0 lesenswert
nicht lesenswert
Hallo Andreas!

Vielen Dank für den Link. Leider kenne ich diese Seite schon.
Ich habe die Schaltung (siehe Anhang) so aufgebaut.
Den LPT-Port kann ich ohne weiteres ansteuern. Nur wenn ich mit dem
Borland Builder C++ die Daten vom SJA1000 auslesen will dann haut das
nicht hin.

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

Bewertung
0 lesenswert
nicht lesenswert
Hallo Andreas!

Vielen Dank für den Link. Leider kenne ich diese Seite schon.
Ich habe die Schaltung (siehe Anhang) so aufgebaut.
Den LPT-Port kann ich ohne weiteres ansteuern. Nur wenn ich mit dem
Borland Builder C++ die Daten vom SJA1000 auslesen will dann haut das
nicht hin.

void TForm1::pause(void)
{
for (unsigned int x=0; x<10000; x++)
 {;}
}

void TForm1::canreg_write(unsigned char adresse, unsigned char daten)
{
write_DataRegister(0x00);
set_bit(0x37A,ALE);
clear_bit(0x37A, RD);
set_bit(0x37A,WR);

clear_bit(0x37A,ALE);
pause();
write_DataRegister(adresse);
pause();
set_bit(0x37A,ALE);
pause();
write_DataRegister(daten);
pause();
clear_bit(0x37A,WR);
set_bit(0x37A,WR);
clear_bit(0x37A,ALE);
}

unsigned char TForm1::canreg_read(unsigned char adresse)
{
short daten = 0;
clear_bit(0x37A,ALE);
pause();
write_DataRegister(adresse);
set_bit(0x37A,ALE);
pause();
set_bit(0x37A,RD);
pause();
daten = read_DataRegister();
clear_bit(0x37A,RD);
return daten;
}

/*----Initialisierungsroutine für den CAN-Controller
SJA1000------------*/
void TForm1::can_init(void)
{
 do
  {
   canreg_write(0,0x01);
  }
 while (((canreg_read(0)) &0x01)==0);
 canreg_write(4,0xFF);
 canreg_write(5,0xFF);

 canreg_write(6,0x43);
 canreg_write(7,0x2F);
 canreg_write(8,0x1A);
 canreg_write(31,0x07);

 do
  {
   canreg_write(0,0x00);
  }
 while (((canreg_read(0))&0x01)==01);
 canreg_write(1,0x0C);
}

Autor: Joe (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Meine Hardware habe ich auch schon überprüft. Ich kann einfach den
Fehler nicht finden, warum es nicht geht. Wie gesagt mit meinem ATMEL
Controller funktioniert die Kommunikation mit den CAN Controller.

Autor: Andreas (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Versuch doch statt pause einfach mal sleep(ZeitInMS).
Vielleicht gibt Windows Deine Daten ja nicht raus.

ISt nur ein Gedanke der mir gerade gekommen ist als ich gesehen habe
wie Du die Pause realisierst.

Grüße
Andreas

Autor: Joe (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Dabke Andreas!

Werd ich mal versuchen! Gibt es sonst noch was dir aufgefallen ist?

Autor: Joe (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallp Andreas!

Dies hab ich jetzt auch mal ausprobiert. Leider klappt es immer noch
nicht. Grrrr...

Autor: Joe (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Mit Borland Builder C++ schaffe ich es noch als nicht, den CAN
Controller korrekt anzusteuern. Wenn ich z.B. vom Register 0x06 den
Inhalt auslesen will dann erhalte ich immer wieder 0x06. Bei den
anderen Registern ist es genau so. Ich weiss nun nicht mehr was ich da
jetzt noch tun kann, damit es funktioniert. Vielleicht stimmt auch was
mit der Verzögerung nicht. Hmmm...

void TForm1::pause(void)
{
Sleep(500);
}

void TForm1::canreg_write(unsigned char adresse, unsigned char daten)
{
write_DataRegister(0x00); //Daten 0
set_bit(0x37A,ALE); // ALE = 0
clear_bit(0x37A, RD); // RD = 1
set_bit(0x37A,WR); // WR = 1

clear_bit(0x37A,ALE); // ALE = 1
pause();
write_DataRegister(adresse);
pause();
set_bit(0x37A,ALE); //ALE = 0;
pause();

write_DataRegister(daten);
pause();
clear_bit(0x37A,WR); //WR = 0;
set_bit(0x37A,WR); // WR = 1;
clear_bit(0x37A,ALE); // ALE = 1
}

unsigned char TForm1::canreg_read(unsigned char adresse)
{
short daten = 0;

clear_bit(0x37A,ALE); // ALE = 1
pause();
write_DataRegister(adresse);
set_bit(0x37A,ALE); // ALE = 0
pause();

set_bit(0x37A,RD); // RD = 0
pause();
daten = read_DataRegister();
clear_bit(0x37A,RD); // RD = 1
return daten;
}

Autor: Joe (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Für die Hilfe bin ich sehr dankbar!

Autor: Joe (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Kann mir in diesem Forum niemand helfen?
Ich bin auf die Hilfe des Forums angewiesen.

Autor: Eddi (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Also mein Studium des Datenblatts hat damals folgenden Verlauf der
Signale ergeben (CS ist immer low, RD und WR sind anfangs high) :

ALE=1
<Adresse> auf AD0-7 legen
ALE=0
WR=0
<Daten> auf AD0-7 ausgeben
WR=1

So läufts jedenfalls seitdem...

Gruß
Eddi

Autor: Joe (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo Eddi!

Danke für die Unterstützung. Ich habe es genau so programiert, leider
funktioniert es immer noch nicht.

unsigned char TForm1::canreg_read(unsigned char adresse)
{
set_bit(0x37A,ALE);
clear_bit(0x37A, RD);
set_bit(0x37A,WR);
short daten = 0;

clear_bit(0x37A,ALE);
pause();
write_DataRegister(adresse);
pause();
set_bit(0x37A,ALE);
pause();

set_bit(0x37A,RD);
pause();
daten = read_DataRegister();
pause();
clear_bit(0x37A,RD);
return daten;
}

Autor: Joe (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Vielleicht ist ein Fehler im Schaltplan vorhanden. Siehe Dateianhang am
Anfang des Threads.
Ich weiss nun nicht was ich da jetzt noch tun kann.
Also mir kommt es so vor, als ob der CAN COntroller die Adresse nicht
korrekt übernimmt.

Autor: Joe (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Was mir dabei noch auffällt ist, dass es bei der LPT kein Data Direction
gibt wie z.B. beim ATMEL ATMEGA8535.

Autor: H-A-L-9000 (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Na klar: Falls dein LPT-Port überhaupt bidirektional ist musst Du ihn
natürlich auf Eingang umschalten, wenn du Daten lesen willst.

Autor: Joe (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ich habe einen ganz normalen LPT Port am PC. Ich weiss gar nicht ob er
bidirektional ist. Wie kann ich einen LPT Port auf Eingang umschalten?

Autor: 123 (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
google hilft immer weiter.

Autor: Joe (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Eine echt dumme Antwort! Danke 123

Autor: Andreas (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo Joe,

das muss irgendwo im Setup sein. Meine es mal da gesehen zu haben.
Beim Booten des Rechners gelangt man dorthin.



Grüße
Andreas

Autor: Joe (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo Andreas!

Ich hab mal im BIOS nachgeschaut. Der LPT Port steht auf EPP Modus.
Also somit müsste es gehen. Ich muss dann möglicherweise im Control
Register das Bit5 auf "1" setzen. Stimmt das?

Autor: emil (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Vielleicht hilft das:

LPT know-how + Steuerung:

http://www.lvr.com/parport.htm

LPT-Monitor (zut Beobachtung der Pin-Zustände):

http://neil.fraser.name/software/lpt/

Autor: Joe (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ok im BIOS habe ich die Einstellung für den LPT vorgenommen.
Leider kann das Reset Request Bit nicht auf "1" setzen.

Das Reset Request Bit muss doch geprüft werden um dann das Bittiming
und die Nachrichtenfilter zu setzen. Erst dann können CAN-Botschaften
gesendet oder empfangen werden. Das Programm bleibt immer in der
do..while Schleife hängen. Was muss ich ändern damit die
Initialisierung durchläuft?

/*----Initialisierungsroutine für den CAN-Controller
SJA1000------------*/
void can_init(void)
{
 do
  {
   canreg_write(0,0x01);
  }
 while (((canreg_read(0)) &0x01)==0);
 canreg_write(4,0xFF);
 canreg_write(5,0xFF);

 canreg_write(6,0x43);
 canreg_write(7,0x2F);
 canreg_write(8,0x1A);
 canreg_write(31,0x07);

 do
  {
   canreg_write(0,0x00);
  }
 while (((canreg_read(0))&0x01)==01);
 canreg_write(1,0x0C);
}

Autor: Joe (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ok so wie es aussieht funktioniert die CAN Initialisierung.
Jetzt bin ich gerade dabei eine Botschaft auf den CAN Bus zu senden.
Das habe ich bis jetzt nicht zum laufen gebracht.
Das Programm bleibt bei "warten bis Sendung ausgelöst" stehen.
Es kann auch sein das die Initialisierung doch nicht richtig ist. Wie
gesagt den SJA1000 habe ich zusammen mit einem ATMEL Controller
am laufen. Klappt wunderbar.

/*----CAN Botschaft
senden------------------------------------------------*/
void TForm1::canmessage_write(struct message *ptransmit)
{
   unsigned int id_1,id_2,id_3;
   unsigned int id_1_hilf,id_2_hilf,id_3_hilf;
   unsigned int trdscr_wert;
   unsigned int i;

   id_3=(ptransmit->id)&0x0f;
   id_2=((ptransmit->id)/16)&0x0f;
   id_1=((ptransmit->id)/256)&0x0f;

   id_1_hilf=id_1*32;
   id_2_hilf=id_2*2;
   id_3_hilf=id_3/8;

   trdscr_wert=(id_1_hilf)|(id_2_hilf)|(id_3_hilf);
   canreg_write(10,trdscr_wert);


   id_3=(ptransmit->dlc)&0x0f;
   id_2=(ptransmit->rtr)*16;
   id_1=((ptransmit->id)&0x0f)*32;

   trdscr_wert =(id_3)|(id_2)|(id_1);
   canreg_write(11,trdscr_wert);

   for (i=0;i<=7;i++)
    {
     canreg_write (12+i,ptransmit->byte[i]);
    }
   canreg_write (1,0x01);                //Sendung auslösen

   do
    {
    }
   while (((canreg_read(2))&0x08)==0);    //warten bis Sendung fertig

}

Autor: Joe (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Gibt es hier in diesem Forum niemand der mir dabei helfen kann?

Autor: Andreas Häusler (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ich vermute Dein Problem beim Ansprechen der parallelen
PC-Schnittstelle. Schau Dir doch mal folgenden Link an:

http://www.the-starbearer.de/Praxis/ElektronikamPC...

Unter Win NT/2000 und XP ist es nicht mehr so einfach möglich auf die
Schnittstellen zuzugreifen. Kenne mich mit dem Builder nicht so aus,
habe immer in Delpi programmiert. Für diese Programmiersprache findest
Du im Web diverse sys- Treiber oder dll's (Port.dll) die dir den
Zugriff auf die Register ermöglichen. Da es sich um eine dll handelt,
sollte das Einbinden in den C++Bilder einfach möglich sein.

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.