Forum: Mikrocontroller und Digitale Elektronik SPI Probleme mit ATMega644


von Tobias (Gast)


Lesenswert?

Hallo,
ich sende mit einem ATMega644 SPI Signale zu einem Display. Leider ist 
jder ca. 10ter Frame korrupt. Dass das Protokoll mit dem Display stimmt 
weiss ich, da ich den gleichen Code mit einem ATMega32 benutzt hatte und 
alle Frames fehlerfrei angekommen sind.
Die SPI Sektion der Datenblätter vom ATMega32 und 644 sind aber 
identisch. Woran kann es also liegen?
Hier der Code:
[c]
#include <avr/io.h>
#define F_CPU 14745600L
#include <util/delay.h>
#define BAUD 115200L

#define UBRR_VAL ((F_CPU+BAUD * 8)/(BAUD*16)-1)      //clever runde
#define BAUD_REAL (F_CPU/(16*(UBRR_VAL+1)))         //reale Baudrate

#define BAUD_ERROR ((BAUD_REAL*1000)/BAUD-1000)      //Fehler in 
Promille

#if ((BAUD_ERROR>10)||(BAUD_ERROR<-10))
#error Systematischer Fehler in der Baudrate größer 1% und damit zu 
hoch!
#endif

#define CSHIGH (PORTB |= (1 << PB3))
#define CSLOW (PORTB &= ~(1 << PB3))
#define CS_DELAY _delay_us(25)

char strWert[4];
uint8_t Cnt = 100;
static unsigned char const CLR_VAL_AM_2[] = {0x11, 0x04, 0x1B, 0x4D, 
0x4E, 0x3D};
//Cursor im Arbeitsmenü
static unsigned char const SET_CURSOR_AM_1[] = {0x11, 0x04, 0x1B, 0x4D, 
0x4E, 0x32};
static unsigned char const SET_CURSOR_AM_2[] = {0x11, 0x04, 0x1B, 0x4D, 
0x4E, 0x3C};
static unsigned char const SET_CURSOR_AM_3[] = {0x11, 0x04, 0x1B, 0x4D, 
0x4E, 0x46};
uint8_t SPIFrame_len = 0;
uint8_t SPIFrame[100];
const unsigned char *ptr2SPIFrame;


void SPI_MasterTransmit(char cData)
{
  uint8_t tmp;
  tmp = SPSR;
  tmp = SPDR;
  /* Start transmission */
  SPDR = cData;
  /* Wait for transmission complete */
  while(!(SPSR & (1<<SPIF)));
}

void SPI_SendFrame(void)
{
  uint16_t sum = 0;
  uint8_t crc = 0;
  for (uint8_t i=0; i<SPIFrame_len; i++){
    sum += ptr2SPIFrame[i];
  }
  crc = sum % 256;
  CSHIGH;
  CS_DELAY;
  CSLOW;
  for (uint8_t i=0; i<SPIFrame_len; i++){
    SPI_MasterTransmit(ptr2SPIFrame[i]);
  }
  SPI_MasterTransmit(crc);
  //Dummy-Byte senden
  _delay_us(8);
  SPI_MasterTransmit(0xFF);
}

int main(void)
{
  DDRB = (1<<PB3) | (1<<PB4) | (1<<PB5) | (1<<PB7); // SPI SS, MOSI und 
SCK als Ausgang setzen
  _delay_ms(300);
  PORTB |= (1<<PB4);   //Display aktivieren
    /* Enable SPI, Master, set clock rate fck/128 = 115200kHz */
  SPCR = (1<<SPE)|(1<<MSTR)|(1<<SPR0)|(1<<SPR1)|(0<<CPHA)|(0<<CPOL);


  while (1)
  {
    Cnt++;
    if (Cnt > 250) Cnt = 100;
    ptr2SPIFrame = CLR_VAL_AM_2; SPIFrame_len = sizeof(CLR_VAL_AM_2);
    SPI_SendFrame();
    _delay_ms(500);
    ptr2SPIFrame = SET_CURSOR_AM_1; SPIFrame_len = 
sizeof(SET_CURSOR_AM_1);
    SPI_SendFrame();
    _delay_ms(500);
    ptr2SPIFrame = SET_CURSOR_AM_2; SPIFrame_len = 
sizeof(SET_CURSOR_AM_2);
    SPI_SendFrame();
    _delay_ms(500);
    ptr2SPIFrame = SET_CURSOR_AM_3; SPIFrame_len = 
sizeof(SET_CURSOR_AM_3);
    SPI_SendFrame();
  }

  return 0;
}
[\c]
Wie gesagt, mit dem ATMega32 funktioniert der gleiche Code fehlerfrei.
Außerdem habe ich das auf 2 getrennten Platinen ausprobiert, ein 
Hardwareproblem schließe ich daher auch aus.

von Kevin K. (nemon) Benutzerseite


Lesenswert?

ist der Compiler für den 644 umgestellt?

von Tobias (Gast)


Lesenswert?

ja, Signatur stimmt überein, 9 von 10 Frames kommen ja auch an.

von Frank K. (fchk)


Lesenswert?

Hast Du mal gemessen, ob der _delay_ms() seine Soll-Länge hat?

fchk

von Tobias (Gast)


Lesenswert?

ja das passt auch

von Frank K. (fchk)


Lesenswert?

ok, dann stimmt der Takt usw schon mal.

Ist der Fehler eingrenzbar, d.h. ist immer das gleiche Byte kaputt?

Hast Du einen Logicanalyzer zum Messen?

Welcher 644 isses denn? Der 644 ohne was dahinter, der 644P oder der 
644PA? Speziell zwischen 644 und 644P gibts größere Unterschiede, der 
644 ohne P hat nämlich z.B. nur einen UART, der P und der PA haben zwei. 
Demzufolge gibts dann nämlich auch unterschiedliche Includes.

von Yaro (Gast)


Lesenswert?

Mit welcher Geschwindigkeit werden die Controller getacktet?
Über welche Leitungen überträgst du das Signal? Wie lang sind diese?

Womöglich sind die Flanken, die der mega644 generiert, zu steil. Dann 
würde Terminierung helfen. Einfach einen kleinen Kondensator (unter 
100p) gegen GND an die SCK-Leitung löten.

Gruß, Yaro

von Tobias (Gast)


Lesenswert?


von Tobias (Gast)


Lesenswert?

Das SPI Signal taktet mit 115200 Hz, Die Leitungen sind sehr kurz, 
sprich alles auf einer Platine.
Einen 100pF Kondensator habe ich nicht da, aber mit einem 100nF könnte 
ich es probieren.
Überprüfung mit dem LogicAnalyzer werde ich noch machen, ich nehme aber 
an dass mal dieses mal jenes Byte korrupiert sein wird, da die Fehler 
auch sehr unregelmäßig kommen.

von Frank K. (fchk)


Lesenswert?

AU bezeichnet nur das Gehäuse (TQFP), gehört also nicht zur 
Typenkennung.
Schau sicherheitshalber nochmal auf den Chip, nicht dass man Dir 
stillschweigend einen 644P-au geliefert hat. Réichelt würde ich das 
glatt zutrauen.

fchk

von Yaro (Gast)


Lesenswert?

100n sind zu viel. Es muss schon im unteren pico-Bereich liegen.
Verwendest du die MISO-Leitung? Wenn nicht, versuch mal, diese (wenn es 
geht) nicht zu verbinden. Bei mir hat dies die Störungen mal behoben 
(auch wenn ich nicht wirklich sagen kann, wieso...)

Gruß, Yaro

von Tobias (Gast)


Lesenswert?

der Kondensator hat die Kommunikationsprobleme noch verschlimmert.

Die Bezeichnung auf dem µC ist die gleiche wie bei Reichelt, also ein 
644 ohne etwas dahinter. Den es so auf der Übersichtsseite von Atmel gar 
nicht gibt 
http://www.atmel.com/dyn/products/param_table.asp?family_id=607&OrderBy=part_no&Direction=ASC

im Gegensatz dazu kann ich im AVR Studio unter Projekt-Einstellungen nur 
zwischen 644 und 644P wählen, aber einen 644A wird nicht angeboten.

von Yaro (Gast)


Lesenswert?

Wie groß war denn der Kondensator?
Er sollte unter 100pF sein.
Ich weiß nicht, in welcher Umgebung du arbeitest, aber eine Abschirmung 
könnte helfen. Oder du nimmst einfach noch einen GND-Layer.
Du sagst, deine Leitungen sind direkt auf der Platine. Sind in den 
Leitungen starke Knicke drin? sind sie sehr lang? Spiralenförmig?

Gruß, Yaro

von Tobias (Gast)


Lesenswert?

das war ein 100pF C.
Die Leitungen sind alle abgerundet und auch nicht spiralförmig (wer 
würde denn auf so eine Idee kommen?). GND Layer ist vorhanden. Die 
Platine wurde auch durch einen PCB Hersteller überprüft und einer 
Prüfstelle EMV getestet. Allerdings noch mit einem ATMega32.
Daher kann es fast nicht sein dass es ein Layout-Problem ist.

Das einzige was für mich Sinn macht, ist dass die I/O's vom ATMega644 
andere elektrische Eigenschaften haben als die vom ATMega32.
Warum hattest du gerade bei SCK den Entstörkondensator vorgeschlagen? 
Bei MOSI könnte doch das gleiche Problem entstehen.

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
Noch kein Account? Hier anmelden.