2015-06-19 42 views
0
#include <stm32f4xx.h> 
#include "stm32f4xx_spi.h" 
#include "stm32f4xx_gpio.h" 
#include "stm32f4xx_rcc.h" 
#include "config.h" 

void init_GPIO() 
{ 
GPIO_InitTypeDef GPIO_InitStructure; 
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOI,ENABLE); 

GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10; 
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT; 
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz; 
GPIO_InitStructure.GPIO_OType = GPIO_OType_PP; 
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL; 
GPIO_Init(GPIOI , &GPIO_InitStructure); 
} 


void SPI1_Configuration_master(void) 
{ 
SPI_InitTypeDef SPI_InitStruct; 
GPIO_InitTypeDef GPIO_InitStructure; 

RCC_AHB1PeriphClockCmd(Open_SPI1_SCK_GPIO_CLK | Open_SPI1_MISO_GPIO_CLK | Open_SPI1_MOSI_GPIO_CLK |Open_SPI1_NSS_GPIO_CLK ,ENABLE); 
RCC_APB2PeriphClockCmd(Open_RCC_APB2Periph_SPI1,ENABLE); 

GPIO_PinAFConfig(Open_SPI1_SCK_GPIO_PORT, Open_SPI1_SCK_SOURCE, Open_SPI1_MOSI_AF); 
GPIO_PinAFConfig(Open_SPI1_MISO_GPIO_PORT, Open_SPI1_MISO_SOURCE, Open_SPI1_MOSI_AF); 
GPIO_PinAFConfig(Open_SPI1_MOSI_GPIO_PORT, Open_SPI1_MOSI_SOURCE, Open_SPI1_MOSI_AF); 
GPIO_PinAFConfig(Open_SPI1_NSS_GPIO_PORT, Open_SPI1_NSS_SOURCE, Open_SPI1_NSS_AF); 

GPIO_InitStructure.GPIO_Pin = Open_SPI1_SCK_PIN; 
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF; 
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz; 
GPIO_InitStructure.GPIO_OType = GPIO_OType_PP; 
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_DOWN; 
GPIO_Init(Open_SPI1_SCK_GPIO_PORT, &GPIO_InitStructure); 

GPIO_InitStructure.GPIO_Pin = Open_SPI1_MISO_PIN; 
GPIO_Init(Open_SPI1_MISO_GPIO_PORT, &GPIO_InitStructure); 

GPIO_InitStructure.GPIO_Pin = Open_SPI1_MOSI_PIN; 
GPIO_Init(Open_SPI1_MOSI_GPIO_PORT, &GPIO_InitStructure); 

GPIO_InitStructure.GPIO_Pin = Open_SPI1_NSS_PIN; 
GPIO_Init(Open_SPI1_NSS_GPIO_PORT, &GPIO_InitStructure); 


SPI_I2S_DeInit(Open_SPI1); 
SPI_InitStruct.SPI_Direction= SPI_Direction_2Lines_FullDuplex; 
SPI_InitStruct.SPI_DataSize = SPI_DataSize_8b; 
SPI_InitStruct.SPI_Mode = SPI_Mode_Master; 
SPI_InitStruct.SPI_CPOL = SPI_CPOL_High; 
SPI_InitStruct.SPI_CPHA = SPI_CPHA_2Edge; 
SPI_InitStruct.SPI_NSS = SPI_NSS_Soft ; 
SPI_InitStruct.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_128; 
SPI_InitStruct.SPI_FirstBit = SPI_FirstBit_MSB; 
SPI_InitStruct.SPI_CRCPolynomial = 7; 
SPI_Init(Open_SPI1, &SPI_InitStruct); 

SPI_Cmd(Open_SPI1, ENABLE); 

} 
void SPI_Configuration2_slave(void) 
{ 
SPI_InitTypeDef SPI_InitStruct; 
GPIO_InitTypeDef GPIO_InitStructure; 

RCC_AHB1PeriphClockCmd(Open_SPI2_SCK_GPIO_CLK | Open_SPI2_MISO_GPIO_CLK | Open_SPI2_MOSI_GPIO_CLK| Open_SPI2_NSS_GPIO_CLK,ENABLE); 
RCC_APB1PeriphClockCmd(RCC_APB1Periph_SPI2,ENABLE); 

GPIO_PinAFConfig(Open_SPI2_SCK_GPIO_PORT, Open_SPI2_SCK_SOURCE, Open_SPI2_MOSI_AF); 
GPIO_PinAFConfig(Open_SPI2_MISO_GPIO_PORT, Open_SPI2_MISO_SOURCE, Open_SPI2_MOSI_AF); 
GPIO_PinAFConfig(Open_SPI2_MOSI_GPIO_PORT, Open_SPI2_MOSI_SOURCE, Open_SPI2_MOSI_AF); 
GPIO_PinAFConfig(Open_SPI2_MOSI_GPIO_PORT, Open_SPI2_NSS_SOURCE, Open_SPI2_MOSI_AF); 

GPIO_InitStructure.GPIO_Pin = Open_SPI2_SCK_PIN; 
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF; 
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz; 
GPIO_InitStructure.GPIO_OType = GPIO_OType_PP; 
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_DOWN; 
GPIO_Init(Open_SPI2_SCK_GPIO_PORT, &GPIO_InitStructure); 

GPIO_InitStructure.GPIO_Pin = Open_SPI2_MISO_PIN; 
GPIO_Init(Open_SPI2_MISO_GPIO_PORT, &GPIO_InitStructure); 

GPIO_InitStructure.GPIO_Pin = Open_SPI2_MOSI_PIN; 
GPIO_Init(Open_SPI2_MOSI_GPIO_PORT, &GPIO_InitStructure); 

GPIO_InitStructure.GPIO_Pin = Open_SPI2_NSS_PIN; 
GPIO_Init(Open_SPI2_MOSI_GPIO_PORT, &GPIO_InitStructure); 

SPI_I2S_DeInit(Open_SPI2); 
SPI_InitStruct.SPI_Direction= SPI_Direction_2Lines_FullDuplex; 
SPI_InitStruct.SPI_DataSize = SPI_DataSize_8b; 
SPI_InitStruct.SPI_Mode = SPI_Mode_Slave; 
SPI_InitStruct.SPI_CPOL = SPI_CPOL_High; 
SPI_InitStruct.SPI_CPHA = SPI_CPHA_2Edge; 
SPI_InitStruct.SPI_NSS = SPI_NSS_Soft ; 
//SPI_InitStruct.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_128; 
SPI_InitStruct.SPI_FirstBit = SPI_FirstBit_MSB; 
SPI_InitStruct.SPI_CRCPolynomial = 7; 
SPI_Init(Open_SPI2, &SPI_InitStruct); 

SPI_Cmd(Open_SPI2, ENABLE); 

} 

u16 SPI2_Send_byte(u16 data) 
{ 
while(SPI_I2S_GetFlagStatus(Open_SPI2, SPI_I2S_FLAG_TXE)==RESET); 
SPI_I2S_SendData(Open_SPI2,data); 

while(SPI_I2S_GetFlagStatus(Open_SPI2, SPI_I2S_FLAG_RXNE)==RESET); 
return SPI_I2S_ReceiveData(Open_SPI2); 
} 

u16 SPI2_Receive_byte(void) 
{/* 
while(SPI_I2S_GetFlagStatus(Open_SPI2, SPI_I2S_FLAG_TXE)==RESET); 
SPI_I2S_SendData(Open_SPI2,0x00); 
*/ 
while(SPI_I2S_GetFlagStatus(Open_SPI2, SPI_I2S_FLAG_RXNE)==RESET); 
return SPI_I2S_ReceiveData(Open_SPI2); 
} 

u16 SPI_Send_byte(u16 data) 
{ 
GPIO_ResetBits(GPIOI,GPIO_Pin_10); 
while(SPI_I2S_GetFlagStatus(Open_SPI1, SPI_I2S_FLAG_TXE)==RESET); 
SPI_I2S_SendData(Open_SPI1,data); 

while(SPI_I2S_GetFlagStatus(Open_SPI1, SPI_I2S_FLAG_RXNE)==RESET); 
GPIO_SetBits(GPIOI,GPIO_Pin_10); 
return SPI_I2S_ReceiveData(Open_SPI1); 
} 

u16 SPI_Receive_byte(u16 data) 
{ 
/*while(SPI_I2S_GetFlagStatus(Open_SPI1, SPI_I2S_FLAG_TXE)==RESET); 
SPI_I2S_SendData(Open_SPI1,data); 
*/ 
while(SPI_I2S_GetFlagStatus(Open_SPI1, SPI_I2S_FLAG_RXNE)==RESET); 
return SPI_I2S_ReceiveData(Open_SPI1); 
} 

int main() 
{ 
char a; 
init_GPIO(); 
SPI_Configuration2_slave(); 
SPI1_Configuration_master(); 
GPIO_SetBits(GPIOI,GPIO_Pin_10); 
while(1) 
{ 
    a =SPI_Send_byte((u16)'a'); 
    a = SPI2_Receive_byte(); 
} 
return 0; 
} 

我想實現的STM32F407ig 我目前想實現在同一板上的兩個SPI1和SPI2之間的通信靈寶。 我嘗試了板間通信的類似代碼。 當我回到mosi和大師味噌我得到的數據傳輸。 但奴隸沒有收到任何東西或它收到零。 建立的連接是正確的。 也像Open_SPI1使用的宏是正確的。Stm32f407IG SPI通信

我想知道我的SPI主設備和從設備的配置是否正確。

有人能否詳細說明NSS軟件如何正確工作。

回答

0

我在STM32F2系列上遇到了SPI問題。我不得不手動切換NSS行,然後一切正常。不知道F4是否有同樣的問題(甚至可能是設計)。這是我的代碼:

/******************************************************************************/ 
void SPI_GPIO_init(void) 
{ 
    GPIO_InitTypeDef GPIO_InitStructure; 

    /* Configure SPI pins SCK and MOSI to be hardware controlled */ 
    GPIO_InitStructure.GPIO_Pin  = SPI_PIN_SCK | SPI_PIN_MOSI; 
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; 
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; 
    GPIO_Init(SPI_GPIO_PORT, &GPIO_InitStructure); 

    /* Configure SPI pin MISO to be an input pin since we are master */ 
    GPIO_InitStructure.GPIO_Pin  = SPI_PIN_MISO; 
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; 
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING; 
    GPIO_Init(SPI_GPIO_PORT, &GPIO_InitStructure); 

    /* Configure SPI pin NSS to be a regular GPIO output. This is due to STM32 
    * goofy handling of SPI: NSS stays low for the entire duration of SPI being 
    * enabled instead of being released after outgoing data is completed. This 
    * is basically a HW bug but it definitely mentiones this in the Ref Manual. 
    * 
    * From the reference manual RM0090: 
    * - NSS output enabled (SSM = 0, SSOE = 1) 
    * This configuration is used only when the device operates in master mode. 
    * The NSS signal is driven low when the master starts the communication and 
    * is kept low until the SPI is disabled. 
    * 
    * Instead, we are going to drive this pin manually as CLRC663 chip expects 
    * */ 
    GPIO_InitStructure.GPIO_Pin  = SPI_PIN_NSS; 
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; 
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; 
    GPIO_Init(SPI_GPIO_PORT, &GPIO_InitStructure); 

    SPI_NSS_high(); 
    DelayMS(1); 

} 

/******************************************************************************/ 
void SPI_NSS_high(void) 
{ 
    GPIO_WriteBit(SPI_GPIO_PORT, SPI_PIN_NSS, Bit_SET); 
} 

/******************************************************************************/ 
void SPI_NSS_low(void) 
{ 
    GPIO_WriteBit(SPI_GPIO_PORT, SPI_PIN_NSS, Bit_RESET); 
} 

/******************************************************************************/ 
void SPI_init(void) 
{ 
    SPI_I2S_DeInit(SPI1); 

    SPI_NSS_high(); 

    SPI_InitTypeDef SPI_InitStructure; 

    /* SPI1 configuration */ 
    SPI_InitStructure.SPI_Direction   = SPI_Direction_2Lines_FullDuplex; 
    SPI_InitStructure.SPI_Mode    = SPI_Mode_Master; 
    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_16; 
    SPI_InitStructure.SPI_FirstBit   = SPI_FirstBit_MSB; 
    SPI_InitStructure.SPI_CRCPolynomial  = 0; 
    SPI_Init(SPI1, &SPI_InitStructure); 

    SPI_Cmd(SPI1, ENABLE); 

    /* Not using interrupts for SPI communication so don't enable the NVIC and 
    * the ISR for it.*/ 
} 

/******************************************************************************/ 
Error SPI_send(uint8_t *snd_buf, uint8_t snd_buf_len) 
{ 
    uint8_t snd_indx  = 0; 
    uint8_t spi_retry  = 0; 

    SPI_NSS_low(); /* Assert the NSS pin low to become SPI bus master */ 

    for (snd_indx = 0; snd_indx < snd_buf_len; snd_indx++) 
    { 
     /* When SPI Tx buffer is empty, send data. Make sure we don't get 
     * stuck in an inf loop while waiting for HW */ 
     spi_retry = 0; 
     while (SET != SPI_I2S_GetFlagStatus(SPI1, SPI_I2S_FLAG_TXE)) 
     { 
     if (0xFF == spi_retry++) 
     { 
      err_printf("Reached SPI hardware retries trying to send data over SPI bus\n"); 
      return (ERR_HW_SPI_TIMEOUT); 
     } 
     } 
     SPI_I2S_SendData(SPI1, snd_buf[ snd_indx ]); 
     //  debug_printf("Sent %02x\n", snd_buf[ snd_indx ]); 

     /* Get the dummy byte coming back when SPI Rx buffer is empty. Make sure 
     * we don't get stuck in an inf loop while waiting for HW */ 
     spi_retry = 0; 
     while (SET != SPI_I2S_GetFlagStatus(SPI1, SPI_I2S_FLAG_RXNE)) 
     { 
     if (0xFF == spi_retry++) 
     { 
      err_printf("Reached SPI hardware retries trying to receive data over SPI bus\n"); 
      return (ERR_HW_SPI_TIMEOUT); 
     } 
     } 
     SPI_I2S_ReceiveData(SPI1); /* Dummy byte so no need to store it */ 
    } 

    SPI_NSS_high(); /* Assert the NSS pin high to release SPI bus master */ 

    return (ERR_NONE); 
} 

/******************************************************************************/ 
Error SPI_transceive(
         uint8_t *snd_buf, 
         uint8_t snd_buf_len, 
         uint8_t *rcv_buf, 
         uint8_t rcv_buf_len 
        ) 
{ 
    uint8_t snd_indx  = 0; 
    uint8_t rcv_indx  = 0; 
    uint16_t spi_retry  = 0; 

    SPI_NSS_low(); /* Assert the NSS pin low to become SPI bus master */ 

    if (snd_buf_len != rcv_buf_len) 
    { 
     err_printf("SPI expects to receive same amount of data that it is sending\n"); 
     return (ERR_HW_SPI_LENGTH_MISMATCH); 
    } 

    for (snd_indx = 0; snd_indx < snd_buf_len; snd_indx++, rcv_indx++) 
    { 
     /* When SPI Tx buffer is empty, send data. Make sure we don't get 
     * stuck in an inf loop while waiting for HW */ 
     spi_retry = 0; 
     while (SET != SPI_I2S_GetFlagStatus(SPI1, SPI_I2S_FLAG_TXE)) 
     { 
     if (0xFF == spi_retry++) 
     { 
      err_printf("Reached SPI hardware retries trying to send data over SPI bus\n"); 
      return (ERR_HW_SPI_TIMEOUT); 
     } 
     } 
     SPI_I2S_SendData(SPI1, snd_buf[ snd_indx ]); 

     /* Now receive the reply when the Rx buffer is empty. Make sure we don't 
     * get stuck in an inf loop while waiting for HW */ 
     spi_retry = 0; 
     while (SET != SPI_I2S_GetFlagStatus(SPI1, SPI_I2S_FLAG_RXNE)) 
     { 
     if (0xFF == spi_retry++) 
     { 
      err_printf("Reached SPI hardware retries trying to receive data over SPI bus\n"); 
      return (ERR_HW_SPI_TIMEOUT); 
     } 
     } 
     uint8_t data = SPI_I2S_ReceiveData(SPI1); 
     rcv_buf[ rcv_indx ] = data; 
     //  debug_printf("Got %02x\n", data); 
    } 

    SPI_NSS_high(); /* Assert the NSS pin high to release SPI bus master */ 

    return (ERR_NONE); 
}