2011-08-03 2 views
1

J'utilise STM32F103ZE Je n'obtiens pas correctement les données SPI. Le maître transmet correctement. Mais toujours lire comme zéro où une valeur non nulle a été envoyée.SPI lit les données comme zéro dans STM32F103ZE

config Master: (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_InitStructure.SPI_NSS = SPI_NSS_Soft 
    SPI_InitStructure.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_2 
    SPI_InitStructure.SPI_FirstBit = SPI_FirstBit_MSB 
    SPI_InitStructure.SPI_CRCPolynomial = 7 

Quelqu'un a une réponse,

Merci Hari

+0

Les forums de soutien de la STM sont assez actifs. J'essaierais là aussi. – leppie

+0

Avez-vous confirmé que la forme d'onde de tension sur la broche MISO est conforme aux attentes? –

+0

Oui. la tension est la même que prévue.J'ai également posté le même dans les forums de soutien ST aussi – Harikrishnan

Répondre

5

Je sais, la question est assez vieux. Cependant, comme j'ai fait face au même problème les derniers jours, j'essaierai de donner une réponse aux futurs lecteurs.

Le code suivant fonctionne sur le STM32F407, qui est utilisé sur la carte de découverte STM32. Ce que je peux voir à partir de la feuille de données, le périphérique SPI est le même que sur le STM32F103, donc Je m'attends à ce que le code fonctionne sur l'autre microcontrôleur sans 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); 

Deux choses sont différentes dans cette procédure d'initialisation à partir du code affiché dans la question:

  1. Ne pas sélectionner le mode bidirectionnel pour SPI ordinaire avec les 3 lignes SCK, MISO et MOSI. MISO et MOSI sont des lignes unidirectionnelles.

  2. J'utilise la gestion matérielle de sélection d'esclave, c'est-à-dire que le bit SSM n'est pas défini. De cette façon, le périphérique SPI peut détecter automatiquement quand le périphérique a été activé (la broche NSS passe à l'état bas) et stocke les bits MOSI dans un registre à décalage. Lorsque suffisamment de bits ont été lus (8 ou 16 en fonction du format de données sélectionné), l'indicateur RXNE est défini dans le registre d'état et la valeur transmise peut être lue à partir du registre DR.

Espérons que ça aide.

+2

Notez que la sémantique de l'interface périphérique est assez différente entre les familles STM32F1 et STM32F4 - le périphérique pourrait être le même, mais le façon dont il est connecté au processeur ** et les étapes nécessaires pour l'horloge et la connecter aux broches d'E/S ** sont sensiblement différentes. –

3

J'avais exactement le même problème d'obtenir la valeur 0x00 du registre de données.

Dans mon cas, le problème était que la ligne MISO était définie comme entrée flottante. Cela fonctionne après l'avoir changé en OType_PP. Voici mon code de configuration pour 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);} 

et fonction d'envoi:

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

Merci de votre réponse – Harikrishnan

+0

Les détails de la configuration des périphériques d'E/S sont assez différents entre le STM32F4 que vous utilisez et le STM32F1 de la question. –

Questions connexes