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.
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.
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
das ist der 644A (http://www.reichelt.de/?;ACTION=3;LA=444;GROUP=A363;GROUPID=2959;ARTICLE=68172;START=0;SORT=artnr;OFFSET=16;SID=28ZxSafKwQARwAACoRypQ91132b8747934197759b657e551ebf3d)
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.
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
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
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.
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
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
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.