首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >为什么我的STM32f4DISCOVERY不能使用SPI?

为什么我的STM32f4DISCOVERY不能使用SPI?
EN

Stack Overflow用户
提问于 2015-04-23 23:15:58
回答 2查看 1.9K关注 0票数 1

这个问题我已经坚持了一段时间了。我在网上关注了几个例子,但都没有成功。我不能让它在我的STM32F4Discovery上工作。我有一个外部芯片(更具体地说,来自Semtech的SX1272),我试图与其进行SPI通信。通过Arduino做的时候,这都是孩子们的游戏,但用ST产品就不行了。我使用过示波器,它显示MOSI命令已发送,但没有MISO输出。(对于Arduino,这很好)。下面是我的代码:

代码语言:javascript
复制
#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峰值,这是不同步的。

EN

回答 2

Stack Overflow用户

发布于 2015-04-23 23:25:40

代码语言:javascript
复制
/* configure pins used by SPI1 
 * PA5 = SCK 
 * PA6 = MISO 
 * PA7 = MOSI 
 */

这表明您的MISO (主输入,从输出)信号在PA6上

代码语言:javascript
复制
  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
EN

Stack Overflow用户

发布于 2015-04-24 16:19:25

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

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/29827659

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档