[tr]我采用stm F103 作为SPI的主机,stm F303作为从机,两者进行SPI
通信,主机向从机发送一组数据,从机同时也向主机发送一组数据,从机和主机都是采用的中断方式,但是每次的结果,从机里面接收的数据都是正确的,主机接收的却是错误的。举个例子来说,主机发送5个数据给从机,从机也发送5个数据给主机,从机能够完全接收主机的5个数据,但主机只能接收从机的前3个数据。如主机发送a[5]={0x01,0x02,0x03,0x04,0x05},从机发送数据b[10]={0x21,0x22,0x23,0x24,0x25},通信完成以后,从机的接收数据是完全对的,而主机的接收数据则为a_receive[5]={0x00,0x00,0x21,0x22,0x23};下面贴出我的程序,恳请大牛们过来指点下,不胜感激!
从机的主函数
- int main(void)
- {
- /* System clocks configuration ---------------------------------------------*/
- RCC_Configuration();
- /* NVIC configuration ------------------------------------------------------*/
- NVIC_Configuration();
- /* GPIO configuration ------------------------------------------------------*/
- GPIO_Configuration();
- SPI_Config();
- // /* Enable the Rx buffer not empty interrupt */
- SPI_I2S_ITConfig(SPI2, SPI_I2S_IT_RXNE, ENABLE);
- /* Enable SPI2 */
- SPI_Cmd(SPI2, ENABLE);
- while(1)
- {
- }
- }
复制代码
从机的中断函数
- void SPI2_IRQHandler(void)
- {
- if (SPI_I2S_GetITStatus(SPI2, SPI_I2S_IT_RXNE) != RESET)
- {
- /* Send SPI2 data */
- SPI2_Buffer_Rx[Rx_Idx++] = SPI_I2S_ReceiveData16(SPI2);
- /* Disable SPI1 TXE interrupt */
- if (Rx_Idx == BufferSize)
- {
- SPI_I2S_ITConfig(SPI2, SPI_I2S_IT_RXNE, DISABLE);
- }
- }
- while(SPI_I2S_GetFlagStatus(SPI2, SPI_I2S_FLAG_TXE) == RESET);
- /* Send SPI1 data */
- SPI_I2S_SendData16(SPI2, SPI2_Buffer_Tx[Tx_Idx++]);
- }
复制代码
主机的主函数
- int main(void)
- {
- /* System clocks configuration ---------------------------------------------*/
- RCC_Configuration();
- /* NVIC configuration ------------------------------------------------------*/
- NVIC_Configuration();
- /* GPIO configuration ------------------------------------------------------*/
- GPIO_Configuration();
- SPI_Config();
- /* Enable SPI2 */
- SPI_I2S_ITConfig(SPI2, SPI_I2S_IT_TXE, ENABLE);
- SPI_Cmd(SPI2, ENABLE);
- while(1)
- {
- }
- }
复制代码
主机的中断函数
- void SPI2_IRQHandler(void)
- {
- if(SPI_I2S_GetITStatus(SPI2, SPI_I2S_IT_TXE) != RESET);
- {
- /* Send SPI1 data */
- SPI_I2S_SendData(SPI2, SPI2_Buffer_Tx[Tx_Idx++]);
- /* Disable SPI1 TXE interrupt */
- if (Tx_Idx == BufferSize)
- {
- SPI_I2S_ITConfig(SPI2, SPI_I2S_IT_TXE, DISABLE);
- }
- }
- while(SPI_I2S_GetFlagStatus(SPI2, SPI_I2S_FLAG_RXNE) == RESET);
- /* Send SPI1 data */
- SPI2_Buffer_Rx[Rx_Idx++] = SPI_I2S_ReceiveData(SPI2);
- }
复制代码
[/tr]
如果你同步收发5个字节的话,显然发完标志会早于收完标志置位前2个字节就置位。
这种情况在SPI通信中是必然的,考虑主机SPI和EEPROM通信的过程(如常见的各厂家的25Cxxx系列),主机在发命令和地址之类的字节时,同样也收到了字节,但是因为EEPROM从机这时候还不知道主机要干什么(起码要收到读写命令和需要读写的地址,才能反应过来,发送正确的读出数据、或者继续接受要写入的数据),所以主机这时候接收到的字节应该丢弃。
所以你应该规划一个自己的协议,比如主机每次发起通信的前两个字节是命令,从机根据这两个字节命令来决定后续回答什么数据,主机在这两个字节发送过程中收的字节丢弃。当然这已经是属于半双工方式了。
一周热门 更多>