最近自己写了一个SPI双机通信的工程,遇到了点问题。
需求:两块stm32f4的板子通过SPI进行全双工通信,主机可以向从机写入数据或者读取数据。设计方案:
主机写入从机:发送包含实际数据的完整帧,发送完后等待从机的确认字节,完成任务;
主机读取从机:发送包含所要数据的信息的指令帧,从机接收到后准备好包含实际数据的完整帧,在主机的驱动下返回;
主机采用软件片选,从机采用硬件片选。(这一块花了蛮久时间搞懂)
整个机制建立在中断基础上:主机初始化时仅使能接收中断,从机初始化时使能发送接收中断,所以从机初始化后会立即向发送缓冲区填入一个字节。当主机想要发送一帧时,在准备好实际的数据后,使能发送中断就可以将整个帧数据逐字节的发送出去。
问题描述:
初始化时分频系数最低到16可以正常工作,但4和8均会出现丢失数据导致无法正常通信。
主从机代码采用预编译的方式写在同一个工程中,下面贴代码
友情提示: 此问题已得到解决,问题已经关闭,关闭后问题禁止继续编辑,回答。
void SPI1_IRQHandler(void)
{
//发送中断
if(SPI_I2S_GetFlagStatus(User_SPI, SPI_I2S_FLAG_TXE) != RESET)
{
switch(SPI_Structure.state)
{
case READY:
SPI_I2S_SendData(User_SPI, SPI_Structure.response);
break;
case COMMANDING:
#ifdef Master
SPI_SendCmdM(); //主机逐字节发送指令帧
#endif
#ifdef Slave
SPI_SendCmdReplyS(); //从机在接收主机指令时发送的无效字节
#endif
break;
case COMMANDED:
#ifdef Master
SPI_RecvFrameReplyM(); //主机在读取从机数据时发送的无效字节
#endif
#ifdef Slave
SPI_SendFrameS(); //从机逐字节发送数据帧
#endif
break;
}
}
//接收中断
if(SPI_I2S_GetFlagStatus(User_SPI, SPI_I2S_FLAG_RXNE) != RESET)
{
u8 data = SPI_I2S_ReceiveData(User_SPI);
#ifdef Master
SPI_RecvDataM(data); //主机接收从机的字节并解包
#endif
#ifdef Slave
SPI_RecvDataS(data); //从机接收主机的字节并解包
#endif
}
}
//供外部调用的主机发送函数
void SPI_MasterSend(u8 ms,SPI_COMState func,u16 base,u8 len)
{
SPI_ExportData(ms,func,base,len); //准备实际帧
SPI_SendStartUp(); //开始发送
}
//开始发送函数
void SPI_SendStartUp()
{
if(!SPI_Structure.SPI_SendCmdHolder.valid) return;
SPI_Structure.state=COMMANDING;
SPI_Structure.com=SPI_Structure.SPI_SendCmdHolder.func;
SPI_Structure.sendIndex=0;
//以上为更新SPI结构体状态
SPI_I2S_ITConfig(User_SPI,SPI_I2S_IT_TXE, ENABLE); //使能发送中断后立即开始发送数据
}
一周热门 更多>