IOWarrior und SPI
Moderator: Guido Körber
IOWarrior und SPI
Bin neuling und versuche seit kurzem ein Programm zu schreiben.
Ich muß ein Chip von Atmel AT89S52 über die SPI Schnittstelle programmieren.
Ich suche einen Beispielcode, womit ich die SPI aktivieren kann und folgende Daten in Hex 85 A0 80 02 senden kann.
Nächste Frage. Wenn ich die SPI aktivire, bekomme ich sofort das Clock-Signal?
danke in voraus
gruß
Ich muß ein Chip von Atmel AT89S52 über die SPI Schnittstelle programmieren.
Ich suche einen Beispielcode, womit ich die SPI aktivieren kann und folgende Daten in Hex 85 A0 80 02 senden kann.
Nächste Frage. Wenn ich die SPI aktivire, bekomme ich sofort das Clock-Signal?
danke in voraus
gruß
-
- Site Admin
- Posts: 2856
- Joined: Tue Nov 25, 2003 10:25 pm
- Location: Germany/Berlin
- Contact:
- Christoph Jung
- Posts: 670
- Joined: Sun Oct 08, 2006 3:43 pm
- Location: Germany / Berlin
- Contact:
Guido hat recht, steht im Sample der Temperaturmessung.
Aber das sollte ungefähr so aussehen:
So sollte das ungefähr aussehen. Schau aber nochmal im Sample und im Datenblatt nach, weil ich mir mit dem Bytes[0] beim schreiben nicht so sicher bin.
Aber das sollte ungefähr so aussehen:
Code: Select all
IOWKIT_SPECIAL_REPORT report;
// Aktivieren des SPI-Mode
report.RportID = 0x8;
report.Bytes[0] = 0x01;
report.Bytes[1] = 0x07;
IowKitWrite(); //zu faul zum tippen ;)
//Schreiben deiner Bytes
report.ReportID = 0x9;
report.Bytes[0] = 0x02;
report.Bytes[1] = 0x85;
report.Bytes[2] = 0xA0;
report.Bytes[3] = 0x80;
report.Bytes[4] = 0x02;
IowKitWrite();
Hallo
Mit der Aktivierung der Scnittstelle bin ich klar gekommen.
report.RportID = 0x8;
report.Bytes[0] = 0x01;
report.Bytes[1] = 0x03;
Hier musste ich aber 03 eingeben. Laut Datenblatt von AT89S52.
Wo ich immer noch nicht durchblicke, ist die Flagsetzung bei report 9.
Wieso kommst du auf 0x02 bei report.Byte[0].
Ist das so, wenn ich z.B. report.Bytes[0] = 0x44; eingebe, dann habe ich folgendes eingestellt.
useDRDY=0; SSactive=1; ignoreDRDY=0;.... und der Rest???
Muß ich beim ersten mal alles einstellen?.
z.B. ob ich mit LSB anfange? dann wäre es 0x41 oder?
wenn ich mit MSB anfange dann 0x44?
Und wie stelle ich den "data count" ein?
Mit der Aktivierung der Scnittstelle bin ich klar gekommen.
report.RportID = 0x8;
report.Bytes[0] = 0x01;
report.Bytes[1] = 0x03;
Hier musste ich aber 03 eingeben. Laut Datenblatt von AT89S52.
Wo ich immer noch nicht durchblicke, ist die Flagsetzung bei report 9.
Wieso kommst du auf 0x02 bei report.Byte[0].
Ist das so, wenn ich z.B. report.Bytes[0] = 0x44; eingebe, dann habe ich folgendes eingestellt.
useDRDY=0; SSactive=1; ignoreDRDY=0;.... und der Rest???
Muß ich beim ersten mal alles einstellen?.
z.B. ob ich mit LSB anfange? dann wäre es 0x41 oder?
wenn ich mit MSB anfange dann 0x44?
Und wie stelle ich den "data count" ein?
0x02 ist umgangssprachlich :stippe wrote: Wo ich immer noch nicht durchblicke, ist die Flagsetzung bei report 9.
Wieso kommst du auf 0x02 bei report.Byte[0].
useSRDY wird nicht verwendet,
SSactive wird nach diesem Report zurückgesetzt. Die meisten SPI-Slaves erwarten nur wenige Bytes in einem Kommando. Mein LCD-Display braucht z.B.. immer nur 2 Bytes. Dafür wäre diese Einstellung richtig.
ignoreDRDY ist nicht gesetzt. Das macht auch nur Sinn wenn man useDRDY gesetzt hatte.
Und es werden 2 Bytes übertragen. Da kommt jetzt die 2 im report.Byte[0] her.
Das ergibt :Ist das so, wenn ich z.B. report.Bytes[0] = 0x44; eingebe, dann habe ich folgendes eingestellt.
useDRDY=0; SSactive=1; ignoreDRDY=0;.... und der Rest???
Ich verwende kein DRDY;
Nach der Übertragung bleibt das Signal SS aktiv, weil ich noch mehr Daten übertragen will.
Ich will 4 Bytes zum Slave schicken.
Die eigentlichen Daten müssen dann in report.Byte[1] bis report.Byte[4] stehen.
Ob diese Einstellungen nun für den AT89S52 richtig sind weiß ich nicht. Wieviele Bytes sollen denn zu Gerät geschickt werden? (Wenn es <=6 Bytes sind reicht ein einzelner Report bei dem SSactive auf 0 gesetzt ist. Um nur 4 Bytes an den Slave zu schicken würde man folgenden Report erstellen:
report.Id=0x09;
report.Byte[0]=0x04; Kein Handshake, SS wird nach Ende der Übertragung wieder auf High gesetzt, Es werden 4 Bytes übertragen.
report.Byte[1]=Data1
report.Byte[2]=Data2
report.Byte[3]=Data3
report.Byte[4]=Data4
report.Byte[5]=Dieser Wert ist egal, er wird nicht übertragen
report.Byte[6]=Dieser Wert ist egal, er wird nicht übertragen
Die MSB/LSB Einstellungen werden nur bei der Initialisierung des SPI-Mode einmal gesetzt (ReportId=0x08) und dann solange verwendet bis der SPI-Mode wieder abgeschaltet wird.Muß ich beim ersten mal alles einstellen?.
z.B. ob ich mit LSB anfange? dann wäre es 0x41 oder?
wenn ich mit MSB anfange dann 0x44?
Ich hoffe das hilft weiter?
Eberhard
- Christoph Jung
- Posts: 670
- Joined: Sun Oct 08, 2006 3:43 pm
- Location: Germany / Berlin
- Contact:
@ Stippe:
Hab da oben nen Tippfehler drin...ist natürlich
Wäre ja sonst quatsch. Aber vom Prinzip ist es das selbe in pink ^^
@ wayoda:
Nett erklärt. Hab sogar ich verstanden ^^
Wäre nen gutes FAQ, wenn wir die Datenblätter nicht hätten
Hab da oben nen Tippfehler drin...ist natürlich
Code: Select all
report.Bytes[0] = 0x04;
@ wayoda:
Nett erklärt. Hab sogar ich verstanden ^^
Wäre nen gutes FAQ, wenn wir die Datenblätter nicht hätten
Hallo und Dankeschön für die prompte Antwort
Ich benutze SS für den RESET und der sollte für ca. 500ms auf low gehen und erst dann kann ich Daten schicken. Und SS solte möglichst ohne Unterbrechngen auf low bleiben. (µC braucht HIGH für RESET, habe aber einen Inverter davor gesetzt.)
Laut Datenblatt muß ich 6 Bytes schicken um weitere Daten, ohne Unterbrechung der SS, zu schreiben.
d. h. ich warte 500ms und erst dann kann ich Daten schicken.
Progrmming enable AC 53 xx xx
Chip Erase AC 8x xx xx
Dann wäre da folgendes
Wärend des Vorgangs darf SS nicht den Zustand ändern.
Also immer auf LOW. Und ich schätze der Datenfluß darf nicht unterbrechen. (SCK immer konstant weiterlaufen)
Übrigens gute Erklärung
Danke nochmals
Artur
Ich benutze SS für den RESET und der sollte für ca. 500ms auf low gehen und erst dann kann ich Daten schicken. Und SS solte möglichst ohne Unterbrechngen auf low bleiben. (µC braucht HIGH für RESET, habe aber einen Inverter davor gesetzt.)
Laut Datenblatt muß ich 6 Bytes schicken um weitere Daten, ohne Unterbrechung der SS, zu schreiben.
Code: Select all
printf("SPI enable\n");
report.ReportID = 0x08;
report.Bytes[0] = 0x01;
report.Bytes[1] = 0x03;
IowKitWrite(devHandle, IOW_PIPE_SPECIAL_MODE, (char *) &report, sizeof(report));
IowKitSetWriteTimeout(iows[i], 1000);
}
printf("programming enable\n");
memset(&report, 0, sizeof(report));
report.ReportID = 0x09;
report.Bytes[0] = 0x46;
report.Bytes[1] = 0x00;
report.Bytes[2] = 0x00;
report.Bytes[3] = 0x00;
report.Bytes[4] = 0x00;
report.Bytes[5] = 0x00;
report.Bytes[6] = 0x00;
IowKitWrite(devHandle, IOW_PIPE_SPECIAL_MODE, (char *) &report, IOWKIT_SPECIAL_REPORT_SIZE);
IowKitRead(devHandle, IOW_PIPE_SPECIAL_MODE, (char *) &report, IOWKIT_SPECIAL_REPORT_SIZE);
Sleep(500);
Progrmming enable AC 53 xx xx
Chip Erase AC 8x xx xx
Dann wäre da folgendes
Code: Select all
report.ReportID = 0x09;
report.Bytes[0] = 0x46;
report.Bytes[1] = 0xAC;
report.Bytes[2] = 0x53;
report.Bytes[3] = 0x00;
report.Bytes[4] = 0x00;
report.Bytes[5] = 0xAC;
report.Bytes[6] = 0x80;
IowKitWrite(devHandle, IOW_PIPE_SPECIAL_MODE, (char *) &report, IOWKIT_SPECIAL_REPORT_SIZE);
IowKitRead(devHandle, IOW_PIPE_SPECIAL_MODE, (char *) &report, IOWKIT_SPECIAL_REPORT_SIZE);
Code: Select all
report.ReportID = 0x09;
report.Bytes[0] = 0x42;
report.Bytes[1] = 0x00;
report.Bytes[2] = 0x00;
IowKitWrite(devHandle, IOW_PIPE_SPECIAL_MODE, (char *) &report, IOWKIT_SPECIAL_REPORT_SIZE);
IowKitRead(devHandle, IOW_PIPE_SPECIAL_MODE, (char *) &report, IOWKIT_SPECIAL_REPORT_SIZE);
Also immer auf LOW. Und ich schätze der Datenfluß darf nicht unterbrechen. (SCK immer konstant weiterlaufen)
Übrigens gute Erklärung
Danke nochmals
Artur
-
- Site Admin
- Posts: 2856
- Joined: Tue Nov 25, 2003 10:25 pm
- Location: Germany/Berlin
- Contact:
Habe folgendes Problem
memset(&report, 0, sizeof(report));
report.ReportID = 0x09;
report.Bytes[0] = 0x44;
report.Bytes[1] = 0xAC;
report.Bytes[2] = 0x53;
IowKitWrite(devHandle, IOW_PIPE_SPECIAL_MODE, (char *) &report, sizeof(report));
IowKitRead(devHandle, IOW_PIPE_SPECIAL_MODE, (char *) &report, sizeof(report));
memset(&report, 0, sizeof(report));
report.ReportID = 0x09;
report.Bytes[0] = 0x44;
report.Bytes[1] = 0xAC;
report.Bytes[2] = 0x53;
report.Bytes[3] = 0x80;
IowKitWrite(devHandle, IOW_PIPE_SPECIAL_MODE, (char *) &report, sizeof(report));
IowKitRead(devHandle, IOW_PIPE_SPECIAL_MODE, (char *) &report, sizeof(report));
Ich habe diesen Code geschrieben.
Die Datenübertragung konnte ich am Osszilloskop überprüfen.
Problem ist aber, daß ich nach dem ersten IowKitWrite(..) für ca 10ms eine Pause sehe. Das ist zu viel für den Microcontroller und somit wird die Datenübertragung wieder abgeschaltet.
Wie stelle ich das an, damit ich zwischen den Reports keine Verzögerung habe.
Oder ist das Hardware bedingt?
Vielen Dank in voraus
memset(&report, 0, sizeof(report));
report.ReportID = 0x09;
report.Bytes[0] = 0x44;
report.Bytes[1] = 0xAC;
report.Bytes[2] = 0x53;
IowKitWrite(devHandle, IOW_PIPE_SPECIAL_MODE, (char *) &report, sizeof(report));
IowKitRead(devHandle, IOW_PIPE_SPECIAL_MODE, (char *) &report, sizeof(report));
memset(&report, 0, sizeof(report));
report.ReportID = 0x09;
report.Bytes[0] = 0x44;
report.Bytes[1] = 0xAC;
report.Bytes[2] = 0x53;
report.Bytes[3] = 0x80;
IowKitWrite(devHandle, IOW_PIPE_SPECIAL_MODE, (char *) &report, sizeof(report));
IowKitRead(devHandle, IOW_PIPE_SPECIAL_MODE, (char *) &report, sizeof(report));
Ich habe diesen Code geschrieben.
Die Datenübertragung konnte ich am Osszilloskop überprüfen.
Problem ist aber, daß ich nach dem ersten IowKitWrite(..) für ca 10ms eine Pause sehe. Das ist zu viel für den Microcontroller und somit wird die Datenübertragung wieder abgeschaltet.
Wie stelle ich das an, damit ich zwischen den Reports keine Verzögerung habe.
Oder ist das Hardware bedingt?
Vielen Dank in voraus
-
- Site Admin
- Posts: 2856
- Joined: Tue Nov 25, 2003 10:25 pm
- Location: Germany/Berlin
- Contact:
Verstehe ich eigentlich nicht, das Prinzip der SPI-Interface ist doch, dass der Master (IOWarrior) die Übertragungsgeschwindigkeit steuert und der Slave (AT) nur auf die Änderungen am SCL-Eingang reagiert. Ich habe so etwas noch nicht gemacht, aber mal eben ins Datenblatt des AT geschaut. 2 Fragen sind mir eingefallen:stippe wrote: Die Datenübertragung konnte ich am Osszilloskop überprüfen.
Problem ist aber, daß ich nach dem ersten IowKitWrite(..) für ca 10ms eine Pause sehe. Das ist zu viel für den Microcontroller und somit wird die Datenübertragung wieder abgeschaltet.
1. Welcher Quarz ist am AT. Ich würde die Datenrate am IOWarrior beim Aktivieren des SPI-Mode ganz nach unten setzen (0.0625 MBit/sec)
2. Aktivieren der Programmierung am AT durch setzen des RESET-Eingangs. Was ich da gelesen habe fand ich missverständlich:
Muss man jetzt erst mal 10 ms warten nachdem RST auf HIGH gesetzt ist? Bei der Verwendung des /SS-Pins vom IOWarrior am RST des AT wird das wohl nicht funktionieren. (Ich würde vielleicht mal einen freien IO-PIN am IOWarrior für den RST verwenden, den ich per write-Befehl auf low(Inverter vor RST) setze. Dann die Bytes zur Programmierung schicken, zum Schluß den Pin wieder auf High.)1. Power-up sequence:
Apply power between VCC and GND pins.
Set RST pin to “H”.
If a crystal is not connected across pins XTAL1 and XTAL2, apply a 3 MHz to
33 MHz clock to XTAL1 pin and wait for at least 10 milliseconds.
Eberhard