开发者

SPI is reading data as zero in STM32F103ZE

I am using STM32F103ZE I am not getting SPI data correctly. Master is transmitting correctly. But always read as zero where a non zero value has been sent.

Master config: (MSP430)

The master configuration is correct. (I tested it.)
Master Mode, MSB First, 8-bit SPI, 
Inactive state is high, SS grounded, 1 MHz clock, no dividers

Slave Config (STM32F103ZE)

    Using SPI2.
    SPI_InitStructure.SPI_Direction = SPI_Direction_1Line_Rx
    SPI_InitStructure.SPI_Mode = SPI_Mode_Slave
    SPI_InitStructure.SPI_DataSize = SPI_DataSize_8b
    SPI_InitStructure.SPI_CPOL = SPI_CPOL_High
    SPI_InitStructure.SPI_CPHA = SPI_CPHA_1Edge
    SPI_InitStructur开发者_运维知识库e.SPI_NSS = SPI_NSS_Soft
    SPI_InitStructure.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_2
    SPI_InitStructure.SPI_FirstBit = SPI_FirstBit_MSB
    SPI_InitStructure.SPI_CRCPolynomial = 7

Anybody have an ANSWER,

Thanks Hari


I know, the question is quite old. Still, since I have faced the same problem the last days, I'll try to give an answer for future readers.

The following code works on the STM32F407, which is used on the STM32 discovery board. What I can see from the datasheet, the SPI peripheral is the same as on the STM32F103, so I expect the code to run on the other microcontroller without modifications.

#include "stm32f4xx.h"

[... configure the pins SCK, MISO, MOSI and NSS ...]

// Configure the SPI as: Slave, 8 bit data, clock high when idle, capture on 
// 1st edge, baud rate prescaler 2, MSB first.
SPI1->CR1 = SPI_CR1_CPOL;
// No interrupts, no DMA and Motorola frame format.
SPI1->CR2 = 0;
// Enable the peripheral.
SPI1->CR1 |= SPI_CR1_SPE;

// Wait until some data has been sent to the slave and print it.
while ((SPI1->SR & SPI_SR_RXNE) == 0);
printf("Received: %d\n", SPI1->DR);

Two things are different in this initialization procedure from the code posted in the question:

  1. Do not select bidirectional mode for ordinary SPI with the 3 lines SCK, MISO and MOSI. Both MISO and MOSI are unidirectional lines.

  2. I use hardware slave select management, i.e. the bit SSM is not set. This way, the SPI peripheral can automatically detect when the device has been asserted (the pin NSS goes low) and will store the MOSI bits in a shift register. When enough bits have been read (8 or 16 depending on the selected data format), the flag RXNE is set in the status register and the transmitted value can be read from the register DR.

Hope that helps.


I had exactly the same problem of getting 0x00 value from data register.

In my case the problem was that MISO line was set as floating input. It works after changing it to OType_PP. Here is my configuration code for STM32F429:

void SPI1_Config(void){
GPIO_InitTypeDef GPIO_InitStruct;
SPI_InitTypeDef SPI_InitStruct;

RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA, ENABLE);

RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOE, ENABLE);

RCC_APB2PeriphClockCmd(RCC_APB2Periph_SPI1, ENABLE);

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

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_InitStruct.GPIO_Pin = GPIO_Pin_7;
GPIO_InitStruct.GPIO_Mode = GPIO_Mode_OUT;
GPIO_InitStruct.GPIO_OType = GPIO_OType_PP;
GPIO_InitStruct.GPIO_Speed = GPIO_Speed_100MHz;
GPIO_InitStruct.GPIO_PuPd = GPIO_PuPd_UP;
GPIO_Init(GPIOE, &GPIO_InitStruct);
GPIOE->BSRRL |= GPIO_Pin_7;

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_Soft | SPI_NSSInternalSoft_Set;
SPI_InitStruct.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_256;
SPI_InitStruct.SPI_FirstBit = SPI_FirstBit_MSB;
SPI_Init(SPI1, &SPI_InitStruct);

SPI_Cmd(SPI1, ENABLE);}

And sending function:

uint8_t SPI1_Send(uint8_t data){
while (SPI_I2S_GetFlagStatus(SPI1, SPI_I2S_FLAG_TXE) == RESET);

SPI_I2S_SendData(SPI1, data);

while (SPI_I2S_GetFlagStatus(SPI1, SPI_I2S_FLAG_RXNE) == RESET);

return SPI_I2S_ReceiveData(SPI1);}
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜