为什么SPI无法使用我的STM32f4DISCOVERY?

时间:2015-04-23 15:15:58

标签: c embedded spi stm32f4discovery

我已经坚持了一段时间。我在网上关注了一些例子,但没有成功。我无法使用STM32F4Discovery。我有一个外部芯片(Semtech的SX1272更具体),我尝试与SPI通信。这是通过Arduino进行的所有儿童游戏,但ST产品没有运气。 我使用了示波器,它显示MOSI命令已发送,但没有MISO出去。 (使用Arduino,这很好)。这是我的代码:

#include "main.h"

void init_SPI1(void){   


  GPIO_InitTypeDef GPIO_InitStruct; 
  SPI_InitTypeDef SPI_InitStruct; 

  // enable clock for used IO pins 
  RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA, ENABLE); 

  /* configure pins used by SPI1 
  * PA5 = SCK 
  * PA6 = MISO 
  * PA7 = MOSI 
  */ 
  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_50MHz; 
  GPIO_InitStruct.GPIO_PuPd = GPIO_PuPd_NOPULL; 
  GPIO_Init(GPIOA, &GPIO_InitStruct); 

  // connect SPI1 pins to SPI alternate function 
  GPIO_PinAFConfig(GPIOA, GPIO_PinSource5, GPIO_AF_SPI1); 
  GPIO_PinAFConfig(GPIOA, GPIO_PinSource6, GPIO_AF_SPI1); 
  GPIO_PinAFConfig(GPIOA, GPIO_PinSource7, GPIO_AF_SPI1); 

  // enable clock for used IO pins 
  RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOE, ENABLE); 

  /* Configure the chip select pin 
  in this case we will use PE7 */ 
  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_50MHz; 
  GPIO_InitStruct.GPIO_PuPd = GPIO_PuPd_UP; 
  GPIO_Init(GPIOE, &GPIO_InitStruct); 

  GPIO_SetBits(GPIOE, GPIO_Pin_7); // set PE7 high 

  // enable peripheral clock 
  RCC_APB2PeriphClockCmd(RCC_APB2Periph_SPI1, ENABLE); 

  /* configure SPI1 in Mode 0  
  * CPOL = 0 --> clock is low when idle 
  * CPHA = 0 --> data is sampled at the first edge 
  */ 
  SPI_InitStruct.SPI_Direction =                SPI_Direction_2Lines_FullDuplex;        // set to full duplex mode, seperate MOSI and MISO lines 
  SPI_InitStruct.SPI_Mode =                     SPI_Mode_Master;                        // transmit in master mode, NSS pin has to be always high 
  SPI_InitStruct.SPI_DataSize =                 SPI_DataSize_8b;                        // one packet of data is 8 bits wide 
  SPI_InitStruct.SPI_CPOL =                     SPI_CPOL_High;                           // clock is low when idle 
  SPI_InitStruct.SPI_CPHA =                     SPI_CPHA_1Edge;                         // data sampled at first edge 
  SPI_InitStruct.SPI_NSS =                      SPI_NSS_Soft | SPI_NSSInternalSoft_Set; // set the NSS management to internal and pull internal NSS high 
  SPI_InitStruct.SPI_BaudRatePrescaler =        SPI_BaudRatePrescaler_64;                // SPI frequency is APB2 frequency / 4 
  SPI_InitStruct.SPI_FirstBit =                 SPI_FirstBit_MSB;                       // data is transmitted MSB first 
  SPI_Init(SPI1, &SPI_InitStruct);  

  SPI_Cmd(SPI1, ENABLE); // enable SPI1 
} 


/* This funtion is used to transmit and receive data  
* with SPI1 
*           data --> data to be transmitted 
*           returns received value 
*/ 
uint8_t SPI1_read(uint8_t data){   
  GPIO_ResetBits(GPIOE, GPIO_Pin_7); // set PE7 (CS) low 

  SPI1->DR = data; // write data to be transmitted to the SPI data register 
  while( !(SPI1->SR & SPI_I2S_FLAG_TXE) ); // wait until transmit complete 
  while( SPI1->SR & SPI_I2S_FLAG_BSY ); // wait until SPI is not busy anymore 

  GPIO_SetBits(GPIOE, GPIO_Pin_7); // set PE7 (CS) high
  uint8_t ret = SPI1->DR;
  return ret; // return received data from SPI data register 
} 


void SPI1_write(uint8_t address, uint8_t data){ 

  uint16_t comb = (address << 8) | data;
  GPIO_ResetBits(GPIOE, GPIO_Pin_7); // set PE7 (CS) low 

  SPI1->DR = address; // write data to be transmitted to the SPI data register 
  while( !(SPI1->SR & SPI_I2S_FLAG_TXE) ); // wait until transmit complete 
  //while( SPI1->SR & SPI_I2S_FLAG_BSY ); // wait until SPI is not busy anymore 

  SPI1->DR = data; // write data to be transmitted to the SPI data register 
  while( !(SPI1->SR & SPI_I2S_FLAG_TXE) ); // wait until transmit complete 
  while( SPI1->SR & SPI_I2S_FLAG_BSY ); // wait until SPI is not busy anymore 

  GPIO_SetBits(GPIOE, GPIO_Pin_7); // set PE7 (CS) high   
} 

int main(void){ 

  init_SPI1(); 

  while(1){  
    SPI1_read(0x01); 
  } 
} 

我从MOSI获得的是一个随机的~1.5V峰值,它不同步。

2 个答案:

答案 0 :(得分:1)

/* configure pins used by SPI1 
 * PA5 = SCK 
 * PA6 = MISO 
 * PA7 = MOSI 
 */

这表明您的MISO(主 ,奴隶外出)信号在PA6上

  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_50MHz; 
  GPIO_InitStruct.GPIO_PuPd = GPIO_PuPd_NOPULL; 
  GPIO_Init(GPIOA, &GPIO_InitStruct); 

但是这会将PA6配置为输出

将PA6配置为输入,然后重试。如果它仍然不起作用,请尝试通过一个1K左右的电阻器注入一个电平,看看是否可以同时获得范围内的电压和接收到的值来反映这一点。

答案 1 :(得分:0)

您是否尝试过使用ST配置工具STM32Cube来生成初始化和通信接口代码。我用它在大约一个小时内使用DMA传输生成时钟设置USART,I2C和SPI通信接口。它包括F4发现板的预定义配置。当我将传输加载到DMA并在传输完成中断回调函数中再次设置时,我所要做的就是清除CS线。