问题描述
我正在尝试将SPI接口与SPI ADXL345传感器和STM32F072 Nucleo板配合使用,我想进行非常基本的读取操作,但现在在等待RXNE信号时读取功能被阻止了,但是RXNE从不停止设置。 SPI始终读取0。我使用IAR,这是我的代码,我也使用这些功能来读写SPI。
int main()
{
USART2_Init();
SPIx_Init();
while (1) {
adxl_baslat();
receiveData[0] = readData(0x32);
receiveData[1] = readData(0x33);
receiveData[2] = readData(0x34);
receiveData[3] = readData(0x35);
receiveData[4] = readData(0x36);
receiveData[5] = readData(0x37);
x = (receiveData[1] << 8) | (receiveData[0]);
y = (receiveData[3] << 8) | (receiveData[2]);
z = (receiveData[5] << 8) | (receiveData[4]);
xg = (float)x * 0.0078;
yg = (float)x * 0.0078;
zg = (float)x * 0.0078;
sprintf(buffer,"xg: %f yg: %f zg: %f \r\n",xg,yg,zg);
USART_PutString(buffer);
}
}
void SPIx_Init()
{
SPI_InitTypeDef SPI_InitStruct;
GPIO_InitTypeDef GPIO_InitStruct;
RCC_APB2PeriphClockCmd(RCC_APB2Periph_SPI1,ENABLE);
SPI_InitStruct.SPI_BaudratePrescaler = SPI_BaudratePrescaler_16;
SPI_InitStruct.SPI_CPHA = SPI_CPHA_2Edge;
SPI_InitStruct.SPI_CPOL = SPI_CPOL_High;
SPI_InitStruct.SPI_DataSize = SPI_DataSize_8b;
SPI_InitStruct.SPI_Direction = SPI_Direction_2Lines_FullDuplex;
SPI_InitStruct.SPI_FirstBit = SPI_FirstBit_MSB;
SPI_InitStruct.SPI_Mode = SPI_Mode_Master;
SPI_InitStruct.SPI_NSS = SPI_NSS_Soft | SPI_NSSInternalSoft_Set;
SPI_Init(SPI1,&SPI_InitStruct);
SPI_Cmd(SPI1,ENABLE);
SPI_DataSizeConfig(SPI1,ENABLE);
SPI_RxFIFOThresholdConfig(SPI1,SPI_RxFIFOThreshold_QF);
// Step 2: Initialize GPIO
RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOA,ENABLE);
// GPIO pins for MOSI,MISO,and SCK
GPIO_InitStruct.GPIO_Pin = SPI_PIN_MOSI | SPI_PIN_MISO | SPI_PIN_SCK;
GPIO_InitStruct.GPIO_Mode = GPIO_Mode_AF;
GPIO_InitStruct.GPIO_OType = GPIO_OType_PP;
GPIO_InitStruct.GPIO_Speed = GPIO_Speed_10MHz;
GPIO_Init(GPIOA,&GPIO_InitStruct);
GPIO_PinAFConfig(GPIOA,GPIO_PinSource5,GPIO_AF_1);
GPIO_PinAFConfig(GPIOA,GPIO_PinSource6,GPIO_PinSource7,GPIO_AF_1);
RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOB,ENABLE);
GPIO_InitStruct.GPIO_Pin = SPI_PIN_SS;
GPIO_InitStruct.GPIO_Mode = GPIO_Mode_OUT;
GPIO_InitStruct.GPIO_OType = GPIO_OType_PP;
GPIO_InitStruct.GPIO_Speed = GPIO_Speed_10MHz;
GPIO_Init(GPIOB,&GPIO_InitStruct);
}
uint8_t sendByte(uint8_t bytetoSend)
{
timeout = TIMEOUT_TIME;
while ((SPI_I2S_GetFlagStatus(SPI1,SPI_I2S_FLAG_TXE) == RESET) & (timeout != 0)) {
timeout--;
}
SPI_SendData8(SPI1,bytetoSend);
timeout = TIMEOUT_TIME;
while ((SPI_I2S_GetFlagStatus(SPI1,SPI_I2S_FLAG_RXNE) == RESET) & (timeout != 0)) {
timeout--;
}
return (uint8_t)SPI_ReceiveData8(SPI1);
}
void writeData(uint8_t address,uint8_t dataToWrite)
{
DATA2 = address | 0x40;
GPIO_ResetBits(GPIOB,GPIO_Pin_9);
sendByte(DATA2);
sendByte(dataToWrite);
GPIO_SetBits(GPIOB,GPIO_Pin_9);
}
uint8_t readData(uint8_t address)
{
address |= 0x40;
address |= 0x80;
GPIO_ResetBits(GPIOB,GPIO_Pin_9);
sendByte(address);
tempByte = sendByte(address);
GPIO_SetBits(GPIOB,GPIO_Pin_9);
return tempByte;
}
void adxl_baslat(void)
{
writeData(0x31,0x01);
writeData(0x2d,0x00);
writeData(0x2d,0x08);
}
解决方法
您的初始化看起来很完整,但是我发现了一个错误:
GPIO引脚A5 / A6 / A7需要设置为GPIO_AF_0
(而不是GPIO_AF_1
),以便在这些引脚上获得SPI1 SCK / MISO / MOSI(请参见STM32F072数据表表15)。这就是为什么您可能总是从RX FIFO读取零的原因。
我有点想知道未设置RXNE标志。当SPI单元处于全双工主模式时,即使未正确配置GPIO引脚,它也应为每个发送的字节接收一个字节。但是我认为STM32F0处理这种情况的方式与旧的STM32L1不同:当我没记错的时候,我确实注意到在STM32F0上,SPI接收器似乎从GPIO引脚而不是直接从SPI发送器(产生它)获取时钟信号。因此,错误配置的SCK引脚也可能说明SPI RX单元什么也没收到。
,在接收有意义的数据之前,您需要清除接收FIFO或DR
uint8_t sendByte(uint8_t byteToSend)
{
timeout = TIMEOUT_TIME;
while ((SPI_I2S_GetFlagStatus(SPI1,SPI_I2S_FLAG_RXNE) != RESET)
{
uint8_t dummy;
dummy = *(volatile uint8_t *)&SPI1 -> DR;
}
timeout = TIMEOUT_TIME;
while ((SPI_I2S_GetFlagStatus(SPI1,SPI_I2S_FLAG_TXE) == RESET) & (timeout != 0)) {
timeout--;
}
SPI_SendData8(SPI1,byteToSend);
timeout = TIMEOUT_TIME;
while ((SPI_I2S_GetFlagStatus(SPI1,SPI_I2S_FLAG_RXNE) == RESET) & (timeout != 0)) {
timeout--;
}
return (uint8_t)SPI_ReceiveData8(SPI1);
}