2013-05-02 03:36 AM
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 #spi2013-05-02 04:36 AM
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.2013-05-02 04:48 AM
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 againIan2013-05-02 06:55 AM
After poking around the internet for a while I have found this example which works on my board:
It would seem the only real difference was clock setup. I will investigate more. Does this sound correct?Ian2013-05-02 08:33 AM
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.2013-11-20 04:49 AM
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); }2013-11-20 06:11 AM
To remap pins the AFIO clock must be enabled.
2013-11-20 10:38 PM
Hello Clive,
I have donechanges
, 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 nosignals
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
2013-11-21 03:40 AM
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_Speedfor
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 likeGPIO_InitStructure.GPIO_OType
GPIO_InitStructure.GPIO_PuPd .
Please let me know the solution..
Thanks Shankar
2013-11-21 06:34 AM
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