首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >STM32F4 SPI发行

STM32F4 SPI发行
EN

Stack Overflow用户
提问于 2015-11-29 13:04:17
回答 3查看 4.4K关注 0票数 2

使用STM32F407vg和我试图在SPI数据寄存器中写入数据,下面的代码显示了配置函数

代码语言:javascript
复制
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
     * PA4 = NSS
 * PA5 = SCK
 * PA6 = MISO
 * PA7 = MOSI
 */
GPIO_InitStruct.GPIO_Pin = GPIO_Pin_7 | GPIO_Pin_6 | GPIO_Pin_5|GPIO_Pin_4;
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_PinSource4, GPIO_AF_SPI1);
GPIO_PinAFConfig(GPIOA, GPIO_PinSource5, GPIO_AF_SPI1);
GPIO_PinAFConfig(GPIOA, GPIO_PinSource6, GPIO_AF_SPI1);
GPIO_PinAFConfig(GPIOA, GPIO_PinSource7, GPIO_AF_SPI1);

//Set chip select high 
GPIOA->BSRRL |= GPIO_Pin_4; // set PE4 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_StructInit(&SPI_InitStruct); // set default config 
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_Low;        // clock is low when idle
SPI_InitStruct.SPI_CPHA = SPI_CPHA_1Edge;      // data sampled at first edge
SPI_InitStruct.SPI_NSS = SPI_NSS_Soft ; // set the NSS management to internal and pull internal NSS high
SPI_InitStruct.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_4; // 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
} 

这是发送数据的函数

代码语言:javascript
复制
 uint8_t SPI1_send(uint8_t data){

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_RXNE) ); // wait until receive complete
while( SPI1->SR & SPI_I2S_FLAG_BSY ); // wait until SPI is not busy anymore
return SPI1->DR; // return received data from SPI data register
}

我认为我已经设置了良好的配置(在我看来,引脚的选择并没有错,所用总线的配置也是正确的)下面的图片是从STM32F407 DataSheet中提取出来的

问题在于DR注册表中的数据与作为参数传递的数据不同。

.I不知道为什么会这样

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2015-12-24 13:41:02

在阅读了这本书的SPI部分之后,我的问题解决了,我只需将SPI连接到SPI引脚(PA6和PA7),然后使用以下函数:

代码语言:javascript
复制
int spiReadWrite(SPI_TypeDef* SPIx, uint8_t *rbuf,
const uint8_t *tbuf, int cnt, enum spiSpeed speed)
{
int i;
SPIx->CR1 = (SPIx->CR1 & ~SPI_BaudRatePrescaler_256) |
speeds[speed];
for (i = 0; i < cnt; i++){
  if (tbuf) {
  SPI_I2S_SendData(SPIx, *tbuf++);
  } else {
  SPI_I2S_SendData(SPIx, 0xff);
  }
while (SPI_I2S_GetFlagStatus(SPIx, SPI_I2S_FLAG_RXNE) == RESET);
  if (rbuf) {
  *rbuf++ = SPI_I2S_ReceiveData(SPIx);
  } else {
  SPI_I2S_ReceiveData(SPIx);
  }
}
return i;
}

通过使用调试器,我可以看到(从tbuf)发送的数据是成功地接收到的(在rbuf中)。

票数 2
EN

Stack Overflow用户

发布于 2015-11-29 16:51:24

SPI DR寄存器不是写入和读取相同存储器的正常内存位置。

相反,写入加载输出移位寄存器,同时读取接收到的输入。根据设备的详细信息,读取还可以“声明”输入,从寄存器中清除输入,直到收到另一个单词。

由于这些原因,尝试使用调试器监视SPI博士不仅不会给您提供所需的信息,甚至可能会对您本来会收到的数据造成损害。

票数 4
EN

Stack Overflow用户

发布于 2017-04-28 16:06:58

注意,SCLK_freq = APB2_freq / (BaudRatePrescaler + 1)

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

https://stackoverflow.com/questions/33983091

复制
相关文章

相似问题

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