Forum: Mikrocontroller und Digitale Elektronik AVR 8535 + Can Controller Problem!!!


von Leo (Gast)


Angehängte Dateien:

Lesenswert?

Hallo!

Ich habe den SJA1000 (CAN-Controller) an meinem AVR 8535 angeschlossen.
PORTB und PORTD.
Irgendwie schaffe ich es einfach nicht den SJA1000 korrekt
anzusprechen! Siehe Quellcode
Kann mir jemand erklären was ich da falsch mache????

von Peter D. (peda)


Lesenswert?

Du must das Timing simulieren, wie es ein 8515 ausgibt, bzw. wie es im
SJA1000 Datenblatt steht:

Schreiben:
Datenbus als Ausgang
ALE = 1
Adresse ausgeben
ALE = 0
Daten ausgeben
WR = 0
WR = 1

Lesen:
Datenbus als Ausgang
ALE = 1
Adresse ausgeben
ALE = 0
Datenbus als Eingang (hochohmig)
RD = 0
Daten einlesen
RD = 1


Peter

von Leo (Gast)


Lesenswert?

Hallo Peter!

Vielen Dank für die schnelle Antwort.
Wenn dies hier dann einhalte, dann muss es zu 100% funktionieren???
Hast du meinen Quellcode gesehen???

von Leo (Gast)


Angehängte Dateien:

Lesenswert?

So habe jetzt die änderungen vorgenommen.
Leider funktioniert es noch immer nicht.
Ich kann einfach z.B. das Register 4 nicht auslesen.
Siehe Quellcode!

von Peter D. (peda)


Lesenswert?

DDRB = 0x00;

FF ist doch Ausgang.

Peter

von Leo (Gast)


Angehängte Dateien:

Lesenswert?

Ich habe das DDRB Register auf 0x00 gesetzt.
So ein misst es funktioniert noch immer nicht.
Ha...was kann da noch tun???

von Leo (Gast)


Angehängte Dateien:

Lesenswert?

Hier habe ich mal eine Zeichnung von meinem Aufbau!

von Stefan Kleinwort (Gast)


Lesenswert?

Die Signale ALE, RD und WR (Portpins) müssen IMMER auf Ausgang
geschaltet werden.

Der Port B muss VOR dem Schreiben auf Ausgang geschaltet werden.
Genauso muss er VOR dem Lesen auf Eingang geschaltet werden.
Am besten jeweils innerhalb der Routinen lesen() und schreiben().

Stefan

von OldBug (Gast)


Lesenswert?

Hallo zusammen!

Aufgrund der vielen Nachfragen hier im Forum habe ich mal meine
SJA-1000 Funktionen so gut wie möglich versucht zu extrahieren.
Leider ist dieser Code noch nicht auf AVRs/MSPs/PICs oder was auch
immer getestet (hatte noch keine Zeit), aber falls da jemand interesse
hat, kann ich diesen Code gerne zur Verfügung stellen.
Ich habe das ganze mit Absicht nicht in die Codesammlung gestellt, da
eigentlich noch eine ganze Menge Doku fehlt und der Code, wie gesagt,
noch nicht getestet ist.

Natürlich stehe ich euch zur Verfügung, wenn ihr das einsetzen wollt!

Gruß,
Patrick...

von Leo (Gast)


Lesenswert?

Hallo OldBug!

Also für den Code würde ich mich interessieren.
Kannst du mir diesen Code per Mail zusenden???

von Leo (Gast)


Lesenswert?

Hier habe ich mal einen Ausschnitt aus meinem C Programm gepostet.
Kann mir da jemand sagen was ich da falsch gemacht habe,
Ich komme nicht weiter!

void init(void)
{
 PORTB = 0;
 DDRB = 0xFF;
 PORTD = 0;
 DDRD = 0xFF;
 ALE = 0;
 RD = 1;
 WR = 1;
}

void schreiben(unsigned char adresse)
{
 init();

 ALE = 1;
 PORTB = adresse;
 ALE = 0;

 PORTB = 0x11;
 WR = 0;
 WR = 1;
}

unsigned char lesen(unsigned char adresse)
{
 init();

 ALE = 1;
 PORTB = adresse;
 ALE = 0;

 DDRB = 0x00;
 RD = 0;
 daten = PORTB;
 RD = 1;

 return daten;
}

void main(void)
{
schreiben(0x04);
sprintf(text," Daten = %3.0u",lesen(0x04));
lcd_gotoxy(0,0);
lcd_puts(text);

while (1)
      {};
}

von Peter D. (peda)


Lesenswert?

Dem Schreiben sollte man vielleicht auch Daten übergeben ?

Und daß Init immer RD und WR auf 0 setzt, dürfte auch gegen den Baum
laufen.



Peter

von Leo (Gast)


Lesenswert?

Hallo Peter!

Ja was meinst du genau?
Könntest du mir den Code korrektieren?
Ich wäre dir sehr dankbar.
Sorry, bin leider kein AVR Experte!
Ich bin halt auf hilfe angewiesen

von Leo (Gast)


Lesenswert?

Ok, den Funktionen übergebe ich ja die Parameter!
z.B. 0x04

von Josef (Gast)


Lesenswert?

Würde den Controller im extern Ram Modus betreiben und so den CAN
Controller ansprechen. Funktioniert besser bezüglich Timing.

www.candip.com/candip-avr.htm

Josef

von Peter D. (peda)


Lesenswert?

"Sorry, bin leider kein AVR Experte!"

Das Datenblatt ist Dein Freund und nicht nur dazu da, daß die
Hersteller ihren Webspace voll kriegen.



"Ich bin halt auf hilfe angewiesen"

Und warum beachtest Du dann meine Hilfe nicht ?

"Dem Schreiben sollte man vielleicht auch Daten übergeben.

Und daß Init immer RD und WR auf 0 setzt, dürfte auch gegen den Baum
laufen."



Peter

von Leo (Gast)


Lesenswert?

Hallo Peter!

Beider schreib-Routine übergebe ich zuerst die Adresse und
dann die Daten. Sihe Code --> PORTB = 0x11.
Bei der Init-Routine setze ich das RD und WR auf EINS.
Das sind Low-aktive eingänge.
Oder verstehe ich da jetzt was falsches???

von Leo (Gast)


Lesenswert?

void init(void)
{
 PORTB = 0;
 DDRB = 0xFF;
 PORTD = 0;
 DDRD = 0xFF;
 ALE = 0;
 RD = 1;
 WR = 1;
}

void schreiben(unsigned char adresse)
{
 init();

 ALE = 1;
 PORTB = adresse; //Hier übergebe ich zuerst die Adresse z.B. 0x04
 ALE = 0;

 PORTB = 0x11; // Hier schreibe ich dann die Daten in das Register
 WR = 0;
 WR = 1;
}

unsigned char lesen(unsigned char adresse)
{
 init();

 ALE = 1;
 PORTB = adresse; //Hier übergebe ich zuerst die Adresse z.B. 0x04
 ALE = 0;

 DDRB = 0x00;
 RD = 0;
 daten = PORTB; // Hier lese ich dann die Daten
 RD = 1;

 return daten;
}

void main(void)
{
schreiben(0x04);
sprintf(text," Daten = %3.0u",lesen(0x04));
lcd_gotoxy(0,0);
lcd_puts(text);

while (1)
      {};
}

Das müsste doch so hinhauen! Aber leider funktioniert es nicht.
Vielleicht habe ich noch einen Denkfehler!
Hmm...

von Peter D. (peda)


Lesenswert?

Oh Gott,

Du übergibst ja die Daten nicht als Parameter, sondern schreibst
konstant 0x11 rein. Das hat doch nicht den geringsten praktischen
Nährwert.


Und "PORTD = 0;" setzt gleichzeitig RD und WR auf 0, was den SJA nun
völlig durcheinander bringt.


Gewöhn Dich besser an die ANSI-C-Syntax, also schreibe:

#define WR PORTD0
#define RD PORTD1

PORTD |= 1<<WR^1<<RD; // setzte beide auf 1

PORTD &= ~(1<<WR); // setze WR auf 0

usw.

Die Bitbefehle vom Codevision sind nicht portabel und verschleiern Dir
aber den Byte-Zugriff.
Sie haben Dich daher durcheinander gebracht, anstatt Dir zu nützen.

Deshalb benutzen die C-Profis nur die Maskenoperatoren & (AND) und |
(OR) und ^ (EXOR). Das ist portabel und wird bei guten Compilern auch
optimiert.



Peter

von Leo (Gast)


Lesenswert?

So ich habe jetzt das Programm noch einwenig abgeändert.

void init(void);
void schreiben(unsigned char adresse, unsigned char daten);
unsigned char lesen(unsigned char adresse);

// Declare your global variables here
void init(void)
{
 PORTB = 0;
 DDRB = 0xFF;
 PORTD = 0;
 DDRD = 0xFF;
 ALE = 0;
 RD = 1;
 WR = 1;
}

void schreiben(unsigned char adresse, unsigned char daten)
{
 ALE = 1;
 PORTB = adresse;
 ALE = 0;

 PORTB = daten;
 WR = 0;
 WR = 1;
}

unsigned char lesen(unsigned char adresse)
{
 unsigned char daten = 0;
 ALE = 1;
 PORTB = adresse;
 ALE = 0;

 DDRB = 0x00;
 RD = 0;
 daten = PINB;
 RD = 1;
 return daten;
}

void main(void)
{
init();
schreiben(0x04,0x55);
sprintf(text," Daten = %3.0u",lesen(0x04));
lcd_gotoxy(0,0);
lcd_puts(text);

while (1)
      {};
}

Misst läuft immer noch nicht! Hmmmm...

von Leo (Gast)


Lesenswert?

So hab das Programm ein bisschen verändert.

#define ALE PORTD.3
#define WR PORTD.6
#define RD PORTD.5
#define HIGH 1;
#define LOW 0;

void init(void);
void schreiben(unsigned char adresse, unsigned char daten);
unsigned char lesen(unsigned char adresse);

// Declare your global variables here
void init(void)
{
 PORTB = 0;
 DDRB = 0xFF;
 ALE = 0;
 RD = 1;
 WR = 1;
}

void schreiben(unsigned char adresse, unsigned char daten)
{
 ALE = 1;
 PORTB = adresse;
 ALE = 0;

 PORTB = daten;
 WR = 0;
 WR = 1;
}

unsigned char lesen(unsigned char adresse)
{
 unsigned char daten = 0;
 ALE = 1;
 PORTB = adresse;
 ALE = 0;

 DDRB = 0x00;
 RD = 0;
 daten = PINB;
 RD = 1;
 return daten;
}

void main(void)
{
init();
schreiben(0x04,0x55);
sprintf(text," Daten = %3.0u",lesen(0x04));
lcd_gotoxy(0,0);
lcd_puts(text);

while (1)
      {};
}

von OldBug (Gast)


Angehängte Dateien:

Lesenswert?

Hab mal versucht, Deine Konfiguration mit in meine Headerfiles
einzubauen. Ich kann diesen Code leider nicht Testen.
Wenn irgendwas nicht klappt, dann einfach die Fehlermeldung oder was
auch immer hier Posten...

Viel Erfolg,
Patrick...

von Leo (Gast)


Lesenswert?

Hallo Patrick!

Danke für den Code!Trotzdem schaffe ich es einfach nicht,
Daten von dem CAN-Controller abzufragen????
So wie ich das Programm geschrieben habe müsste es doch funktionieren.
Ich weiss nicht was ich da noch falsch gemacht habe!

#define ALE PORTD.3
#define WR PORTD.6
#define RD PORTD.5
#define HIGH 1;
#define LOW 0;

void init(void);
void schreiben(unsigned char adresse, unsigned char daten);
unsigned char lesen(unsigned char adresse);

// Declare your global variables here
void init(void)
{
 PORTB = 0;
 DDRB = 0xFF;
 DDRD = 0xFF;
 ALE = 0;
 RD = 1;
 WR = 1;
}

void schreiben(unsigned char adresse, unsigned char daten)
{
 ALE = 1;
 PORTB = adresse;
 ALE = 0;

 PORTB = daten;
 WR = 0;
 WR = 1;
}

unsigned char lesen(unsigned char adresse)
{
 unsigned char daten = 0;
 ALE = 1;
 PORTB = adresse;
 ALE = 0;

 RD = 0;
 daten = PORTB;
 RD = 1;
 return daten;
}

void main(void)
{


init();
schreiben(0x04,0x55);
sprintf(text," Daten = %3.0u",lesen(0x04));
lcd_gotoxy(0,0);
lcd_puts(text);

while (1)
      {};
}

von Leo (Gast)


Lesenswert?

Hmm...hab noch bei meinem Programm was vergessen!

Siehe Funktion lesen:

unsigned char lesen(unsigned char adresse)
{
 unsigned char daten = 0;
 ALE = 1;
 PORTB = adresse;
 ALE = 0;

 DDRB = 0x00;
 RD = 0;
 daten = PORTB;
 RD = 1;
 return daten;
}

von Leo (Gast)


Lesenswert?

Kann mir jemand dabei Helfen!
Ich weiss nicht was ich noch an dem Programm verändern soll.
Um Rat wäre ich sehr dankbar!

MfG Hennse

von Stefan Kleinwort (Gast)


Lesenswert?

Das sieht eigendlich jetzt schon ganz gut aus.
Was mir noch aufgefallen ist: die Rückgabe kenne ich nur mit Klammern,
also in Deinem Programm:
  return(daten);

Wenn Du nicht weiterkommst, dann leg Deine Schreibroutine mal in eine
Endlosschleife und messe die Signale mit dem Oszi nach. Danach dasselbe
mit der Leseroutine. Um herauszufinden, ob die Pins auch wirklich Ein-
bzw. Ausgang sind: mit einem 10kohm-R nach Masse oder VCC ziehen, nur
wenn der Pin Eingang sein soll, darf sich was ändern.

Wie gesagt, sonst fällt mir auch nichts auf.
Bitte nicht privat mailen, wenn ich eine Idee bzw. Zeit zum Antworten
habe, melde ich mich schon, ausserdem sollen ja auch andere an Deinem
Problem lernen können.

Stefan

von Peter D. (peda)


Lesenswert?

Langsam wirds.

Hast Du Dir denn wirklich nicht mal das SJA-Timing angesehen ?

Nach dem Lesen must Du doch wieder auf Ausgang schalten, sonst geht das
nächste Lesen / Schreiben gegen den Baum:


unsigned char lesen(unsigned char adresse)
{
 unsigned char daten;
 ALE = 1;
 PORTB = adresse;
 ALE = 0;

 DDRB = 0x00;
 RD = 0;
 daten = PORTB;
 RD = 1;
 DDRB = 0xFF;
 return daten;
}



Peter

von Leo (Gast)


Lesenswert?

Jetzt hab ich mal mit dem Oszi den Takt überprüft.
--> Taktfrequenz nicht vorhanden.

Hmmm..dann ist auch klar warum der CAN-Controller nicht arbeitet.

von Leo (Gast)


Angehängte Dateien:

Lesenswert?

So jetzt hab ich mal noch die Hardware überprüft. takt ist diesesmal
vorhanden.
Ich habe keinen Fehler entdeckt.
Die Software habe ich auch verbessert. Nichts tut sich.
Ich weiss jetzt nicht was ich noch tun kann!

von Leo (Gast)


Lesenswert?

Was mir noch einfällt.
Den AVR versorge ich mit 8Mhz und den CAN-Controller mit 16Mhz.
Macht das was aus wenn die Frequenzen unterschiedlich sind????

von Leo (Gast)


Lesenswert?

So...jetzt glaube ich das der CAN Controller defekt ist.
Was anderes kann ich mir nicht vorstellen!

Für Hilfe wäre ich sehr sehr dankbar!

von Leo (Gast)


Lesenswert?

Brauche dringend Unterstützung!!!!

von Leo (Gast)


Lesenswert?

Was mir noch einfällt, ist das überhaupt richtig, dass das CS immer
auf Ground liegt???

Werden die Adressen erst übernommen wenn das ALE Signal anliegt oder
muss
ich noch das WR Signal aktivieren?

von Leo (Gast)


Lesenswert?

Mir hat jemand erzählt, dass das CS Signal nicht direkt auf Masse gelegt
werden soll! Stimmt dies???

von Peter D. (peda)


Lesenswert?

Erwartest Du im Ernst, daß jemand für Dich das Datenblatt lesen soll
???

Wenn Du keinen Oszi hast, um das Timing  mit dem im Datenblatte zu
vergleichen, dann nimm einen Taster und eine Entprellroutine und
"taste" Dich Schritt für Schritt durch (LEDs mit Vorwiderständen an
alle Signale).

Warte nicht immer, bis Dir jemand den nächsten Schritt vorsagt, treibe
mal selber ein bischen Debugaufwand.

Prüfe was fehlschlägt, das Lesen oder das Schreiben. Z.B. kannst Du den
Takt setzen bzw. abschalten oder die TXD-Pins einschalten.
Lese von verschiedenen Adressen, vergleiche, was rauskommt usw.


Peter

von Peter D. (peda)


Lesenswert?

P.S. "Durchtasten" kann man auch mit getchar().

von Leo (Gast)


Lesenswert?

Warum ich hab mich doch an das Datenblatt gehalten!
Ich habe mitbekommen das man das CS Signal nicht auf Masse legen soll,
sondern separat über einen Port bedienen soll!
Vielleicht liegt es auch daran.

von Peter D. (peda)


Lesenswert?

"Ich habe mitbekommen das man das CS Signal nicht auf Masse legen
soll,
sondern separat über einen Port bedienen soll!"

Wo steht das denn im Datenblatt ?



Vielleicht stellst Du mal Deine Schaltplan hier rein:

- alle VCC und GND angeschlossen ?
- Intel-Mode selektiert ?
- Reset ordentlich gemacht ?
- ist ein Takt am Taktausgang zu sehen ?
- keine Lötbrücken, Unterbrechungen ?


Versuch doch wirklich mal die einzelnen Schritte zu debuggen, entweder
über die UART oder mit Taster und LEDs.

Mach ich ja genauso, wenn eine Funktion nicht als Ganzes geht, zerlege
ich sie in Einzelschritte, notfalls bis runter zum einzelnen Befehl.


Peter

von Leo (Gast)


Angehängte Dateien:

Lesenswert?

Hallo Peter!

1. alle VCC und GND angeschlossen
2. Intel-Mode aktiviert.
3. zwischen VCC und Reset-Eingang vom AVR habe ich einen 10kOhm
Widerstand reingelötet.
4. Takt von 16Mhz vorhanden.
5. keine Lötbrücken bzw. Kurzschlüsse vorhanden.
6. Ich kann sogar die Daten einlesen. (DDRB = 0x00 funktioniert)
7. Steuerleitungen (ALE  RD  WR) funktionieren.

Ich habe mal das veränderte Programm hier gepostet.

von Leo (Gast)


Angehängte Dateien:

Lesenswert?

Hier habe ich mal noch das Timing vom SJA1000 gepostet!

von Leo (Gast)


Lesenswert?

Also jetzt habe ich mal Schritt für Schritt alles gecheckt, aber
leider ohne Erfolg! Hmmm....
Ich denke es liegt doch an der Software. (Siehe Prog. AVR-CAN.c)
Aber wass soll ich da noch verändern. Hab alle möglichen Varianten
geprüft.

von Peter D. (peda)


Lesenswert?

Ich kann immer nur wiederholen, das Datenblatt ist Dein Freund, lies es
gründlich !!!

Z.B. steht da drin, daß im Operating Mode von Adresse 0x04 immer 0xFF
gelesen wird.

Ein Controller ist kein SRAM, d.h. Du kannst nur bestimmte Bits setzen
und rücklesen, je nach Mode.



Peter

von Leo (Gast)


Lesenswert?

Hallo Peter!

Jetzt habe ich es endlich geschaft!
Kann Daten lesen und schreiben.

Was ich noch vergessen habe ist, das ich in der lese Routine
--> daten = PORTB verwendet habe.
Da muss nämlich --> daten = PINB stehen.
Also ich denke mal das es Funktioniert.
Hab z.B. Adresse 0x02 angewählt und einen Wert reingeschrieb(z.B.
0x12). Siehe da, ich konnte das Daten Byte auslesen --> 0x12.
Somit müsste das jetzt so stimmen.

von Leo (Gast)


Lesenswert?

Hallo Peter!

Endlich habe ich es geschaft. Ich kann Daten lesen und schreiben.
In der LESE routine habe ich PORTB statt PINB benutzt. (-->daten =
PINB)

Z.B. habe ich die Adresse 0x02 angesprochen und den Wert 0x12
reingeschrieben.
Siehe da, ich konnte das Datenbyte 0x12 auslesen. Somit müsste das
ganze auch funktionieren.

MfG Hennse

von Leo (Gast)


Lesenswert?

Hallo Peter!

Endlich habe ich es geschaft. Ich kann Daten lesen und schreiben.
In der LESE routine habe ich PORTB statt PINB benutzt. (-->daten =
PINB)

Z.B. habe ich die Adresse 0x02 angesprochen und den Wert 0x12
reingeschrieben.
Siehe da, ich konnte das Datenbyte 0x12 auslesen. Somit müsste das
ganze auch funktionieren.

MfG Hennse

von Peter D. (peda)


Lesenswert?

Kann jedem mal passieren.

Ich mache viel mit dem 8051 und da gibt es diese Unterscheidung nicht.
Deshalb ist es mir bei Deinem Code auch nicht aufgefallen.

Vielleicht wäre es mir aufgefallen, wenn Du gesagt hättest, daß Du
immer die Adresse zurück liest. Du hast aber immer nur gesagt, es geht
nicht.


Peter

von Leo (Gast)


Lesenswert?

Vielen Dank Peter!

Deine Unterstützung war hilfreich.
Ich denke jetzt mal wenn ich Daten auslesen kann wie in diesem
Beispiel dann wird dies auch so korrekt sein oder???
Ein Zufallswert kann es ja nicht sein!

von Leo (Gast)


Lesenswert?

Nur noch eine Frage:

Wenn ich z.B. das Register 0x02 mit dem Wert 0x12 beschreibe und
ich unterbreche die Versorgungsspannung, dann kann ich den Wert von
0x12 nicht mehr auslesen. Hat der SJA nur ein SRAM???

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.