Hallo, ich wollte ein SPI Bus Sniffer in C programmieren. Leider komme ich nicht zum richtigen Ergebnis und hoffe auf ein wenig Unterstuetzung. Die Daten werden vom meinem Master AVR recht simpel ausgegeben. Im IdleMod ist CLOCK = HIGH. Ich trigger auf die fallende Flanke des Clocksignal's , wenn das Clock Signal auf LOW geht lese ich den Zustand vom DATA Pin ein und trigger auf die steigende Flanke des CLOCK Signals. Danach shifte ich meine Daten um 1 Bit nach links (die Daten kommen spaeter MSB). Die Schleife wird 8 mal ausgefuehrt um einen Byte zuerhalten. Sende ich zum Slave 0xF0 funktioniert es, wenn aber das LSB != 0 ist geht es nicht mehr. Ich hoffe mir kann jemand ein kleinen Denkanstoss geben. Mfg Dirk ---- Master Code ---- #include <avr/io.h> #include <avr/interrupt.h> #include <avr/signal.h> #include <stdio.h> #include <avr/delay.h> #include <avr/pgmspace.h> #include <stdlib.h> #include "uart.h" #define XTAL_CPU 4000000 #define UART_BAUD_RATE 19200 // 9600 baud * #define SNIFFER_PORT PORTD #define CLK 7 #define DATA 6 #define CLKHIGH SNIFFER_PORT |= (1<<CLK); #define CLKLOW SNIFFER_PORT &= ~(1<<CLK); #define DATAHIGH SNIFFER_PORT |= (1<<DATA); #define DATALOW SNIFFER_PORT &= ~(1<<DATA); volatile unsigned char i; unsigned char s[30]; int main( void ) { DDRD = 0xFF; // AUSGANG CLKHIGH for(i=0;i<200;i++) { _delay_ms(1); } for(;;) { for(i=0;i<4;i++) { CLKLOW _delay_ms(1); DATALOW _delay_ms(1); CLKHIGH _delay_ms(1); } for(i=0;i<4;i++) { CLKLOW _delay_ms(1); DATAHIGH _delay_ms(1); CLKHIGH _delay_ms(1); } CLKHIGH _delay_ms(20); _delay_ms(20); _delay_ms(20); _delay_ms(20); _delay_ms(20); _delay_ms(20); _delay_ms(20); _delay_ms(20); _delay_ms(20); _delay_ms(20); _delay_ms(20); _delay_ms(20); _delay_ms(20); _delay_ms(20); _delay_ms(20); _delay_ms(20); _delay_ms(20); _delay_ms(20); _delay_ms(20); _delay_ms(20); _delay_ms(20); _delay_ms(20); _delay_ms(20); _delay_ms(20); _delay_ms(20); } } ---- Slave Coe ---- #include <avr/io.h> #include <avr/interrupt.h> #include <avr/signal.h> #include <stdio.h> #include <avr/delay.h> #include <avr/pgmspace.h> #include <stdlib.h> #include "uart.h" #define XTAL_CPU 7372800 #define UART_BAUD_RATE 115200 // 9600 baud * #define SNIFFER_PIN PIND #define CLK 2 #define DATA 3 volatile unsigned char spi_data; volatile unsigned char counter; unsigned char s[30]; int main( void ) { DDRD = 0x00; // PORTD = INPUT PORTD = 0xFF; // PULL UP's ON uart_init( UART_BAUD_SELECT(UART_BAUD_RATE,XTAL_CPU) ); // UART INIT sei(); // GLOBALE INT's ON for(;;){ uart_puts_P("START TRIGGERING\n\r"); _delay_ms(20); spi_data = 0x00; counter = 0x00; do{ if(!(SNIFFER_PIN & (1<<CLK))) // if clock = 0 check DATA PIN { if(!(SNIFFER_PIN & (1<<DATA))) // if DATAPIN = LOW { spi_data <<=1; spi_data |= 0x00; }else{ // if DATAPIN = HIGH spi_data <<=1; spi_data |= 0x01; } while (!( SNIFFER_PIN & (1<<CLK) )) ; // warten bis steigende flanke auf CLK counter++; } }while(counter<8); // 8Bit (1Byte) einlesen uart_puts_P("Byte: "); itoa(spi_data , s, 2); // Key Code uart_puts(s); uart_puts_P("\n\r"); spi_data = 0; counter = 0; _delay_ms(1); } }
Hi, vielleicht hilft es weiter: Ich sende 0000 1111 und empfange 1000 0111. Ich sende 0001 1000 und empfange 1100 0000. Anscheinend shifte ich meine Daten zu oft, aber ehrlich gesagt sehe ich den Fehler nicht. Mfg Dirk
Nur Vermutung: Vielleicht ein Timing-Problem, Clock Low, Daten aber "noch nicht" richtig gesetzt (delay zw. clock low und DATA* im Sender) aber werden dennoch schon gesampled. Testweise vielleicht im Sender erst Datenpin setzen und dann Clock "stroben".
Hi, ich danke Dir. Es funktioniert nun ich hoffe es geht spaeter auch an der realen Hardware. Mfg Dirk
"Es funktioniert nun" Das ist reiner Zufall ! Der Trick beim SPI ist, Du brauchst ein Strobe-Signal. Damit wird dann dem Slave gesagt, wann ein neues Byte oder Datenpaket beginnt und wann es zuende ist. Manche Slaves haben auch noch zusätzlich ein Startbit, d.h sie ignorieren alle Takte, bis ein 1-Bit kommt. Bei diesen kann man dann den Strobe-Eingang fest auf GND legen. Ohne Strobe oder Startbit hast Du keine Chance, beide Teilnehmer zu synchronisieren. Peter
Hi, ich hatte zu spaet gesehen das die eigentliche Hardware ein Chip Select Pin aktiviert bevor die Uebertragung beginnt. Aus diesem Grund bin ich auf den HW Spi meines Mega's umgestiegen. Es funktioniert nun Tadellos. Mfg Dirk
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.