STM32F103使用SPI读取ADXL345数据为0、RXNE未置位问题求助
问题排查与修复方案
- CS引脚配置完全不匹配
你的GPIO初始化中仅配置了PA4为NSS引脚,但CS_Enable()/CS_Disable()操作的是PA9,且PA9完全没有被初始化为输出模式,ADXL345的片选引脚始终未被正确拉低,器件不会响应任何SPI指令,自然不会返回数据导致RXNE永远不置位。 - NSS引脚输出模式错误
你将PA4配置为开漏输出(Out_OD),如果没有外部上拉电阻,引脚无法正常输出高电平,即使后续改用PA4作为CS引脚也会通信失败,软件控制的CS引脚建议配置为推挽输出。 - SPI收发逻辑存在溢出隐患
SPI是全双工通信,每发送1字节数据的同时会收到1字节数据,你现有的SPI_Transmission函数只发不读,累计多字节发送后容易触发OVR溢出标志,导致SPI通信异常。
修复步骤
- 统一CS引脚定义,比如改用PA4作为CS引脚,修改CS控制函数:
void CS_Enable (void) { GPIOA->BSRR |= GPIO_BSRR_BR4; // 拉低PA4 } void CS_Disable (void) { GPIOA->BSRR |= GPIO_BSRR_BS4; // 拉高PA4 }
- 修改GPIO配置中PA4的输出模式为推挽输出:
MyGPIO_Struct_TypeDef NSS={GPIOA,4,Out_PP}; // 改为推挽输出
- 优化
SPI_Transmission函数,发送每个字节后读取DR避免溢出:
void SPI_Transmission(uint8_t *data, int size){ uint8_t temp; int i=0; while (i<size) { while (!((SPI1->SR)&(SPI_SR_TXE))){}; *(volatile uint8_t *)&SPI1->DR = data[i]; while (!((SPI1->SR) &(SPI_SR_RXNE))){}; temp = *(volatile uint8_t *)&SPI1->DR; // 读走接收的数据避免溢出 i++; } while (((SPI1->SR)&(SPI_SR_BSY))){}; }
- 可适当降低SPI波特率测试,避免通信时序不匹配,比如将波特率分频改为256分频:
SPI1->CR1 |= SPI_CR1_BR_0 | SPI_CR1_BR_1 | SPI_CR1_BR_2; // 72M/256≈281KHz
内容的提问来源于stack exchange,提问作者zalix
相关产品推荐
相关产品推荐

