cancel
Showing results for 
Search instead for 
Did you mean: 

STM32 SPI Setup

i_
Associate II
Posted on May 02, 2013 at 12:36

Hi all,

New to the stm32 range and so far all is well. I am having a couple of problems setting up SPI on my stm32vldiscovery board and was hoping to get some help. I'm sure I must be missing something very small but can't seem to find it. I have probed portB with a scope but havn't got any visible output.

I have a couple of theories on what may be the problem, perhaps you can help.

The lines:

    GPIO_PinAFConfig(GPIOB, GPIO_PinSource13, GPIO_AF_SPI2);

    GPIO_PinAFConfig(GPIOB, GPIO_PinSource14, GPIO_AF_SPI2);

    GPIO_PinAFConfig(GPIOB, GPIO_PinSource15, GPIO_AF_SPI2);

Will not compile, I get an error: GPIO_AF_SPI2 is undeclared. To compile I have been commenting these out.

I have not setup any clock preferences?

Thanks again, please see attached code below. (apologies for messy code, still just getting bits working!)

Ian

/**

******************************

******************************

******************

  * @file    main.c

  * @author  icooper

  * @version V1.0.0

  * @date    29/04//2013

  * @brief   Main program body.

******************************

******************************

******************

  * File Description:

  * Just messing around with some io

  */

/* Includes ------------------------------

------------------------------

------*/

&sharpinclude ''stm32f10x.h''

&sharpinclude ''stm32f10x_rcc.h''

&sharpinclude ''stm32f10x_gpio.h''

&sharpinclude ''stm32f10x_usart.h''

&sharpinclude ''stm32f10x_spi.h''

&sharpinclude ''stdint.h''

GPIO_InitTypeDef GPIO_InitStructure;

USART_InitTypeDef USART_InitStructure;

SPI_InitTypeDef SPI_InitStructure;

void Delay(uint32_t nTime);

int main(void)

{

    //Enable Peripheral Clocks, GPIOC, GPIOA, USART1, Alternative Function(AF), SPI2

    RCC_APB2PeriphClockCmd(RCC_

APB

2Periph_GPIOC |

                           RCC_APB2Periph_GPIOA |

                           RCC_APB2Periph_GPIOB |

                           //RCC_APB2Periph_USART1 |

                           RCC_APB2Periph_AFIO ,

                           ENABLE);

    RCC_APB1PeriphClockCmd(RCC_

APB

1Periph_SPI2 , ENABLE);

    //Configure Pins for CS for SPI

    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_4; //GPIO_Pin is a bit vector

    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; //Output Push Pull

    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; //Set Speed

    GPIO_Init(GPIOA, &GPIO_InitStructure);

    //confugre spi - CLK PA5, MOSI PA7

    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_13 | GPIO_Pin_14 | GPIO_Pin_15;

    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; //Alternative function - push pull

    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; //Set Speed

    GPIO_Init(GPIOB, &GPIO_InitStructure);

    GPIO_PinAFConfig(GPIOB, GPIO_PinSource13, GPIO_AF_SPI2);

    GPIO_PinAFConfig(GPIOB, GPIO_PinSource14, GPIO_AF_SPI2);

    GPIO_PinAFConfig(GPIOB, GPIO_PinSource15, GPIO_AF_SPI2);

    //Configure SysTickTimer

    if    (SysTick_Config(

SystemCoreClo

ck / 1000))

    while(1);

    SPI_Cmd(SPI2, DISABLE);

    //configure spi

    SPI_InitStructure.SPI_

Directio

n = SPI_Direction_2Lines_

FullDuple

x;

    SPI_InitStructure.SPI_Mode = SPI_Mode_Master;

    SPI_InitStructure.SPI_DataSize = SPI_DataSize_8b;

    SPI_InitStructure.SPI_CPOL = SPI_CPOL_High;

    SPI_InitStructure.SPI_CPHA = SPI_CPHA_2Edge;

    SPI_InitStructure.SPI_NSS = SPI_NSS_Soft;

    SPI_InitStructure.SPI_

BaudRate

Prescaler = SPI_BaudRatePrescaler_16;

    SPI_InitStructure.SPI_FirstBit = SPI_FirstBit_MSB;

    SPI_InitStructure.SPI_

CRCPolyn

omial = 7;

    SPI_Init(SPI2, &SPI_InitStructure);

    SPI_Cmd(SPI2, ENABLE);

  while (1)

  {

      Delay(50); //wait 50ms

      sendbyte_spi_lcd('c');

      Delay(50); //wait 50ms

  }

}

void sendbyte_spi_lcd(unsigned char byte){

    GPIO_WriteBit(GPIOA, GPIO_Pin_4, 0);

    GPIO_WriteBit(GPIOC, GPIO_Pin_8, 1);

    SPI_I2S_SendData(SPI2, byte);

    //while(SPI_I2S_GetFlagStatus(

SPI2, SPI_I2S_FLAG_BSY) == SET);

}

//Delay loop

static __IO uint32_t TimingDelay;

void Delay(uint32_t nTime){

    TimingDelay = nTime;

    while(TimingDelay != 0);

}

void SysTick_Handler(void){

    if (TimingDelay != 0x00)

        TimingDelay--;

}

#stm32 #spi
13 REPLIES 13
Posted on May 02, 2013 at 13:36

GPIO_PinAFConfig() is not for F1 parts, but rather newer chip designs.

Make sure you look at the F1 firmware examples.

For the VL Discovery, make sure the project is set up correctly to recognize that the F100 parts can only run up to 24 MHz, and uses the appropriate startup.s file, and has the right defines. Where you can use a project template for the VL board.

Make sure TXE is asserted before jamming data to the device.
Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..
i_
Associate II
Posted on May 02, 2013 at 13:48

Hi Clive1,

Thanks for the fast and informative reply!

Yeh, after some digging I have found a lack of that function in the GPIO.c file for this library anyway (no wonder it doesn't compile).  I am managing to successfully program my board and have UART working successfully, so I assume all is setup ok?

As far as I am aware TXE is set when data is transferred? 

Thanks again

Ian

i_
Associate II
Posted on May 02, 2013 at 15:55

After poking around the internet for a while I have found this example which works on my board:

http://www.stm32circle.com/forum/viewtopic.php?id=536

It would seem the only real difference was clock setup. I will investigate more. Does this sound correct?

Ian
Posted on May 02, 2013 at 17:33

As far as I am aware TXE is set when data is transferred?

It should be front tested so as not to trash the currently pending data register. It should assert at about the time the first bit starts transmitting, ie data register is moved to the output shift register for transmission. RXNE asserts as the last bit is shifted back in.
Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..
shankar
Associate II
Posted on November 20, 2013 at 13:49

Hello Clive,

I am not able to get SPI1 signals on STM32F103ZG.

I referred many of the STM32 Forum discussions, but I am not able to get the Clock or Data signals on SPI1 pins of STM32F103ZG on PortA Pin 5, 6 ,& 7. Please help me in solving this problem.

I have attached the code in Main file for your reference

int main(void)

{

        static uint8_t i;

    

        SPI_Ini();

    

     /* Enable SPI_MASTER TXE interrupt */

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

    

           /* Enable the SPI peripheral */

       SPI_Cmd(SPI1, ENABLE);

    

    while(1)

        {

        /* Send SPI_MASTER data */

       SPI_I2S_SendData(SPI1, SPI_MASTER_Buffer_Tx[0]);

       

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

        }

                

}  // main end

void SPI_Ini(void)

{

    

    SPI_InitTypeDef              SPI_InitStructure;

        GPIO_InitTypeDef      GPIO_InitStructure;

    

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

   RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);

    

    /* Enable the SPI1 periph */

   RCC_APB2PeriphClockCmd(RCC_APB2Periph_SPI1, ENABLE);

    

 

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

    

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

        GPIO_PinRemapConfig(GPIO_Remap_SPI1, ENABLE);

        GPIO_InitStructure.GPIO_Pin = GPIO_Pin_5 | GPIO_Pin_6 | GPIO_Pin_7;

        GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;            // alternate mode

        GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;    // 50MHz

        GPIO_Init(GPIOA, &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_8;

    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;             // input mode

    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;    // 50MHz

    GPIO_Init(GPIOA, &GPIO_InitStructure);

    /* Enable the Rx buffer not empty interrupt */

    SPI_I2S_ITConfig(SPI1, SPI_I2S_IT_TXE, ENABLE);

    

    /* Configure the SPI interrupt priority */

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

    

    /* Enable the SPI peripheral */

        SPI_Cmd(SPI1, ENABLE);

}

Posted on November 20, 2013 at 15:11

To remap pins the AFIO clock must be enabled.

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..
shankar
Associate II
Posted on November 21, 2013 at 07:38

Hello Clive,

I have done

changes

, as per your inputs by calling two Functions as below, after SPI_Ini

(

) in main

(

)..

GPIO_PinRemapConfig

(

GPIO_Remap_SPI1, ENABLE);

RCC_APB2PeriphClockCmd

(

RCC_APB2Periph_SPI1, ENABLE);

There are no

signals

on PA 5, 6 & 7. I have not connected anything on these lines. They are open. 

I just want to know whether clock and data signals are coming on these respective pins. Everything else works on my board.

Shankar

shankar
Associate II
Posted on November 21, 2013 at 12:40

Hello,

Do we have to connect the SPI CLK, MOSI, MISO to any Pull up or Pull Down Externally. Hope STM32F103ZG supports only GPIO_InitStructure

.

GPIO_Pin; GPIO_InitStructure

.

GPIO_Mode GPIO_InitStructure

.

GPIO_Speed

for

configuring GPIO Pins,.. Because I couldn't see any other elements than these above 3 to configure GPIO'sin this IC. I mean, I don'thave elements like

GPIO_InitStructure.GPIO_OType
GPIO_InitStructure.GPIO_PuPd .
Please let me know the solution..
Thanks Shankar

Posted on November 21, 2013 at 15:34

There seem to be several problems here, firstly the code is incomplete, an IRQ is initialized and no routine is presented. The IRQ is supposed to service TXE, but then you have another loop that pays no mind to TXE and sends data to the peripheral. There is a loop which might get optimized out.

The purpose of PA8 is not explained.

PA5/PA6/PA7 aren't remapped functions, so why are they being remapped?

SCK/MOSI should be AF_PP

MISO should be IN_FLOATING

See also F1 Examples

STM32F10x_StdPeriph_Lib_V3.5.0\Project\STM32F10x_StdPeriph_Examples\SPI\FullDuplex_SoftNSS\main.c
Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..