最近公司项目需要做双STM32F4的SPI通讯,结果遇到了问题。主设备有信号发出来,但是从设备接收不到,进不了中断函数,我把SPI_I2S_ReceiveData(SPI1);单独拿出来也没有收到数据,看了一天半了,还没找到问题,希望各位前辈能提供帮助。我能确定的是我的主设备有信号发出,最后有示波器的图。
以下是从设备SPI配置代码
void SPI1_init(void)
{
SPI_InitTypeDef SPI_InitStructure;
GPIO_InitTypeDef GPIO_InitStructure;
NVIC_InitTypeDef NVIC_InitStructure;
/* 开启SPI1时钟 */
RCC_APB2PeriphClockCmd(RCC_APB2Periph_SPI1, ENABLE);
/* 开启GPIOA时钟 */
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA, ENABLE);
/* 引脚复用 */
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);
/* PA4:SS1 */
/* PA5:SCK */
/* PA6:MISO */
/* PA7:MOSI */
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_4 | GPIO_Pin_5 | GPIO_Pin_6 | GPIO_Pin_7;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;
GPIO_Init(GPIOA, &GPIO_InitStructure);
// SPI1_CSS_ENABLE;
SPI_InitStructure.SPI_Direction = SPI_Direction_2Lines_FullDuplex;
SPI_InitStructure.SPI_Mode = SPI_Mode_Slave;
SPI_InitStructure.SPI_DataSize = SPI_DataSize_8b;
SPI_InitStructure.SPI_CPOL = SPI_CPOL_High;
SPI_InitStructure.SPI_CPHA = SPI_CPHA_2Edge;
SPI_InitStructure.SPI_NSS = SPI_NSS_Hard;
SPI_InitStructure.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_256;
SPI_InitStructure.SPI_FirstBit = SPI_FirstBit_MSB;
SPI_InitStructure.SPI_CRCPolynomial = 10;
SPI_Init(SPI1, &SPI_InitStructure);
SPI_Cmd(SPI1, ENABLE);
SPI_TIModeCmd(SPI1, ENABLE);
NVIC_InitStructure.NVIC_IRQChannel = SPI1_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 2;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
/* 使能中断函数 */
SPI_I2S_ITConfig(SPI1, SPI_I2S_IT_RXNE, ENABLE);
}
void SPI1_IRQHandler(void)
{
if(SPI_I2S_GetFlagStatus(SPI1, SPI_I2S_IT_RXNE) == SET)
{
rec = SPI_I2S_ReceiveData(SPI1);
SPI_I2S_ClearITPendingBit(SPI1, SPI_I2S_IT_RXNE);
}
}![](https://img2023.cnblogs.com/q/3248975/202312/3248975-20231229113407272-39448143.jpg)
中断进不去,rec = SPI_I2S_ReceiveData(SPI1);单独放在主程序里也没有收到东西,不知道是不是中断时钟没开还是什么,我看有些博主分享的代码,从机用硬件模式,片选是低电平……查了半天没什么结果,还请各位前辈不吝赐教,感谢各位前辈
从你提供的代码和描述来看,SPI从设备配置的代码和中断处理函数基本上是正确的。然而,SPI通信可能受到一些常见问题的影响,导致从设备无法接收到主设备的数据。以下是一些建议,希望对你解决问题有帮助:
SPI模式配置一致性:
确保主设备和从设备的SPI模式配置一致。特别关注SPI_CPOL(时钟极性)和SPI_CPHA(时钟相位)的设置,确保它们与主设备相匹配。
时钟和数据线接线:
检查SPI时钟线(SCK)、主输入从输出数据线(MISO)和主输出从输入数据线(MOSI)的物理连接。确保它们正确连接。
硬件NSS(片选信号)配置:
确保硬件NSS配置正确。在你的代码中,SPI_NSS_Hard 被设置为硬件控制,这意味着片选信号会通过硬件自动控制。确保片选信号的低电平和高电平时机正确。
SPI时钟配置:
通过 SPI_BaudRatePrescaler 设置SPI的时钟速率。确保主从设备的时钟速率兼容。如果时钟速率设置不当,可能导致通信失败。
硬件连接问题:
检查硬件连接,确保没有松动的电缆或连接错误。确认电源供应正常,确保信号引线长度适中,不会导致信号失真。
中断配置和使能:
检查中断配置和使能是否正确。在你的代码中,中断配置和使能看起来是正确的,但仍然检查一下是否有其他地方可能会关闭SPI的中断。
时钟使能:
确保SPI外设时钟已经被使能。在你的代码中,确保 RCC_APB2PeriphClockCmd(RCC_APB2Periph_SPI1, ENABLE); 已正确执行。
优先级和子优先级配置:
在中断配置中,确保优先级和子优先级的设置是合适的。确保它们不会被其他中断影响。
如果在检查以上建议后问题仍然存在,你可能需要深入分析SPI通信的时序波形,以确定是否存在电气问题或其他硬件问题。同时,考虑使用示波器监视SPI时钟和数据线上的波形,以便更好地了解信号的状态。