我正在使用STM32F407vg并且我试图在SPI数据寄存器中写入数据,以下代码显示了配置功能
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
}
这是发送数据的功能
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中提取的
答案 0 :(得分:4)
SPI DR寄存器不是正常的存储器位置,写入和读取访问同一存储器。
相反,写入加载输出移位寄存器,而读取读取接收的输入。根据设备的详细信息,阅读也可以"声明"输入,从寄存器中清除它直到收到另一个字。
由于这些原因,尝试使用调试器观察SPI DR不仅不会向您提供您寻找的信息,甚至可能会损坏您将收到的数据。
答案 1 :(得分:2)
从this book读取SPI部分后,我的问题解决了,我只需将SPI MOSI连接到SPI MISO引脚(PA6和PA7),然后使用以下功能:
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 :(得分:0)
请注意SCLK_freq = APB2_freq /(BaudRatePrescaler + 1)