Probleme mit CAN Controller (SJA1000)

Gast #136085
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?
Angehängte Dateien:
Gast #136087
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.
Angehängte Dateien:
Gast #136088
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);
}
Angehängte Dateien:
Gast #136089
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.
Gast #136090
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
Gast #136093
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;
}
Gast #136096
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
Gast #136097
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;
}
Gast #136098
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.
Gast #136105
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?
Gast #136107
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);
}
Gast #136108
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

}
Gast #136110
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.

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren