Forum: Mikrocontroller und Digitale Elektronik STM32F4 SPI Probleme


von Besucher (Gast)


Lesenswert?

Hallo Allerseits,

ich versuche das SPI Interface des STM32F4 zu initialisieren um damit 
ein RFM01/02 anzusprechen. Es scheitert allerdings schon bei der 
Initialisierung. Die Interrupt Handler der beiden SPI Interfaces(2 & 3) 
werden angesprungen, bevor ich überhaupt ein Zeichen sende.

Hat jemand von euch die SPI Schnittstelle des F4 schon erfolgreich in 
Betrieb genommen? Beispielcode ist willkommen :)

Anbei mal meine nicht funktionierende Variante:
void SPI2_IRQHandler(void)
{
  if (SPI_I2S_GetITStatus(SPI2, SPI_I2S_IT_TXE)!= RESET)
  {
    SPI_I2S_ClearITPendingBit(SPI2, SPI_I2S_IT_TXE);
  }
}

void SPI3_IRQHandler(void)
{

  if (SPI_I2S_GetITStatus(SPI3, SPI_I2S_IT_TXE)!= RESET)
  {
    SPI_I2S_ClearITPendingBit(SPI3, SPI_I2S_IT_TXE);
  }
}
void init_RFM02(void){
  /* Disable SPI Interrupts during init */
  SPI_I2S_ITConfig(SPI2, SPI_I2S_IT_TXE, DISABLE);
  SPI_I2S_ITConfig(SPI3, SPI_I2S_IT_TXE, DISABLE);
  //Transmitter init
  SPI3_CS_LOW;
  SPI_I2S_SendData(SPI3,RFM12_CMD_CFG | RFM12_CFG_EL | RFM12_CFG_EF | 
RFM12_BAND_433| RFM12_XTAL_12PF);
  while(!SPI_I2S_GetFlagStatus(SPI3,SPI_I2S_FLAG_TXE));
  SPI_I2S_ClearFlag(SPI3,SPI_I2S_FLAG_TXE);
  SPI3_CS_HIGH;
  SPI3_CS_LOW;
  SPI_I2S_SendData(SPI3,RFM12_CMD_PWRMGT | RFM12_PWRMGT_DC | 
RFM12_PWRMGT_EX | RFM12_PWRMGT_ES | RFM12_PWRMGT_ET);
  while(!SPI_I2S_GetFlagStatus(SPI3,SPI_I2S_FLAG_TXE));
  SPI_I2S_ClearFlag(SPI3,SPI_I2S_FLAG_TXE);
  SPI3_CS_HIGH;
  SPI3_CS_LOW;
  //430.9MHz
  SPI_I2S_SendData(SPI3,RFM12_CMD_FREQUENCY | 36);
  while(!SPI_I2S_GetFlagStatus(SPI3,SPI_I2S_FLAG_TXE));
  SPI_I2S_ClearFlag(SPI3,SPI_I2S_FLAG_TXE);
  SPI3_CS_HIGH;
  SPI3_CS_LOW;
  SPI_I2S_SendData(SPI3,RFM12_CMD_DATARATE | 17);
  while(!SPI_I2S_GetFlagStatus(SPI3,SPI_I2S_FLAG_TXE));
  SPI_I2S_ClearFlag(SPI3,SPI_I2S_FLAG_TXE);
  SPI3_CS_HIGH;
  SPI3_CS_LOW;
  SPI_I2S_SendData(SPI3,RFM12_CMD_RXCTRL | RFM12_RXCTRL_P16_VDI | 
RFM12_RXCTRL_VDI_FAST | RFM12_RXCTRL_BW_134 | RFM12_RXCTRL_LNA_0 | 
RFM12_RXCTRL_RSSI_103);;
  while(!SPI_I2S_GetFlagStatus(SPI3,SPI_I2S_FLAG_TXE));
  SPI_I2S_ClearFlag(SPI3,SPI_I2S_FLAG_TXE);
  SPI3_CS_HIGH;
  SPI3_CS_LOW;
  SPI_I2S_SendData(SPI3,RFM12_CMD_DATAFILTER | RFM12_DATAFILTER_AL | 
RFM12_DATAFILTER_S | 0xC);
  while(!SPI_I2S_GetFlagStatus(SPI3,SPI_I2S_FLAG_TXE));
  SPI_I2S_ClearFlag(SPI3,SPI_I2S_FLAG_TXE);
  SPI3_CS_HIGH;
  SPI3_CS_LOW;
  SPI_I2S_SendData(SPI3,RFM12_CMD_FIFORESET | RFM12_FIFORESET_DR | 
0x80);
  while(!SPI_I2S_GetFlagStatus(SPI3,SPI_I2S_FLAG_TXE));
  SPI_I2S_ClearFlag(SPI3,SPI_I2S_FLAG_TXE);
  SPI3_CS_HIGH;
  SPI3_CS_LOW;
  SPI_I2S_SendData(SPI3,RFM12_CMD_AFC | RFM12_AFC_AUTO_ONCE | 
RFM12_AFC_OE | RFM12_AFC_EN);
  while(!SPI_I2S_GetFlagStatus(SPI3,SPI_I2S_FLAG_TXE));
  SPI_I2S_ClearFlag(SPI3,SPI_I2S_FLAG_TXE);
  SPI3_CS_HIGH;
  SPI3_CS_LOW;
  SPI_I2S_SendData(SPI3,RFM12_CMD_TXCONF| 0x50);
  while(!SPI_I2S_GetFlagStatus(SPI3,SPI_I2S_FLAG_TXE));
  SPI_I2S_ClearFlag(SPI3,SPI_I2S_FLAG_TXE);
  SPI3_CS_HIGH;
  SPI3_CS_LOW;
  SPI_I2S_SendData(SPI3,RFM12_CMD_WAKEUP);
  while(!SPI_I2S_GetFlagStatus(SPI3,SPI_I2S_FLAG_TXE));
  SPI_I2S_ClearFlag(SPI3,SPI_I2S_FLAG_TXE);
  SPI3_CS_HIGH;
  SPI3_CS_LOW;
  SPI_I2S_SendData(SPI3,RFM12_CMD_DUTYCYCLE);
  while(!SPI_I2S_GetFlagStatus(SPI3,SPI_I2S_FLAG_TXE));
  SPI_I2S_ClearFlag(SPI3,SPI_I2S_FLAG_TXE);
  SPI3_CS_HIGH;
  SPI3_CS_LOW;
  SPI_I2S_SendData(SPI3,RFM12_CMD_LBDMCD);
  while(!SPI_I2S_GetFlagStatus(SPI3,SPI_I2S_FLAG_TXE));
  SPI_I2S_ClearFlag(SPI3,SPI_I2S_FLAG_TXE);
  SPI3_CS_HIGH;
  /* Enable the Tx buffer empty interrupt */
  SPI_I2S_ITConfig(SPI2, SPI_I2S_IT_TXE, ENABLE);
  SPI_I2S_ITConfig(SPI3, SPI_I2S_IT_TXE, ENABLE);
}
void init_SPI(void) {

  GPIO_InitTypeDef GPIO_InitStructure;
  EXTI_InitTypeDef EXTI_InitStructure;
  NVIC_InitTypeDef NVIC_InitStructure;
  SPI_DeInit(SPI2);
  SPI_DeInit(SPI3);
  /* Enable the SPI clock 2 & 3 */
  RCC_APB1PeriphClockCmd(RCC_APB1Periph_SPI2 | RCC_APB1Periph_SPI3, 
ENABLE);
  RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOB,ENABLE);
  /* SPI GPIO Configuration 
--------------------------------------------------*/
  /* Connect SPI pins to AF */
  //PB3/13 SCK
  //PB4/14 MISO
  //PB5/15 MOSI
  //PB2/12 CS
  //PB1/11 nIRQ
  GPIO_PinAFConfig(GPIOB, GPIO_PinSource3, GPIO_AF_SPI3);
  GPIO_PinAFConfig(GPIOB, GPIO_PinSource5, GPIO_AF_SPI3);
  GPIO_PinAFConfig(GPIOB, GPIO_PinSource13, GPIO_AF_SPI2);
  GPIO_PinAFConfig(GPIOB, GPIO_PinSource14, GPIO_AF_SPI2);
  GPIO_PinAFConfig(GPIOB, GPIO_PinSource15, GPIO_AF_SPI2);
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
  GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
  GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_DOWN;
  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_3  | GPIO_Pin_5
      |GPIO_Pin_13 | GPIO_Pin_14 | GPIO_Pin_15;
  GPIO_Init(GPIOB, &GPIO_InitStructure);

  //GPIO CS
  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_2 | GPIO_Pin_12;
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT;
  GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;
  GPIO_Init(GPIOB, &GPIO_InitStructure);
  GPIO_SetBits(GPIOB,GPIO_Pin_2 | GPIO_Pin_12);
  /* Enable SYSCFG clock */
  //EXI
  RCC_APB2PeriphClockCmd(RCC_APB2Periph_SYSCFG, ENABLE);
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN;
  GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;
  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_1 | GPIO_Pin_11;
  GPIO_Init(GPIOB, &GPIO_InitStructure);
  EXTI_InitStructure.EXTI_Line = EXTI_Line1 | EXTI_Line11;
  EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt;
  EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Rising;
  EXTI_InitStructure.EXTI_LineCmd = ENABLE;
  EXTI_Init(&EXTI_InitStructure);

  SPI_InitTypeDef SPI_InitStructure;
  /* Initializes the SPI communication */
  SPI_StructInit(&SPI_InitStructure);
  SPI_InitStructure.SPI_Direction = SPI_Direction_2Lines_FullDuplex;
  SPI_InitStructure.SPI_DataSize = SPI_DataSize_16b;
  SPI_InitStructure.SPI_CPOL = SPI_CPOL_Low;
  SPI_InitStructure.SPI_CPHA = SPI_CPHA_1Edge;
  SPI_InitStructure.SPI_NSS = SPI_NSS_Soft;
  SPI_InitStructure.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_256;
  SPI_InitStructure.SPI_FirstBit = SPI_FirstBit_MSB;
  SPI_InitStructure.SPI_CRCPolynomial = 7;
  SPI_InitStructure.SPI_Mode = SPI_Mode_Master;
  SPI_Init(SPI2, &SPI_InitStructure);
  SPI_InitStructure.SPI_Direction = SPI_Direction_1Line_Tx;
  SPI_Init(SPI3, &SPI_InitStructure);
  /* Enable the SPI peripheral */
  SPI_Cmd(SPI2, ENABLE);
  SPI_Cmd(SPI3, ENABLE);
  /* Enable the Tx buffer empty interrupt */
  SPI_I2S_ClearITPendingBit(SPI2, SPI_I2S_IT_TXE);
  SPI_I2S_ClearITPendingBit(SPI3, SPI_I2S_IT_TXE);
  SPI_I2S_ITConfig(SPI2, SPI_I2S_IT_TXE, ENABLE);
  SPI_I2S_ITConfig(SPI3, SPI_I2S_IT_TXE, ENABLE);

  NVIC_InitStructure.NVIC_IRQChannel = SPI2_IRQn;
  NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 4;
  NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
  NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
  NVIC_Init(&NVIC_InitStructure);
  NVIC_InitStructure.NVIC_IRQChannel = SPI3_IRQn;
  NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 5;
  NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
  NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
  NVIC_Init(&NVIC_InitStructure);
  NVIC_InitStructure.NVIC_IRQChannel = EXTI1_IRQn;
  NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 6;
  NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
  NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
  NVIC_Init(&NVIC_InitStructure);
  NVIC_InitStructure.NVIC_IRQChannel = EXTI15_10_IRQn;
  NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 7;
  NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
  NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
  NVIC_Init(&NVIC_InitStructure);
}


Schonmal vielen Dank für kommende Hilfe :)
von Besucher (Gast)


Lesenswert?

Achso,

bis auf das Chip Select tut sich bei den GPIOs gar nix.
von vaid (Gast)


Lesenswert?

Ich würd sagen da fehlt der Takt für die SPI Peripherie
von (prx) A. K. (prx)


Lesenswert?

Der Takt ist da, auch wenn man das in dem Codegewirr kaum sieht. 
Allerdings bringt es nichts, ein taktloses SPI zu deinitialisieren.

Es könnte allerdings sein, das die AFIO keinen Takt hat.
von (prx) A. K. (prx)


Lesenswert?

Besucher schrieb:

> Die Interrupt Handler der beiden SPI Interfaces(2 & 3)
> werden angesprungen, bevor ich überhaupt ein Zeichen sende.

Was mich bei eingeschaltetem "Tx buffer empty interrupt" nicht wirklich 
erstaunt.
von Besucher (Gast)


Lesenswert?

Hi,

das Flag wird doch gelöscht, somit sollte der doch nicht angesprungen 
werden?

Der SPI Takt ist an und einen AFIO Takt gibts doch beim F4 nicht mehr, 
oder?

Mfg
von (prx) A. K. (prx)


Lesenswert?

Besucher schrieb:

> das Flag wird doch gelöscht, somit sollte der doch nicht angesprungen
> werden?

Wird der ausgelöst solange der Puffer leer ist oder beim Übergang von 
voll zu leer?
von Besucher (Gast)


Lesenswert?

Ok, vorerst gelöst. Hab die Interrupts deaktiviert, die werden 
anscheinend permanent wieder gesetzt.. Dachte immer nur einmal, wenn das 
Transmit Register leer geworden ist.
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.