2016-09-21 12:29 PM
Hi, I started to work on SPI, my intention is to read three gyroscope sensor by SPI bus,
Currently I testing SPI preipheral of my STM32 Discovery Board (STM32F407), this board has the sensor LIS302DL , when i read the ''WHo am I'' register I received 0x3F but it should be 0x7B, even more when I read continuously this register it got 0x3F,0x3F, 0x3F and more then i receive 0xFF,0xFF and several times and basicaly i receive groups of 0x3F and groups of 0xFF, other register read correctly the default values but it still appear 0xFFs. I used some code I found in this forum, here below part of the code#include ''stm32f4xx.h''
#include ''stdint.h''
#include <
stdio.h
>
#define Rst_NSS1 GPIO_ResetBits(GPIOE,GPIO_Pin_3)
#define Set_NSS1 GPIO_SetBits(GPIOE,GPIO_Pin_3)
/*More codes*/
static void SystemClock_Config(void)
{
RCC_DeInit();
RCC_HSEConfig(RCC_HSE_ON);
while(RCC_GetFlagStatus(RCC_FLAG_HSERDY) == RESET);
if(RCC_WaitForHSEStartUp()){
RCC_PLLConfig(RCC_PLLSource_HSE,PLL_M,PLL_N,8,PLL_Q);
RCC_PLLCmd(ENABLE);
while(SET != RCC_GetFlagStatus(RCC_FLAG_PLLRDY));
//Delay(900);
RCC_SYSCLKConfig(RCC_SYSCLKSource_PLLCLK);
//while (RCC_GetFlagStatus(RCC_FLAG_PLLRDY) == RESET);
RCC_HCLKConfig(RCC_SYSCLK_Div1); //AHB clock = SYSCLK (168MHz)
RCC_PCLK1Config(RCC_HCLK_Div4); //APB1 clock = HCLK/4
RCC_PCLK2Config(RCC_HCLK_Div16); //APB2 clock = HCLK/16
RCC_GetClocksFreq(&Clocks);
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA | RCC_AHB1Periph_GPIOB | RCC_AHB1Periph_GPIOC | RCC_AHB1Periph_DMA2, ENABLE);
RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1 | RCC_APB2Periph_ADC2 | RCC_APB2Periph_ADC3, ENABLE);
RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1, ENABLE);// for USART1
RCC_APB2PeriphClockCmd(RCC_APB2Periph_SPI1, ENABLE);// for SPI1
RCC_APB1PeriphClockCmd(RCC_APB1Periph_SPI2, ENABLE);// for SPI2
RCC_APB1PeriphResetCmd(RCC_APB1Periph_SPI3, ENABLE);// for SPI3
//RCC_MCO1Config(RCC_MCO1Source_HSE,RCC_MCO1Div_1);
//RCC_MCO2Config(RCC_MCO2Source_PLLCLK,RCC_MCO2Div_1);
}
}
void Init_SPI1(void){
SPI_InitStructure.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_16;
SPI_InitStructure.SPI_CPHA = SPI_CPHA_2Edge;
SPI_InitStructure.SPI_CPOL = SPI_CPOL_High;
SPI_InitStructure.SPI_CRCPolynomial = 7;
SPI_InitStructure.SPI_DataSize = SPI_DataSize_8b;
SPI_InitStructure.SPI_Direction = SPI_Direction_2Lines_FullDuplex;
SPI_InitStructure.SPI_FirstBit = SPI_FirstBit_MSB;
SPI_InitStructure.SPI_Mode = SPI_Mode_Master;
SPI_InitStructure.SPI_NSS = SPI_NSS_Soft;
SPI_Init(SPI1,&SPI_InitStructure);
SPI_TIModeCmd(SPI1,DISABLE);
SPI_Cmd(SPI1,ENABLE);
SPI_CalculateCRC(SPI1, DISABLE);
void Init_GPIO(void){
/* SPI1 */
GPIO_PinAFConfig(GPIOA, GPIO_PinSource5, GPIO_AF_SPI1);
GPIO_PinAFConfig(GPIOA, GPIO_PinSource6, GPIO_AF_SPI1);
GPIO_PinAFConfig(GPIOA, GPIO_PinSource7, GPIO_AF_SPI1);
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_5 | GPIO_Pin_6 | GPIO_Pin_7; //(SCK|MISO|MOSI)
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL ;
GPIO_Init(GPIOA, &GPIO_InitStructure);
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_3; //(NSS : customized)
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT;
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL ;
GPIO_Init(GPIOE, &GPIO_InitStructure);
}
uint32_t Registro,i;
uint16_t tempo;
uint16_t ReadSPI = 0x7F;
uint16_t WriteSPI = 0x7F;
uint16_t Addr = 0x80;
#define RdAddrPlus(MemAdd) ((0x80 | MemAdd) | 0x40)
#define RdAddr(MemAdd) ((0x80 | MemAdd) & 0xBF)
#define WrAddrPlus(MemAdd) ((0x7F & MemAdd) | 0x40)
#define WrAddr(MemAdd) (0x7F & MemAdd & 0xBF)
uint16_t SPI_SendByte(uint16_t DataSpi)
{
while (SPI_I2S_GetFlagStatus(SPI1, SPI_I2S_FLAG_TXE) == 0){} //wait for transmit buffer to not be empty (ie data loaded in)
//USART_puts(USART1,''SPI bus Free\n\r'');
SPI_I2S_SendData(SPI1,DataSpi);
while (SPI_I2S_GetFlagStatus(SPI1, SPI_I2S_FLAG_RXNE) == 0){} //wait for transmit buffer to not be empty (ie data loaded in)
return(SPI_I2S_ReceiveData(SPI1)); // Clear out any pending RX data
}
int main()
{
SystemCoreClockUpdate();
SystemClock_Config();
if (SysTick_Config(SystemCoreClock / 168000)) { /* SysTick 1 msec interrupts */
while (1); /* Capture error */
}
Init_GPIO();
Init_USART1();
USART_ITConfig(USART1, USART_IT_RXNE, ENABLE); // enable the USART1 receive interrupt
NVIC_InitStructure.NVIC_IRQChannel = USART1_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
USART_Cmd(USART1, ENABLE); // enable USART1
USART_puts(USART1,''INICIO:D \n \r'');
NVIC_Configuration();
Init_SPI1();
/* SPI */
Rst_NSS1;
//Set_NSS1;
Delay(10);
//SPI_SendByte(RdAddr(0x0F));
while(1){
SPI_SendByte(RdAddr(0x20));
tempo = SPI_SendByte(RdAddr(0x00));
sprintf(texto,''SPI1 DR: %x \n\r'',tempo);
USART_puts(USART1,texto);
}
return 0;
}
I hope someone can help me with this
thanks in advance
#device #stm32f4 #stm32f4 #discovery #discovery #spi #spi #device
2016-09-21 02:26 PM
Hi arlen,
Maybe you should check your device addressing and communication direction. You can refer to this User manual, and for more details.Have a look at the SPI example under the
library: STM32F4xx_DSP_StdPeriph_Lib_V1.7.1\Project\STM32F4xx_StdPeriph_Examples\SPIRegards2016-09-22 02:29 PM
Hi
thanks for you help, I´ve checked the PCB discovery version, and I've just realized that it was the version 2013 which use the sensor LIS3DSH , no the LIS302, Now the register are read correctly, it is according to the datasheet however I still got 0xFF. someone had this trouble? I attach a picture showing the data in UART Thanks in advance ________________ Attachments : SPI_test.png : https://st--c.eu10.content.force.com/sfc/dist/version/download/?oid=00Db0000000YtG6&ids=0680X000006I1AZ&d=%2Fa%2F0X0000000bjw%2Fm_vr0bNO1xDrNLX9Ir7Q3ZZqocyXUZu7S3SO2WaAkGo&asPdf=false2016-09-23 08:33 AM
NSS pin uses GPIOE, but there's no:
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOE, ENABLE); HTH2016-09-23 01:35 PM
hi barton
Thanks for your help, Yes , i missed it, i've added it and it works, Now i can read the registers correctly, however i have noticed that the when i read the same register several times the first value is always 0xFF and the next values are read correctly , it is 0x21 (this is rigth value) Why does it happen?, i know that while SPI peripheral is sending the data,at the same time the SPI DR register is filled , the code below is the part how i read the same register several times:Ind=5;
/* SPI */
while(Ind){
Rst_NSS1;
Delay(10);
SPI_SendByte(RdAddr(0x0D)); //this function return the SPI DR register to clear out any pending RX data
tempo = SPI_SendByte(RdAddr(0x00));
Set_NSS1;
sprintf(texto,''SPI1 DR: %x
'',tempo);
USART_puts(USART1,texto);
Ind--;//while(1){
}
and I got :
0xFF
0x21
0x21
...
I tried to do a multireading using this code but it doesn't work, It gives only 0xFF:
Ind=5;
/* SPI */
Rst_NSS1;
Delay(10);
SPI_SendByte(RdAddr(0x0D)); //this function return the SPI DR register to clear out any pending RX data
while(Ind){
tempo = SPI_SendByte(RdAddr(0x00));
sprintf(texto,''SPI1 DR: %x
'',tempo);
USART_puts(USART1,texto);
Ind--;
}
Set_NSS1;
I not sure about that , but the multireading just works when it wannaa read several times increasing the address? or it can also be used reading the same register?
arlen
2016-09-24 12:22 AM
arlen
already suggested, I think you need to look at the ST examples for this board which work fine they are available here: http://www.st.com/content/st_com/en/products/embedded-software/mcus-embedded-software/stm32-embedded-software/stm32-standard-peripheral-libraries-expansions/stsw-stm32068.html