cancel
Showing results for 
Search instead for 
Did you mean: 

Problem with SPI

j3lda
Associate II
Posted on March 20, 2013 at 15:29

Hello, I´m using STM32F303 and I´m trying to communicate via SPI (simplex SPI1-SPI2 using interrupts). It couldn´t be easier but it doesn´t work and I can´t find mistake. I connect PB3 (SPI1_SCK) with PB13(SPI2_SCK) and PB5(SPI1_MOSI) with PB14(SPI2_MISO) but it doesn´t generate interrupts. Here is my code. Thanks a lot for your help.

/* Private variables ---------------------------------------------------------*/

NVIC_InitTypeDef      NVIC_InitStructure;

GPIO_InitTypeDef      GPIO_InitStructure;

__IO uint32_t TimDelay = 0;

uint8_t SPI_MASTER_Buffer_Tx[]={1};

uint8_t ReceivedData;

/* Private function prototypes -----------------------------------------------*/

/* Private functions ---------------------------------------------------------*/

void SPI_Ini(void);

int main(void)

{

    SPI_Ini();

    /* GPIOE Periph clock enable */

   RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOE, ENABLE);

    

   /* Configure PE.9 (LED) */

   GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9 ;

   GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT;

   GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP ;

   GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;

   GPIO_Init(GPIOE, &GPIO_InitStructure);

    

    while(1){

    

        /* Send SPI_MASTER data */

       SPI_SendData8(SPI1, SPI_MASTER_Buffer_Tx[0]);

        

       if(ReceivedData!=0)GPIOE->BSRR = 0x200; // LED on

        

       for(TimDelay=0; TimDelay < 100000; TimDelay++);

        

  }

}

void SPI_Ini(void)

{

    

    SPI_InitTypeDef  SPI_InitStructure;

    

    /* Enable GPIOB for SCK, MISO, MOSI GPIO clocks */

   RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOB, ENABLE);

    

    /* Enable the SPI1 periph */

   RCC_APB1PeriphClockCmd(RCC_APB2Periph_SPI1, ENABLE);

    

    /* Enable the SPI2 periph */

   RCC_APB1PeriphClockCmd(RCC_APB1Periph_SPI2, ENABLE);

 

    /*----------------------Inicialization SPI master------------------------------------*/

    

    /* SPI1 SCK pin configuration: AF PP output 50MHz  */

   GPIO_PinAFConfig(GPIOB, GPIO_PinSource3, GPIO_AF_5);  // PB3: SPI1 SCK

   GPIO_InitStructure.GPIO_Pin = GPIO_Pin_3;

   GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;            // alternate mode

   GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;    // 50MHz

   GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;         // push pull output

   //GPIO_InitStructure.GPIO_PuPd  = GPIO_PuPd_DOWN;

   GPIO_Init(GPIOB, &GPIO_InitStructure);

    

    /* SPI1  MOSI pin configuration: AF PP output 50MHz */

    GPIO_PinAFConfig(GPIOB, GPIO_PinSource5, GPIO_AF_5); // PB5: SPI1 MOSI

    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_5;

    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;                 // alternate mode

    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;         // 50MHz

    GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;              // push pull output

    //GPIO_InitStructure.GPIO_PuPd  = GPIO_PuPd_UP;

    GPIO_Init(GPIOB, &GPIO_InitStructure);

  /* SPI1 configuration -------------------------------------------------------*/

  SPI_I2S_DeInit(SPI1);

  SPI_InitStructure.SPI_Direction = SPI_Direction_1Line_Tx;

  SPI_InitStructure.SPI_DataSize = SPI_DataSize_8b;

  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_2;

  SPI_InitStructure.SPI_FirstBit = SPI_FirstBit_LSB;

  SPI_InitStructure.SPI_CRCPolynomial = 7;

  SPI_InitStructure.SPI_Mode = SPI_Mode_Master;

  SPI_Init(SPI1, &SPI_InitStructure);

    

    /*----------------------Inicialization SPI slave------------------------------------*/

 

    /* SPI2 SCK pin configuration: input mode 50MHz */

    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_13;

    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN;             // input mode

    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;    // 50MHz

    //GPIO_InitStructure.GPIO_PuPd  = GPIO_PuPd_DOWN;

    GPIO_Init(GPIOB, &GPIO_InitStructure);

    

    /* SPI2 MISO pin configuration: AF PP output 50MHz */

    GPIO_PinAFConfig(GPIOB, GPIO_PinSource14, GPIO_AF_5); // PB14: SPI2 MISO

    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_14;

    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;            // alternative mode

    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;    // 50MHz

    GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;         // push pull output

    //GPIO_InitStructure.GPIO_PuPd  = GPIO_PuPd_UP;

    GPIO_Init(GPIOB, &GPIO_InitStructure);

    

    /* SPI2 configuration -------------------------------------------------------*/

    SPI_I2S_DeInit(SPI2);

    SPI_InitStructure.SPI_Direction = SPI_Direction_1Line_Rx;

    SPI_InitStructure.SPI_Mode = SPI_Mode_Slave;

    SPI_Init(SPI2, &SPI_InitStructure);

    

    /* Enable the Rx buffer not empty interrupt */

    SPI_I2S_ITConfig(SPI2, SPI_I2S_IT_RXNE, ENABLE);

    

    /* Configure the SPI interrupt priority */

   NVIC_InitStructure.NVIC_IRQChannel = SPI2_IRQn;

   NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;

   NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;

   NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;

   NVIC_Init(&NVIC_InitStructure);

    

    /* Enable the SPI peripheral */

   SPI_Cmd(SPI2, ENABLE);

    

    /* Enable the SPI peripheral */

   SPI_Cmd(SPI1, ENABLE);

 

}

void SPI2_IRQHandler(void)

{

    /* SPI in Slave Receiver mode--------------------------------------- */

   if (SPI_I2S_GetITStatus(SPI2, SPI_I2S_IT_RXNE) == SET)

  {

        ReceivedData = SPI_ReceiveData8(SPI2);

  }

}

 
6 REPLIES 6
Posted on March 20, 2013 at 16:49

A Master MOSI (output) needs to go to a Slave MOSI (input)

You should wait for TXE before sending data.

Config clock and data output with a scope.

RCC_APB1PeriphClockCmd(RCC_APB2Periph_SPI1, ENABLE); // APB2!!
Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..
j3lda
Associate II
Posted on March 20, 2013 at 18:01

Thanks Clive. I would never have found mistake APB1->APB2. I fix code according your ideas. It is sending data now, but still not receiving (SPI2 handler is not called).

Are you sure that I would use MOSI instead of MISO in slave? For example in reference manual for STM32F10x and this application note (page 5): 

http://read.pudn.com/downloads106/sourcecode/embed/437624/stm32/STM32F%20Documents/Application%20Note/STM32F10xxx%20SPI%20application%20examples.pdf

is written that in simplex mode should be connected MOSI (master) with MISO (slave).

I thing that mistake should be in setting pull ups/down, I don´t undertad where use PU or PD or no PUPD. Thank you for answer.

int main(void)

{

    SPI_Ini();

      /* Enable SPI_MASTER TXE interrupt */

      SPI_I2S_ITConfig(SPI1, SPI_I2S_IT_TXE, ENABLE);//**********************************************

    

       /* Enable the Rx buffer not empty interrupt */

      SPI_I2S_ITConfig(SPI2, SPI_I2S_IT_RXNE, ENABLE);

    

        /* Enable the SPI peripheral */

       SPI_Cmd(SPI2, ENABLE);

    

       /* Enable the SPI peripheral */

       SPI_Cmd(SPI1, ENABLE);

    

       while(1){  }

}

void SPI_Ini(void)

{

    

    SPI_InitTypeDef  SPI_InitStructure;

    

  /* Enable GPIOB for SCK, MISO, MOSI GPIO clocks */

  RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOB, ENABLE);

  RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOA, ENABLE);

    

   /* Enable the SPI1 periph */

  RCC_APB2PeriphClockCmd(RCC_APB2Periph_SPI1, ENABLE);

    

   /* Enable the SPI2 periph */

  RCC_APB1PeriphClockCmd(RCC_APB1Periph_SPI2, ENABLE);

 

    /*--------+-------------Inicializace SPI master------------------------------------*/

    

    /* SPI1 SCK pin configuration: AF PP output 50MHz  */

  GPIO_PinAFConfig(GPIOB, GPIO_PinSource3, GPIO_AF_5); // PB3: SPI1 SCK

  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_3;

  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;         // alternate mode

  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;    // 50MHz

  GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;       // push pull output

  //GPIO_InitStructure.GPIO_PuPd  = GPIO_PuPd_DOWN;//???????????????????????????????

  GPIO_Init(GPIOB, &GPIO_InitStructure);

    

    /* SPI1  MOSI pin configuration: AF PP output 50MHz */

  GPIO_PinAFConfig(GPIOB, GPIO_PinSource5, GPIO_AF_5); // PB5: SPI1 MOSI

  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_5;

  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;         // alternate mode

  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;    // 50MHz

  GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;       // push pull output

  //GPIO_InitStructure.GPIO_PuPd  = GPIO_PuPd_DOWN;//??????????????????????????????

  GPIO_Init(GPIOB, &GPIO_InitStructure);

  /* SPI1 configuration -------------------------------------------------------*/

  SPI_I2S_DeInit(SPI1);

  SPI_InitStructure.SPI_Direction = SPI_Direction_1Line_Tx;

  SPI_InitStructure.SPI_DataSize = SPI_DataSize_8b;

  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_2;

  SPI_InitStructure.SPI_FirstBit = SPI_FirstBit_LSB;

  SPI_InitStructure.SPI_CRCPolynomial = 7;

  SPI_InitStructure.SPI_Mode = SPI_Mode_Master;

  SPI_Init(SPI1, &SPI_InitStructure);

     

  /*--------+-------------Inicialization SPI slave------------------------------------*/

 

  /* SPI2 SCK pin configuration: input mode 50MHz */

  //GPIO_PinAFConfig(GPIOB, GPIO_PinSource13, GPIO_AF_5);

  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_13;

  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN;  // input mode

  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;    // 50MHz

  //GPIO_InitStructure.GPIO_PuPd  = GPIO_PuPd_NOPULL;//??????????????????????????

  GPIO_Init(GPIOB, &GPIO_InitStructure);

    

   /* SPI2 MOSI pin configuration: input 50MHz */

  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_15;              // PB15: SPI2 MOSI

  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN;         // alternative mode

  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;    // 50MHz

  //GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;       // push pull output

  //GPIO_InitStructure.GPIO_PuPd  = GPIO_PuPd_DOWN;//??????????????????????????????

  GPIO_Init(GPIOB, &GPIO_InitStructure);

    

    /* SPI2 configuration -------------------------------------------------------*/

  SPI_I2S_DeInit(SPI2);

  SPI_InitStructure.SPI_Direction = SPI_Direction_1Line_Rx;

   SPI_InitStructure.SPI_Mode = SPI_Mode_Slave;

  SPI_Init(SPI2, &SPI_InitStructure);

    

   /* Configure the Priority Group to 1 bit */                

  NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);

    

   /* Configure the SPI interrupt priority */

  NVIC_InitStructure.NVIC_IRQChannel = SPI1_IRQn;

  NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;

  NVIC_InitStructure.NVIC_IRQChannelSubPriority = 2;

  NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;

  NVIC_Init(&NVIC_InitStructure);

    

    /* Configure the SPI interrupt priority */

  NVIC_InitStructure.NVIC_IRQChannel = SPI2_IRQn;

  NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;

  NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;

  NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;

  NVIC_Init(&NVIC_InitStructure);

 

}

void SPI2_IRQHandler(void)//***********************************never called

{

    /* SPI in Slave Receiver mode--------------------------------------- */

    if (SPI_I2S_GetITStatus(SPI2, SPI_I2S_IT_RXNE) == SET)

    {

        ReceivedData = SPI_ReceiveData8(SPI2);

    }

}

void SPI1_IRQHandler(void)

{

   

  if (SPI_I2S_GetITStatus(SPI1, SPI_I2S_IT_TXE) != RESET)

  {

        SPI_SendData8(SPI1, SPI_MASTER_Buffer_Tx[TxIdx++]);

        

        if (TxIdx == 4)

       {

          SPI_I2S_ITConfig(SPI1, SPI_I2S_IT_TXE, DISABLE);

        }

    }

}

Posted on March 20, 2013 at 18:07

Not sure how the 1 wire settings impact things, MOSI (Master Out, Slave In) are common in the 2 wire modes. What does the manual say?

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..
j3lda
Associate II
Posted on March 20, 2013 at 18:14

SPIx_MOSI | Simplex bidirectional data wire/ slave  | Not used. Can be used as a GPIO

SPIx_MISO | Simplex bidirectional data wire/ slave  | (point to point) AF push-pull

Posted on March 20, 2013 at 18:24

Do you see any data on the wire with a scope?

The pull-up is irrelevant in PP (Push-Pull) mode, the pin is driven actively in both directions when in output mode. In input mode it's also not going to make any difference when it's connected to a PP driver.

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..
j3lda
Associate II
Posted on March 22, 2013 at 15:53

Yes, data looks fine on Scope. But when I simulate SCK (I give 3V on SCK_slave) it works....

I am lost :(

But clock signal is sinus.... and I think that it should be square.... But I have SCK pins directly connected by wire...