Forum: Mikrocontroller und Digitale Elektronik STM32F103 SPI TXE Flag wird nicht gesetzt


von Karl-Friedrich (Gast)


Lesenswert?

Hallo liebes Forum,

Ich versuche gerade die SPI an meinem STM32 zum laufen zu kriegen und 
schaffe es nicht. Ich verwende als Entwicklungsumgebung CoIDE mit dem 
ARM-GCC. Ich komm mit dem Debugger immer bis zur folgenden Zeile:

while (SPI_I2S_GetFlagStatus(SPI1, SPI_I2S_FLAG_TXE ) == RESET);

Diese Bedingung ist allerdings immer erfüllt, d.h. er springt nie aus 
der Schleife um zu senden. Der Chipselect funktioniert (habe ich mit dem 
Oszi gestestet).

Da ich sowohl ein Developmentboard als auch eine eigene Schaltung 
verwende ist es unwahrscheinlich, dass der Chip bzw. das Register kapput 
ist.
Ich nehme an, dass ich einen Denkfehler gemacht habe. Könnt ihr mir 
vielleicht sagen welchen?

Ich verwende folgenden Code (vieles davon habe ich aus den Beispielen 
der LIB entnommen, ist außerdem nur ein Testcode um zu überprüfen ob ich 
überhaupt etwas senden kann):




#include "stm32f10x_conf.h"

GPIO_InitTypeDef GPIO_InitStructure;
SPI_InitTypeDef SPI_InitStructure;

void spi_chipSelect(void){
  GPIO_WriteBit(GPIOB, GPIO_Pin_12, RESET);
}
void spi_chipDeselect(void){
  GPIO_WriteBit(GPIOB, GPIO_Pin_12, SET);
}
ErrorStatus HSEStartUpStatus;
void taktinit(void){
  /* RCC system reset(for debug purpose) */
  RCC_DeInit();

      /* Enable HSE */
  RCC_HSEConfig(RCC_HSE_ON);

      /* Wait till HSE is ready */
  HSEStartUpStatus = RCC_WaitForHSEStartUp();

   if (HSEStartUpStatus == SUCCESS)
      {
          /* HCLK = SYSCLK */
     RCC_HCLKConfig(RCC_SYSCLK_Div1);

          /* PCLK2 = HCLK/2 */
       RCC_PCLK2Config(RCC_HCLK_Div2);

          /* PCLK1 = HCLK/2 */
       RCC_PCLK1Config(RCC_HCLK_Div2);

          /* PLLCLK = 8MHz * 9 = 72 MHz */
       RCC_PLLConfig(0x00010000, RCC_PLLMul_9);

          /* Enable PLL */
       RCC_PLLCmd(ENABLE);

          /* Wait till PLL is ready */
       while (RCC_GetFlagStatus(RCC_FLAG_PLLRDY) == RESET) {}

          /* Select PLL as system clock source */
       RCC_SYSCLKConfig(RCC_SYSCLKSource_PLLCLK);

          /* Wait till PLL is used as system clock source */
       while (RCC_GetSYSCLKSource() != 0x08) {}
      }

      /* Enable peripheral clocks 
----------------------------------------------*/
      /* GPIOA, GPIOB and SPI1 clock enable */
  RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);
  RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO,ENABLE);
  RCC_APB2PeriphClockCmd(RCC_APB1Periph_SPI2, ENABLE);
}

void Portinit(void){
  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_13 | GPIO_Pin_15;
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
  GPIO_Init(GPIOB, &GPIO_InitStructure);
  //MISO
  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_14;
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
  GPIO_Init(GPIOB, &GPIO_InitStructure);
  //NSS
  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_12;
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
  GPIO_Init(GPIOB, &GPIO_InitStructure);

  GPIO_WriteBit(GPIOB, GPIO_Pin_12, SET);
}
void SPIinit(void){
  SPI_InitStructure.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_32;
  SPI_InitStructure.SPI_CPHA = SPI_CPHA_2Edge;
  SPI_InitStructure.SPI_CPOL = SPI_CPOL_High;
  SPI_InitStructure.SPI_CRCPolynomial = 0;
  SPI_InitStructure.SPI_DataSize = SPI_DataSize_8b;
  SPI_InitStructure.SPI_Direction = SPI_Direction_2Lines_FullDuplex;
  SPI_InitStructure.SPI_FirstBit = SPI_FirstBit_MSB;
  SPI_InitStructure.SPI_Mode = SPI_Mode_Master;
  SPI_InitStructure.SPI_NSS = SPI_NSS_Soft;
  SPI_Init(SPI2, &SPI_InitStructure);
  SPI_Cmd(SPI2, ENABLE);
}
int main(void)
{

  SystemInit();
  void taktinit();
  void Portinit();
  void SPIinit();

  while(1)
    {
      spi_chipSelect();
      int Tx_idx=0;
      while (Tx_idx<1000000){
        while (SPI_I2S_GetFlagStatus(SPI1, SPI_I2S_FLAG_TXE ) == RESET);
        SPI_I2S_SendData(SPI2, 0xFF);
        //Flag nachgucken/müsste eig Reset sein^^, ist aber set so wies 
aussieht oder doch Reset?
        Tx_idx++;

      }
      spi_chipDeselect();
    }
}

von Jim M. (turboj)


Lesenswert?

Du initialisierst SPI2, und fragst dann das Flag vom uninitialisiertem 
SPI1 ab. C&P Fehler?

von Karl-Friedrich (Gast)


Angehängte Dateien:

Lesenswert?

Danke turboj. Ja das kommt davon, wenn man sich im letzten Moment dann 
doch entschließt SPI2 statt SPI1 zu verweden. Aber an dem Problem hat 
sich nichts geändert. Auch wird das Flag immer mit dem Wert 2 (kann doch 
eigentlich nicht sein oder?) initiallisiert.
Habe einen Screenshot angefügt, wie es im Debugger aussieht, wenn ich 
das erste mal in die Schleife spring.
Kann es sein, dass das Flag nicht richtig initiallisiert wird?
Ich kann ebenfalls nichts senden (Ich bekomm keine Werte auf dem Oszi, 
auch wenn ich die Abfrage vorher sein lasse).

von holger (Gast)


Lesenswert?

Schau da mal GANZ genau hin:

  RCC_APB2PeriphClockCmd(RCC_APB1Periph_SPI2, ENABLE);

von Karl-Friedrich (Gast)


Lesenswert?

Also ich den Fehler gefunden.

Wenn man sich das hier mal anschaut wird auch klar wieso:

int main(void)
{

  SystemInit();
  void taktinit();
  void Portinit();
  void SPIinit();

hab wohl nen Blackout gehabt^^
Jetzt bekomm ich zumindest mal das Flag richtig raus. Takt wird mir aber 
immernoch keiner angezeigt :(

von Grml .. (grml)


Lesenswert?

SPI2 hängt an APB1 nicht APB2. Das Interface hat keine Clock.

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.