Hallo zusammen,
ich möchte folgende Kommunikation über SPI realisieren:
MASTER SLAVE
___________ ______________
| | |
PIC18F26K80 |<------------>|PIC12F1840 |
____________| |______________|
Angeschlossene PINS:
Master (28-Pin SOIC):
SDI: RC4 (PIN 15)
SDO: RC5 (PIN 16)
SCK: RC3 (PIN 14)
CS: RA7 (PIN 9)
Slave (8-Pin SOIC)
SDI: RA2 (PIN 5)
SDO: RA0 (PIN 7)
SCK: RA1 (PIN 6)
SS: RA3 (PIN 4) (Ist aber auch MCLR)
Nun versuche ich zunächst in einfacher form einfach eine Kommunikation
herzustellen, dabei gehe ich folgendermaßen vor:
MASTER:
CS wird auf Low gezogen.
SPI-Write Routine wird in main aufgerufen und irgend ein Wert
übertragen:
1 | signed char spi_write( unsigned char tx_SPIbyte )
|
2 | {
|
3 | unsigned char TempVar;
|
4 | TempVar = SSPBUF; // Clears BF
|
5 | PIR1bits.SSPIF = 0; // Clear interrupt flag
|
6 | SSPCON1bits.WCOL = 0; // Clear any previous write collision
|
7 | SSPBUF = tx_SPIbyte; // write byte to SSPBUF register
|
8 |
|
9 | if ( SSPCON1 & 0x80 ) // test if write collision occurred
|
10 | return ( -1 ); // if WCOL bit set return negative #
|
11 | else
|
12 | while( !SSPSTATbits.BF ); // wait until 'BF' bit is set
|
13 | TempVar = SSPBUF; // Clear BF
|
14 | return ( 0 ); // if WCOL not set, return non-negative
|
15 | }
|
SLAVE:
Hängt in einer While schleife und ruft spi_read auf und versucht etwas
zu empfangen und dann etwas zu senden.
1 | unsigned char spi( unsigned char data_out )
|
2 | {
|
3 | SSPBUF = data_out; // write byte to SSPBUF register
|
4 | while( !SSPSTATbits.BF ); // wait until bus cycle complete
|
5 | return ( SSPBUF ); // return data and clear BF
|
6 | }
|
Soweit so gut, jetzt kuck ich mir die Signale am Oszi an.
- CS geht auf LOW -> Passt
- Clock wird vom Master ausgegeben -> Passt
- Daten werden vom Master ausgegeben -> Passt
Aber es werden vom Slave keine Daten ausgegeben, ich habe schon mehrere
Variationen des Codes versucht. Debuggen geht leider nicht auf dem
Slave, da die SPI-Pins gleichzeitig auch die Programmierpins sind und
somit kein Live-Debugging möglich ist.
In der Initialisierung wurde eigtenlich alles richtig gesetzt, auch die
Alternativen Pin Configurations und Tris Register.
Ich probiere nun schon seit 3 Tagen eine Verbindung aufzubauen aber es
klappt nicht. Wenn ich den Slave jedoch als Master konfiguriere dann
sendet er aus dem SDO pin Daten.
INIT vom SLAVE:
1 | inline void init_spi(void)
|
2 | {
|
3 | // disable spi before configuration
|
4 | SSP1CON1bits.SSPEN = 0;
|
5 |
|
6 | // set status params
|
7 | SSP1STATbits.CKE = 0; // idle to active
|
8 | SSP1STATbits.SMP = 0; // input data sampled at middle
|
9 |
|
10 | // set control register 1
|
11 | SSP1CON1bits.SSPM0 = 0; // slave mode
|
12 | SSP1CON1bits.SSPM1 = 0; // clock = sck, ss = enabled
|
13 | SSP1CON1bits.SSPM2 = 1; // 0x04
|
14 | SSP1CON1bits.SSPM3 = 0; // ...
|
15 | SSP1CON1bits.CKP = 1; // idle state for clock is high
|
16 |
|
17 | // enable spi after configuration
|
18 | SSP1CON1bits.SSPEN = 1;
|
19 | }
|
Wenn jemand Tipps geben könnte auf was man noch achten muss wäre ich
sehr dankbar! Ach ja, da der SS auf dem MCLR Pin liegt, ist MCLR in den
Configuration Bits deaktiviert!
MFG
Flo