Hallo Profis, ich hab mal wieder ein Grundlagenproblem: Und zwar habe ich anhand des Datenblatts vom ATmega8 und einiger Threads dieses Forums den Controller nun so weit gebracht, dass er sendet. Der Code: ******************************************************************** //HAUPTPROGRAMM int main (void) { SPI_MasterInit(); sei(); for(;;) { SPI_MasterTransmit(0xff); _delay_us(20); SPI_MasterTransmit(0x00); _delay_us(20); } return 0; } //Funktionen void SPI_MasterInit(void) { /* Set MOSI and SCK output, all others input */ DDRB |= (1<<PB2) | (1<<PB3) | (1<<PB5); /* Enable SPI, Master, set clock rate fck/16 */ SPCR = (1<<SPE)|(1<<MSTR)|(1<<SPR0); } void SPI_MasterTransmit(char cData) { /* Start transmission */ SPDR = cData; /* Wait for transmission complete */ while(!(SPSR & (1<<SPIF))) ; } *********************************************************************** Nun meine Frage: Ich will SPI nutzen, um einen Sensor auszulesen. Dazu muss erst ein char an den Sensor gesendet werden, damit dieser weiß was ich von ihm will. Anschließend sendet dieser ein 11Bit-Wort zurück an den Controller. Nur: Wie empfange ich?? Vor allem ein 11Bit-Wort. Danke für Eure Hilfe. Gruß Tom
Was ist mit dem /SS Signal. Benötigst du eins? P.S. Is das ein VTI Sensor????
So nochmal. Hatte das Problem auch mal mit nem VTI Sensor. Wenn der vom Sensor ein 11Bit Signal bekommen hat habe ich zuerst einen 8Bit Befehl gesendet und im Anschluss 2 Dummybytes gesendet (0x00). Die ausbleibende Frequenz war dem Sensor egal, da er seinen Takt vom Controller bekommen hat. Zwischen den Dummybefehlen natürlich den Speicher auslesen.
Ja, es ist ein Sensor von VTI. Und zwar der SCA1000. Dieser wird dann in der Prototypenphase durch den SCA61T getauscht. Ich hoffe jedoch, dass beide identische Werte über SPI senden/erwarten. Verwendest Du ähnliche Sensoren? Bzgl. /SS: Muss ich erst PB2 (also /SS) auf Low, dann senden und dann auf Antwort vom Sensor warten?
Hallo Gast, könntest Du mir das evtl etwas genauer erklären mit den Dummybytes? Heißt das: - 8Bit Kommando - 1. Dummybyte - Speicher auslesen - 2. Dummybyte - Speicher auslesen Oder verstehe ich das falsch?
Wenn der Mega8 als Master fungiert, kannst du einen X-beliebigen Portpin nehmen. Als Slave allerdings wird durch externes Low-ziehen des SS-Pins die Empfangsroutine angeworfen. MW
Ich hatte den SCA100T. 1. /SS auf low (so war es bei mir mußte im Datenblatt gucken ob high oder low) 2. 8Bit-Befehl senden 3. Dummybyte 0x00 senden 4. Empfangsspeicher auslesen 5. Dummybyte 0x00 senden 6. /SS auf high So war das bei mir. Habe leider kein Codebeispiel zur Hand, kann das aber heute Abend nachlegen bei Bedarf.
Hallo Gast, das wäre echt super nett von Dir, wenn ich den Code bekommen könnte. Es sind nämlich (fast) identische Sensoren. Nun die vielleicht blödeste aller Fragen: Wie sieht die Funktion fürs Empfangen aus und wo/was ist der Empfangsspeicher? Vielen Dank und Beste Grüße Tom
Einfach das Register auslesen und feddich. Mußt event noch die SPI danach wieder freischalten (Flags)??!!?? Das weiß ich aber nicht so genau. Atmel is schon zu lange her. Werde den Code später mal posten.
Anbei wie versprochen der Code für den SCA100T
1 | int read_x_channel(void) |
2 | {
|
3 | short x1,x2; |
4 | int x3, xGes; |
5 | |
6 | PORTB = (0 << PB0); //SS auf low setzen |
7 | SPDR = 0x10; //Befehl read X-Channel in SPDR |
8 | while(!(SPSR & (1<<SPIF))); //Warten bis Empfangsende |
9 | x1 = SPDR; //Wert x1 aus DR wird gespeichert |
10 | x3 = x1<<3 //x1 wird um 3 verschoben |
11 | SPDR = 0x0c; //Dummybyte |
12 | while(!(SPSR & (1<<SPIF))); //s.o. |
13 | x2 = SPDR; //Wert x2 aus DR wird gespeichert |
14 | x2 = x2 >> 5; //x2 wird korregiert/ Verschieben um 5 Stellen |
15 | |
16 | xGes = x3 + x2; //Endwert wird berechnet |
17 | PORTB = (1 << PB0); //SS auf high setzen |
18 | |
19 | return (xGes); //Endwert wird zurück gegeben |
20 | }
|
Nicht schön aber läuft
oder du machst das ganze über Software SPI, dann kannst du tatsächlich genau 11 Bit auslesen, aber wie heißt es so schön: "Never change a working system"
Hallo zusammen, nochmals vielen Dank für Eure Hilfe. Heute hab ich den neuen Sensor bekommen (SCA61T) mit folgendem Code will ich dem an den Pelz: ***********************************************************************+ //HAUPTPROGRAMM int main (void) { SPI_MasterInit(); sei(); DDRD = 0xff; while(1) { short x1, x2; int x3, xGes; PORTB = (0 << PB2); //SS auf Low SPDR = 0x10; //Kommando "Read X-Channel" in SPDR while(!(SPSR & (1<<SPIF))); //Warten auf Empfangsende x1 = SPDR; //Wert x1 aus SPDR auslesen x3 = x1>>3; //x1 um drei Stellen verschieben SPDR = 0x0c; //Dummybyte senden while(!(SPSR & (1<<SPIF))); //Warten auf Empfangsende x2 = SPDR; //Wert x2 aus SPDR auslesen //x2 = x2 >> 5; //Wert x2 um fünf Stellen verschieben xGes = x3 + x2; //Gesamtwert errechnen PORTB = (1<<PB2); // /SS auf High PORTD = x2; _delay_ms(50); } return 0; } //Funktionen void SPI_MasterInit(void) { /* Set MOSI and SCK output, all others input */ DDRB |= (1<<PB2) | (1<<PB3) | (1<<PB5); /* Enable SPI, Master, set clock rate fck/32 */ SPCR = (1<<SPE) | (1<<MSTR) | (1<<SPR1); } ******************************************************************** Zur Visualisierung während den Tests will gebe ich immer ein Byte an PORTD aus (hier x2). x2 wird auch super ausgelesen, alles passt. Aber wenn ich x1 ausgebe, erhalte ich nur 1en. Was muss ich ändern, damit das funzt? Beste Grüße Tom
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
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.