Forum: Mikrocontroller und Digitale Elektronik STM8S: 1x SPI Master & 1x SPI Slave


von Daniel Bauer (Gast)


Lesenswert?

Hallo Forum,

ich verzweifle seit einiger Zeit daran, 2 STM8S per SPI miteinander im 
Full-Duplex-Modus und per Hardware-NSS/CS kommunizieren zu lassen.
Mein Ziel ist es dabei, das der Master einen Frame von 2 Byte an den 
Slave sendet und dabei CS entsprechend 'aktiviert' (LOW). Daraufhin soll 
CS 'idle' (HIGH) werden bis das Spielchen wieder von vorn beginnnt.
Das was der Slave an den Master sendet soll irrelevant sein.

Meinem Verständnis nach habe ich dies für den einfachst möglichen 
SPI-Master, unter Beachtung von "5. Set the MSTR and SPE bits ([!]they 
remain set only if the NSS pin is connected to a high-level signal[/!])" 
[RM0016, Reference manual, Doc ID 14587 Rev 8, S.258] für dessen 
Initialisierung, bereits erreicht (OpenBench LogicSniffer zeigt das 
gewünschte Bild; ausgenommen CS, welches dauerhaft HIGH ist):
1
void SPI_Config(void)
2
{
3
  SPI_DeInit();
4
  SPI_Init(SPI_FIRSTBIT_MSB,
5
           SPI_BAUDRATEPRESCALER_128,
6
           SPI_MODE_MASTER,          
7
           SPI_CLOCKPOLARITY_HIGH,   
8
           SPI_CLOCKPHASE_2EDGE,     
9
           SPI_DATADIRECTION_2LINES_FULLDUPLEX, 
10
           SPI_NSS_HARD,                        
11
           0x00                                 
12
          );
13
  SPI_Cmd(ENABLE);
14
}
15
16
int main( void )
17
{
18
  u16 wait = 0x00;
19
 
20
  CLK_HSIPrescalerConfig(CLK_PRESCALER_HSIDIV1); /* Fmaster = 16MHz */
21
22
  do
23
  {
24
    wait = 0x00;
25
    do{wait++;}while(wait<150);
26
27
    SPI_Config();
28
  }
29
  while ( ((SPI->CR1 & SPI_CR1_MSTR) == 0) &&
30
          ((SPI->CR1 & SPI_CR1_SPE ) == 0)
31
        );
32
33
  for (;;)
34
  {
35
    (void) SPI_SendData(0xAA);
36
    do{}while( (SPI->SR & SPI_SR_TXE) == 0x00 );
37
38
    (void) SPI_SendData(0x55);
39
    do{}while( (SPI->SR & SPI_SR_TXE) == 0x00 );
40
41
    wait = 0x00;
42
    do{wait++;}while(wait<150);
43
  }
44
45
  return 0;
46
}

Nun weiss ich aber beim Slave nicht so recht weiter.
Wie oben durch [!]...[/!] gekennzeichnet, erwartet ein STM8S-SPI-Master 
ein HIGH auf CS um sich überhaupt zu initialisieren.
Ein STM8S-SPI-Slave gibt ein solches HIGH aber scheinbar per Default 
nicht aus.
Dieser erwartet statt dessen ein LOW während eines Datentransfers:
"3. In Hardware mode (refer to Slave select (NSS) pin management on page 
255), the NSS pin must be connected to a low level signal during the 
complete data transmit sequence." [RM0016, Reference manual, Doc ID 
14587 Rev 8, S.258]
1
void SPI_Config(void)
2
{
3
  SPI_DeInit();
4
  SPI_Init(SPI_FIRSTBIT_MSB,
5
           SPI_BAUDRATEPRESCALER_8,
6
           SPI_MODE_SLAVE,        
7
           SPI_CLOCKPOLARITY_HIGH,
8
           SPI_CLOCKPHASE_2EDGE,  
9
           SPI_DATADIRECTION_2LINES_FULLDUPLEX, 
10
           SPI_NSS_HARD,                        
11
           0x00                                 
12
          );
13
  SPI_ITConfig(SPI_IT_RXNE, ENABLE);
14
  SPI_ITConfig(SPI_IT_TXE,  ENABLE);
15
  SPI_Cmd(ENABLE);
16
}
17
18
#pragma vector = (SPI_TXE_vector & SPI_RXNE_vector)
19
__interrupt void SPI_RX_IRQHandler(void)
20
{
21
  if ( SET == SPI_GetITStatus(SPI_IT_TXE) )
22
  {
23
    return;
24
  }
25
  if ( SET == SPI_GetITStatus(SPI_IT_RXNE) )
26
  {
27
    u8 spi_tx_data = SPI_ReceiveData();
28
    return;
29
  }
30
}
31
32
int main( void )
33
{
34
  CLK_HSIPrescalerConfig(CLK_PRESCALER_HSIDIV1); /* Fmaster = 16MHz */
35
36
  SPI_Config();
37
38
  enableInterrupts();
39
40
  for (;;)
41
  {
42
  }
43
44
  return 0;
45
}

Der Versuch für den Slave NSS zusätzlich per GPIO als Pull-Up-Input zu 
konfigurieren hat leider auch nicht das gewünschte Ergebnis erzielt.
Siehe hierzu:
"Note: In applications with a parallel multi-slave structure, with 
separate NSS signals and the slave MISO outputs connected together, the 
corresponding GPIO registers must be configured correctly. [...]  When 
the NSS signal is released, the pin is driven by GPIO register settings 
only. To function correctly, the GPIO has to be configured in input 
pull-up mode with no interrupt." [RM0016, Reference manual, Doc ID 14587 
Rev 8, S.258]

Hat jemand von Euch Erfahrungen hierzu?
Kann mir jemand einen Tipp geben der mich weiterbringt?
Ist ggf. eine externe Beschaltung für NSS/CS erforderlich?

Ich bin für jede Hilfe dankbar.

Grüße,
Daniel

von Daniel Bauer (Gast)


Lesenswert?

Hi,

was ich beim schreiben meines initialen Beitrags vergessen habe zu 
erwähnen:

Die eigentlichen Probleme sind
- das für den Fall der durch die angegebenen Code-Beispiele angegeben 
ist keine Initialisierung des Masters erreiche.
- das ich mit dem beschriebenen Versuch für den Slave NSS zusätzlich per 
GPIO als Pull-Up-Input zu konfigurieren keinen RX-Interrupts im Slave 
erhalte, weil NSS dauerhaft auf HIGH steht bzw. nicht 
ausreichend/korrekt vom Master auf LOW gezogen wird bzw. gezogen werden 
kann.

Zusätzlich ist vielleicht noch interessant, daß ich 2 
STM8S-Discovery-Boards (STM8S105C6T6) und VDD = 5V verwende.
Zudem wird stets nur ein Board per USB mit Spannung versorgt. Das andere 
wird dadurch versorgt, das ich eine Verbindung zwischen GND und VCC der 
jeweiligen Konnektoren CN7 hergestellt habe.

Danke,
Daniel

von McG (Gast)


Lesenswert?

Das würde mich auch interessieren!
Hatte gleiches Problem vor längerer Zeit auch und hab's nicht lösen 
können.

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.