This discussion has been locked.
You can no longer post new replies to this discussion. If you have a question you can start a new discussion

SPI problem in STM32L

Hi,
Please help me to know why the following example code for SPI of STM32L152VD is not working, I do not see any signals in scope on pins SCK and MOSI niether in Data register in dubugger.

void SPI_Master_init(void)
{

GPIO_InitTypeDef GPIO_InitStruct;
SPI_InitTypeDef SPI_InitStruct;

/* Initialization and Configuration functions *********************************/


        // enable peripheral clock
    RCC_AHBPeriphClockCmd(RCC_APB2Periph_SPI1, ENABLE);
    RCC_AHBPeriphClockCmd(RCC_APB1Periph_SPI2, ENABLE);

    RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOA, ENABLE);
    RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOB, ENABLE);

    GPIO_InitStruct.GPIO_Pin = GPIO_Pin_5 | GPIO_Pin_6 | GPIO_Pin_7;
    GPIO_InitStruct.GPIO_Mode = GPIO_Mode_AF;
    GPIO_InitStruct.GPIO_OType = GPIO_OType_PP;
    GPIO_InitStruct.GPIO_Speed = GPIO_Speed_40MHz;
    GPIO_InitStruct.GPIO_PuPd = GPIO_PuPd_NOPULL;
    GPIO_Init(GPIOA, &GPIO_InitStruct);

          GPIO_InitStruct.GPIO_Pin = GPIO_Pin_13 | GPIO_Pin_14 | GPIO_Pin_15;
    GPIO_InitStruct.GPIO_Mode = GPIO_Mode_AF;
    GPIO_InitStruct.GPIO_OType = GPIO_OType_PP;
    GPIO_InitStruct.GPIO_Speed = GPIO_Speed_40MHz;
    GPIO_InitStruct.GPIO_PuPd = GPIO_PuPd_NOPULL;
    GPIO_Init(GPIOB, &GPIO_InitStruct);

            // connect SPI1 pins to SPI alternate function
    GPIO_PinAFConfig(GPIOA, GPIO_PinSource5, GPIO_AF_SPI1);
    GPIO_PinAFConfig(GPIOA, GPIO_PinSource6, GPIO_AF_SPI1);
    GPIO_PinAFConfig(GPIOA, GPIO_PinSource7, GPIO_AF_SPI1);

                //    // connect SPI2 pins to SPI alternate function
    GPIO_PinAFConfig(GPIOB, GPIO_PinSource13, GPIO_AF_SPI2);
    GPIO_PinAFConfig(GPIOB, GPIO_PinSource14, GPIO_AF_SPI2);
    GPIO_PinAFConfig(GPIOB, GPIO_PinSource15, GPIO_AF_SPI2);

    SPI_InitStruct.SPI_Direction = SPI_Direction_2Lines_FullDuplex; // set to full duplex
    SPI_InitStruct.SPI_Mode = SPI_Mode_Master;     // transmit in master mode, NSS pin has
    SPI_InitStruct.SPI_DataSize = SPI_DataSize_8b; // one packet of data is 8 bits wide
    SPI_InitStruct.SPI_CPOL = SPI_CPOL_Low;        // clock is low when idle
    SPI_InitStruct.SPI_CPHA = SPI_CPHA_1Edge;      // data sampled at first edge
    SPI_InitStruct.SPI_NSS = SPI_NSS_Hard; // set the NSS HARD
    SPI_InitStruct.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_256; // SPI frequency is
    SPI_InitStruct.SPI_FirstBit = SPI_FirstBit_MSB;// data is transmitted MSB first
    SPI_Init(SPI1, &SPI_InitStruct);

    SPI_SSOutputCmd(SPI1,ENABLE); //Set SSOE bit in SPI_CR1 register
    SPI_Cmd(SPI1, ENABLE); // enable SPI1

    SPI_InitStruct.SPI_Direction = SPI_Direction_2Lines_FullDuplex; // set to full duplex
    SPI_InitStruct.SPI_Mode = SPI_Mode_Master;     // transmit in master mode, NSS pin has
    SPI_InitStruct.SPI_DataSize = SPI_DataSize_8b; // one packet of data is 8 bits wide
    SPI_InitStruct.SPI_CPOL = SPI_CPOL_Low;        // clock is low when idle
    SPI_InitStruct.SPI_CPHA = SPI_CPHA_1Edge;      // data sampled at first edge
    SPI_InitStruct.SPI_NSS = SPI_NSS_Hard; // set the NSS HARD
    SPI_InitStruct.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_256; // SPI frequency is
    SPI_InitStruct.SPI_FirstBit = SPI_FirstBit_MSB;// data is transmitted MSB first
    SPI_Init(SPI2, &SPI_InitStruct);

    SPI_SSOutputCmd(SPI2,ENABLE); //Set SSOE bit in SPI_CR1 register
    SPI_Cmd(SPI2, ENABLE); // enable SPI2


and in main:

int main(void){


SPI_Master_init(); while(1) {
SPI_I2S_SendData(SPI1, 0xFFFF); SPI1->DR = 0x11; SPI_I2S_SendData(SPI2,0xFFFF); SPI2->DR = 0x11;

Parents Reply Children
  • Dear Pier,

    Thanks. I corrected the code.

    RCC_APB1PeriphClockCmd(RCC_APB1Periph_SPI2,ENABLE);
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_SPI1,ENABLE);
    


    Yet I don't have signals.

  • looking at your code. I am wondering about if you are setting up SPI2. I see some of the lower code as duplicate of code you already typed in. You declare master mode two times. the code looks the same.

  • http://www.keil.com/forum/59935/

    I have made a header board for STM32L152VD after every restart it takes few seconds for the board to start running.
    I used the same program to run on STM32L152RC discovery board but I had no problem.

    -->

    Did the mentioned SPI problem happen on the header board for STM32L152VD or the STM32L152RC discovery board?

  • Dear Gary,
    I initialized SPI1 and SPI2 to check if any will work. (both master and independent)

  • Dear John,
    I tested the program in both boards.The one I made with STM32L152VD and STM32L discovery both have same problem.
    I check the SCK and MISO by scope while not connected to slave. Is it necessary to connect to slave in SPI while checking by scope?

  • No much use looking at the MISO signal without a slave. This signal is Master In, Slave Out. So driven by the slave.

    It's the MOSI you want to look at - Master Out, Slave In. But then you don't want to send 0xFFFF since that doesn't give you any nice action on the pin.

    The clock signal is always owned by the master and should always play when the master tries to send - no need for any slave connected.

  • Dear Per,
    You are right. It was a mistake in typing. I am expecting to see signals on SCK and MOSI.

  • As I see the following piece of code has been repeated many times by developers the same in the web.
    I surprise Y it not works in my discovery board!
    I expect to see the signals in scope but I see nothing.

    void SPI_RCC_Configuration()
    {
    
                    RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOB,ENABLE);
                    RCC_APB1PeriphClockCmd(RCC_APB1Periph_SPI2,ENABLE);
    
    }
    
     void SPI_GPIO_Configuration(void)
    {
              GPIO_InitTypeDef GPIO_InitStruct;
                    GPIO_InitStruct.GPIO_Pin =  GPIO_Pin_13 | GPIO_Pin_14|GPIO_Pin_15;
                    GPIO_InitStruct.GPIO_Speed = GPIO_Speed_40MHz;
                    GPIO_InitStruct.GPIO_Mode = GPIO_Mode_AF;
              GPIO_InitStruct.GPIO_OType=GPIO_OType_PP;
              GPIO_Init(GPIOB, &GPIO_InitStruct);
    
                    GPIO_InitStruct.GPIO_Pin = GPIO_Pin_12;
                    GPIO_InitStruct.GPIO_Mode = GPIO_Mode_OUT;
              GPIO_InitStruct.GPIO_OType=GPIO_OType_PP;
                    GPIO_Init(GPIOB, &GPIO_InitStruct);
                    GPIO_SetBits(GPIOB,GPIO_Pin_12);
    
    }
    
    void SPI_Configuration(void)
    {
            SPI_InitTypeDef SPI_InitStruct;
    
            SPI_RCC_Configuration();
    
            SPI_InitStruct.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_8;
            SPI_InitStruct.SPI_Direction= SPI_Direction_2Lines_FullDuplex;
            SPI_InitStruct.SPI_Mode = SPI_Mode_Master;
            SPI_InitStruct.SPI_DataSize = SPI_DataSize_8b;
            SPI_InitStruct.SPI_CPOL = SPI_CPOL_Low;
            SPI_InitStruct.SPI_CPHA = SPI_CPHA_1Edge;
            SPI_InitStruct.SPI_NSS = SPI_NSS_Hard;
            SPI_InitStruct.SPI_FirstBit = SPI_FirstBit_MSB;
            SPI_InitStruct.SPI_CRCPolynomial = 7;
            SPI_Init(SPI2, &SPI_InitStruct);
    
            SPI_GPIO_Configuration();
    
            SPI_SSOutputCmd(SPI2, ENABLE);
            SPI_Cmd(SPI2, ENABLE);
    }
    
    //MAIN.C
    #include "stm32l1xx.h"
    #include "clock.h"
    #include "spi_driver.h"
    
    
    int main(void) { int i; SystemCoreClockSetHSI(); SPI_RCC_Configuration(); SPI_Configuration(); SPI_GPIO_Configuration();
    while(1) { SPI2->DR = 1; //sending 1 as data for(i=0;i<100000;i++) __nop(); }
    return 0; }

  • Why would SPI_GPIO_Configuration be called twice? Once in the SPI_Configuration Function and once in the main() function.

  • I was looking for SPI code for your board but am not finding a example. On the STM website I downloaded the FW for your board.

    at this location at the bottom of the page:
    www.st.com/.../PF260821

    The do not have a SPI example for the discovery board. They do have other examples.

    The Nucleo board has a SPI example that compiles. The code is different in many ways from
    the above code.

  • google

    SPI problem with hardware NSS management
    (no text)

  • Dear Gary,
    Yes it is better to delete one them.

  • I tried on a new board with STM32L152VD 100pin by correcting the below the problem solved.

    RCC_AHBPeriphClockCmd(RCC_APB2Periph_SPI1, ENABLE);
    RCC_AHBPeriphClockCmd(RCC_APB1Periph_SPI2, ENABLE);
    corrected to
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_SPI1, ENABLE);
    RCC_APB1PeriphClockCmd(RCC_APB1Periph_SPI2, ENABLE);
    

    My last code for SPI1 and SPI2 is in below where I see signals in scope for SCK and MOSI

    
    GPIO_InitTypeDef GPIO_InitStruct;
    SPI_InitTypeDef SPI_InitStruct;
    NVIC_InitTypeDef NVIC_InitStructure;
    
      NVIC_InitStructure.NVIC_IRQChannel = SPI1_IRQn;
      NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;
      NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
      NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
      NVIC_Init(&NVIC_InitStructure);
    
      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);
    
            ///* Initialization and Configuration functions *********************************/
    //      // enable peripheral clock
              RCC_APB1PeriphClockCmd(RCC_APB1Periph_SPI2, ENABLE);
              RCC_APB2PeriphClockCmd(RCC_APB2Periph_SPI1, ENABLE);
    
              RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOA, ENABLE);
              RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOB, ENABLE);
    
        GPIO_InitStruct.GPIO_Pin = GPIO_Pin_13 | GPIO_Pin_14 | GPIO_Pin_15;
        GPIO_InitStruct.GPIO_Mode = GPIO_Mode_AF;
        GPIO_InitStruct.GPIO_OType = GPIO_OType_PP;
        GPIO_InitStruct.GPIO_Speed = GPIO_Speed_2MHz;
        GPIO_InitStruct.GPIO_PuPd = GPIO_PuPd_NOPULL;
        GPIO_Init(GPIOB, &GPIO_InitStruct);
    
        // connect SPI3 pins to SPI alternate function
        GPIO_PinAFConfig(GPIOB, GPIO_PinSource13, GPIO_AF_SPI2);
        GPIO_PinAFConfig(GPIOB, GPIO_PinSource14, GPIO_AF_SPI2);
        GPIO_PinAFConfig(GPIOB, GPIO_PinSource15, GPIO_AF_SPI2);
    
    
    
        SPI_InitStruct.SPI_Direction = SPI_Direction_2Lines_FullDuplex; // set to full duplex
        SPI_InitStruct.SPI_Mode = SPI_Mode_Master;     // transmit in master mode, NSS pin has
        SPI_InitStruct.SPI_DataSize = SPI_DataSize_8b; // one packet of data is 8 bits wide
        SPI_InitStruct.SPI_CPOL = SPI_CPOL_Low;        // clock is low when idle
        SPI_InitStruct.SPI_CPHA = SPI_CPHA_1Edge;      // data sampled at first edge
        SPI_InitStruct.SPI_NSS = SPI_NSS_Hard; // set the NSS HARD
        SPI_InitStruct.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_256; // SPI frequency is
        SPI_InitStruct.SPI_FirstBit = SPI_FirstBit_MSB;// data is transmitted MSB first
        SPI_Init(SPI2, &SPI_InitStruct);
    
                    //================SPI1
                     GPIO_InitStruct.GPIO_Pin = GPIO_Pin_5 | GPIO_Pin_6 | GPIO_Pin_7;
        GPIO_InitStruct.GPIO_Mode = GPIO_Mode_AF;
        GPIO_InitStruct.GPIO_OType = GPIO_OType_PP;
        GPIO_InitStruct.GPIO_Speed = GPIO_Speed_2MHz;
        GPIO_InitStruct.GPIO_PuPd = GPIO_PuPd_NOPULL;
        GPIO_Init(GPIOA, &GPIO_InitStruct);
    
        // connect SPI3 pins to SPI alternate function
        GPIO_PinAFConfig(GPIOA, GPIO_PinSource5, GPIO_AF_SPI1);
        GPIO_PinAFConfig(GPIOA, GPIO_PinSource6, GPIO_AF_SPI1);
        GPIO_PinAFConfig(GPIOA, GPIO_PinSource7, GPIO_AF_SPI1);
    
    
    
        SPI_InitStruct.SPI_Direction = SPI_Direction_2Lines_FullDuplex; // set to full duplex
        SPI_InitStruct.SPI_Mode = SPI_Mode_Master;     // transmit in master mode, NSS pin has
        SPI_InitStruct.SPI_DataSize = SPI_DataSize_8b; // one packet of data is 8 bits wide
        SPI_InitStruct.SPI_CPOL = SPI_CPOL_Low;        // clock is low when idle
        SPI_InitStruct.SPI_CPHA = SPI_CPHA_1Edge;      // data sampled at first edge
        SPI_InitStruct.SPI_NSS = SPI_NSS_Hard; // set the NSS HARD
        SPI_InitStruct.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_256; // SPI frequency is
        SPI_InitStruct.SPI_FirstBit = SPI_FirstBit_MSB;// data is transmitted MSB first
        SPI_Init(SPI1, &SPI_InitStruct);
    
    
       SPI_SSOutputCmd(SPI2,ENABLE); //Set SSOE bit in SPI_CR1 register
       SPI_Cmd(SPI2, ENABLE); // enable SPI2
       SPI_SSOutputCmd(SPI1,ENABLE); //Set SSOE bit in SPI_CR1 register
       SPI_Cmd(SPI1, ENABLE); // enable SPI2
    
    
    }
    
    
    
    
    

  • Hi Hamed,

    Could you also show your main function code and IRQ_HANDLERS.

    I would like to be able to reproduce this.

    Thank You, Gary