Unterschiede
Hier werden die Unterschiede zwischen zwei Versionen angezeigt.
Beide Seiten der vorigen Revision Vorhergehende Überarbeitung Nächste Überarbeitung | Vorhergehende Überarbeitung | ||
microcontrollertechnik:spi_kommunikation [2022/06/24 08:25] – tfischer | microcontrollertechnik:spi_kommunikation [2024/01/10 01:18] (aktuell) – gelöscht mexleadmin | ||
---|---|---|---|
Zeile 1: | Zeile 1: | ||
- | ====== SPI Kommunikation ====== | ||
- | Bei der Simulide Software 1255 und jünger kommt es vor, dass am Slave die Daten nicht durch das SPI eingelesen werden können. | ||
- | |||
- | Im Folgenden ist ein Bugfix beschrieben. | ||
- | |||
- | |||
- | **ACHTUNG: Der beschriebene Bugfix erlaubt nur eine Kommunikation vom Master zum Slave. Eine Rückkommunikation ist hiermit NICHT möglich.** | ||
- | |||
- | === Master === | ||
- | |||
- | Änderungen | ||
- | * Es sollte nur '' | ||
- | * Der Bugfix wurde nur mit einer zeitlichen Verzögerung von ca. $10\mu s$ zwischen dem Versenden von Nachrichten getestet. \\ Bei kürzeren Verzögerungen kann es dazu kommen, dass beim Empfänger die Daten im SPDR Register gestört ankommen. | ||
- | |||
- | <sxh c; first-line: 1> | ||
- | #ifndef F_CPU | ||
- | #define F_CPU 12288000UL | ||
- | #endif | ||
- | |||
- | #include < | ||
- | #include < | ||
- | |||
- | uint8_t i=0; | ||
- | int main() | ||
- | { | ||
- | DDRC &= 0b11111100; | ||
- | PORTC |= 0b00000011; | ||
- | |||
- | DDRB = 0b00111100; | ||
- | SPCR = (1<< | ||
- | |||
- | while(1) | ||
- | { | ||
- | if(!(PINC & 1<< | ||
- | { | ||
- | PORTB &= ~(1 << PORTB2); | ||
- | SPDR = 0b10101100; | ||
- | while(!(SPSR & (1<< | ||
- | PORTB |= 1 << PORTB2; | ||
- | _delay_us(10); | ||
- | } | ||
- | } | ||
- | } | ||
- | </ | ||
- | |||
- | === Slave=== | ||
- | |||
- | Änderungen | ||
- | * Es ist zusätzlich die Unterfunktion '' | ||
- | * Ein Rückversandt der Daten vom Slave zum Master (MISO) ist nicht möglich. Entsprechend ist von einem Beschreiben von SPDR (Zeile 22) abzusehen, da diese den Bugfix stören. | ||
- | * | ||
- | * Eine Verwendung des SPI Interrupt ( '' | ||
- | * Das '' | ||
- | * Zusätzlich wird der Interrupt $ISR(PCINT0_vect)$ zur Signalerkennung genutzt. | ||
- | |||
- | |||
- | <sxh c; first-line: 1> | ||
- | #ifndef F_CPU | ||
- | #define F_CPU 12288000UL | ||
- | #endif | ||
- | |||
- | #include < | ||
- | #include < | ||
- | #include < | ||
- | |||
- | void SPIsoft_Init(); | ||
- | |||
- | int main() | ||
- | { | ||
- | DDRB = (1<< | ||
- | |||
- | DDRD = 0xFF; | ||
- | SPCR = (1<< | ||
- | |||
- | SPIsoft_Init(); | ||
- | |||
- | while(1) | ||
- | { | ||
- | // SPDR = 0x01; | ||
- | while(!(SPSR & (1<< | ||
- | _delay_us(10); | ||
- | PORTD = SPDR; | ||
- | } | ||
- | } | ||
- | |||
- | void SPIsoft_Init() | ||
- | { | ||
- | PCICR |= 1<< | ||
- | PCMSK0|= 1<< | ||
- | 1<< | ||
- | sei(); | ||
- | } | ||
- | |||
- | ISR(PCINT0_vect) | ||
- | { | ||
- | if( !(PINB>> | ||
- | |||
- | SPDR = ( SPDR << 1 ) + ((PINB>> | ||
- | } | ||
- | </ |