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


von Joe (Gast)


Angehängte Dateien:

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?

von Andreas (Gast)


Lesenswert?

Hallo Joe,

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

nach. Da gibt es Beispiele dazu

Grüße
Amdreas

von Joe (Gast)


Angehängte Dateien:

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.

von Joe (Gast)


Angehängte Dateien:

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);
}

von Joe (Gast)


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.

von Andreas (Gast)


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

von Joe (Gast)


Lesenswert?

Dabke Andreas!

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

von Joe (Gast)


Lesenswert?

Hallp Andreas!

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

von Joe (Gast)


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;
}

von Joe (Gast)


Lesenswert?

Für die Hilfe bin ich sehr dankbar!

von Joe (Gast)


Lesenswert?

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

von Eddi (Gast)


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

von Joe (Gast)


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;
}

von Joe (Gast)


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.

von Joe (Gast)


Lesenswert?

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

von H-A-L-9000 (Gast)


Lesenswert?

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

von Joe (Gast)


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?

von 123 (Gast)


Lesenswert?

google hilft immer weiter.

von Joe (Gast)


Lesenswert?

Eine echt dumme Antwort! Danke 123

von Andreas (Gast)


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

von Joe (Gast)


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?

von emil (Gast)


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/

von Joe (Gast)


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);
}

von Joe (Gast)


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

}

von Joe (Gast)


Lesenswert?

Gibt es hier in diesem Forum niemand der mir dabei helfen kann?

von Andreas Häusler (Gast)


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/LPT/LPT%20programmieren.htm

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.

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
Noch kein Account? Hier anmelden.