mikrocontroller.net

Forum: Compiler & IDEs SPI Daten aufnehmen


Autor: Dirk (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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);
  }
}

Autor: Dirk (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hi,

mein Master AVR sendet 0000 1111. Mein Slave AVR erhaelt immer 1000
0111.

Autor: Dirk (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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

Autor: Andreas Schwarz (andreas) (Admin) Benutzerseite Flattr this
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Nächstes Mal bitte den Code in den Anhang, steht doch deutlich da.

Autor: mthomas (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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".

Autor: Dirk (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hi,

ich danke Dir. Es funktioniert nun ich hoffe es geht spaeter auch an
der realen Hardware.

Mfg

Dirk

Autor: peter dannegger (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
"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

Autor: Dirk (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.