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

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren