Gast
#1678978
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.