SPI unstabil

Gast #1651768
Lesenswert?
• ▲
▼
Hallo Leute,

ich bin gerade dabei, mir ein LCD-Modul zu basteln, was ich über I2C und 
über SPI ansteuern kann. Auf dem Modul sitzt ein ATmega8, angesprochen 
wird es auch von ATmegas.
I2C funktioniert schon, allerdings habe ich mit dem SPI Probleme...
Manchmal funktioniert die Übertragung schlecht, manchmal garnicht, 
manchmal bricht sie zusammen...
Habe schon öfter mit SPI gearbeitet, aber noch nie solche Probleme 
gehabt...
Habe die beiden Platinen mit einem Flachbandkabel verbunden, schon 2 
verschiedene Sender ausprobiert (um Hardwarefehler auszuschließen). Auf 
dem LCD-Modul sollte auch kein Hardware-Fehler sein, die Leitungen sind 
sauber von einander getrennt.

Ansteuerroutinen sind folgende (Ausschnitt)
Sender
1
void lcdSPIInit(uint8_t operation){ //1: save SPI-settings, Init lcd SPI; 0: restore SPI
2
  static uint8_t spcr;
3
  static uint8_t spiPort, spiDDR;
4

5
  if(operation == 1){
6
    spcr = SPCR;
7
    spiPort = SPI_PORT;
8
    spiDDR = SPI_DDR;
9

10
    CHIPSELECT_DDR |= (1<<CHIPSELECT_PIN);
11

12
    SPCR = (1<<SPE) | (1<<MSTR) | (1<<SPR0);
13
    SPI_PORT |= (1<<MOSI_PIN) | (1<<SCK_PIN);
14
    SPI_DDR |= (1<<MOSI_PIN) | (1<<SCK_PIN);
15
    CHIPSELECT_PORT &= ~(1<<CHIPSELECT_PIN);
16
  }else if(operation == 0){
17
    CHIPSELECT_PORT |= (1<<CHIPSELECT_PIN);
18
    _delay_us(1);
19
    SPI_DDR = spiDDR;
20
    SPI_PORT = spiPort;
21
    SPCR = spcr;
22
  }
23

24
}
25

26
void lcdSPI_data(char data){   //Char ausgeben
27
  lcdSPIInit(1);
28
  SPDR = data;
29
  while(!SPI_READY);
30
  _delay_us(10);
31
  SPDR = 1;
32
  while(!SPI_READY);
33
  lcdSPIInit(0);
34
  _delay_ms(5);
35
}
36

37
void lcdSPI_string(char *data){    //Char-Array ausgeben
38
  lcdSPIInit(1);
39
  while(*data){
40
    SPDR = *data;
41
    while(!SPI_READY);
42
    _delay_us(20);
43
    data++;
44
  }
45
  SPDR = '\0';
46
  while(!SPI_READY);
47
  _delay_us(20);
48
  SPDR = 2;
49
  while(!SPI_READY);
50
  lcdSPIInit(0);
51
  _delay_ms(5);
52
}


Empfänger:
1
int main(void){
2
  volatile char i;
3

4
  _delay_ms(10);
5
  extern char buf[17];
6
  SPIInit();
7
  TWIInit();
8
  lcd_init();
9
  DDRC |= 0x08;  //Hintergurndbeleuchtung
10
  PORTC &= ~0x08; //aus
11

12
  buf[16] = 0;  //absicherung, um ein unabgeschl. Array zu vermeiden
13

14
  sei();
15

16
  while(1){
17
    i++;
18
  }
19

20
  return 0;
21
}
22

23

24
void SPIInit(void){
25
  DDRB &= ~0x2C;  //SCK,MOSI,SS is Input
26
  DDRB |= 0x10;   //MISO Output
27

28
  SPCR = (1<<SPIE) | (1<<SPE);
29
}
30

31

32
ISR(SPI_STC_vect){
33
  extern uint8_t data, bufpos;
34
  extern char buf[17];
35

36
  data = SPDR;
37

38
  if(data <= 31 && data != 0){
39
    switch(data){
40
      case 1:
41
        lcd_data(buf[0]);
42
      break;
43
      case 2:
44
        lcd_string(buf);
45
      break;
46
      case 3:
47
        lcd_clear();
48
      break;
49
      case 4:
50
        lcd_set_cursor(buf[0]-40, buf[1]-40);
51
      break;
52
      case 5:
53
        PORTC |= 0x08;  //Hintergrundbeleuchtung an
54
      break;
55
      case 6:
56
        PORTC &= ~0x08;  //Hintergrundbeleuchtung aus
57
      break;
58
      default: lcd_string("SPI-ERROR!!");
59
    }
60
    bufpos = 0;
61
  }else if(bufpos < 16){
62
      buf[bufpos++] = data;
63
  }
64
}

Ich sitzt schon seit einigen Stunden an diesem Problem, komme dem Fehler 
aber nicht auf die schliche...

Sieht jemand vielleicht was?

Gruß, Yaro
Gast #1651782
Lesenswert?
• ▲
▼
Wenn ich mit lcdSPI_data(char data) sende, kommt es seltener zu 
Störungen.
Wenn ich mit lcdSPI_string(char *data) "Hello World" sende, dann ist der 
häufigste Fehler, dass statt dem o ein y ankommt, und der 
zweithäufigste, dass statt dem l ein c kommt... Oder es kommt überhaupt 
kein String an...
Die Fehler sind zwar oft die selben, lassen sich aben nicht (nicht in 
der gleichen Reihenfolge) reproduzieren, sondern sind zufällig.

Gruß, Yaro
Gast #1651827
Lesenswert?
• ▲
▼
Ich bekomme das Problem ein wenig in Griff, wenn ich nach jedem Byte die 
SS-Leitung hoch und dann wieder runterziehe, um das SPI zu resetten. 
Dann verliere ich beim Senden zwar öfters mal einen Buchstaben, aber der 
Rest bleibt ok.
Trotzdem ist das doch kein wünschenswerter Zustand!
Ich hab mit SPI bisher noch nie solche Probleme gehabt! Es lief immer 
ohne Probleme!

Woran könnte sowas liegen?
Ich bin für jeden Tip dankbar!

Gruß, Yaro
Gast #1651843
Lesenswert?
• ▲
▼
Ich puffere den Empfänger. Auf das LCD gebe ich den Text erst dann aus, 
wenn das letzte Zeichen angekommen ist.
Ich schreibe zuerst alles in den Puffer, danach kommt dann das 
Steuerzeichen, mit dem das Modul weiß, was es mit den angekommenen Bytes 
tun soll.

Gruß,  Yaro
#1652025
Lesenswert?
• ▲
▼
Je schneller die Daten über den Bus gehen, umso mehr musst du an 
Beschaltung bzw. Layout machen. Bei MOSI MISO SCK nach GND und bei CS 
AUF VCC. Nimm mal 10k, wenn das zu viel ist, dann 1k. Das brauchst du, 
weil du immer Kapazitäten auf der Leitung hast.
Bei mir ging das bis 25 MHz gut, dann mochte der Controller nimmer.

Antwort schreiben

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.

Formatierung
  • [c]C-Code[/c]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] – Link zu einem Artikel
  • Verweis auf einen anderen Beitrag: Rechtsklick auf dessen Beitrags-ID (#8078628), „Adresse kopieren“, in den Text einfügen

Mehr zur Formatierung

Längeren Sourcecode als Anhang, nicht in den Text. JPG nur für Fotos und Scans; Zeichnungen und Screenshots als PNG oder GIF. Siehe Bildformate.

Schon registriert? Anmelden

Wird nicht angezeigt. Wir schicken dir einen Link; sobald du damit bestätigst, erscheint dein Beitrag.

Mit dem Abschicken legst du einen kostenlosen Account an und erkennst die Nutzungsbedingungen und die Datenschutzerklärung an.