any012 发表于 2016-5-23 17:21:06

STM32做从设备,循环读取主设备发送的数据,两次中有一次错

主设备发送的是:0x3a05,0x010a,0x0100,0x0000,0x9d76
现在用stm32做为spi的从设备,用到的资源有,定时器,串口1,spi2,dma;
定时器用来做1s基准,每1秒开启一次spi2中断使能,中断函数里判断帧首,帧首正确后接收5个16位数据,然后置个标志位。主函数里等待这个标志位被置位,然后关断中断,并将接收到的数据通过串口发送出来。
DMA是用来不停的将另组5个16位数据通过SPI2发送出去(SPI2接收主设备数据时同时将自身的数据发送出去)。

现在的现象是,
1s定时到。
spirecive: 3a05
spirecive: 10a
spirecive: 100
spirecive: 0
spirecive: 9d76
1s定时到。
spirecive: 3a05
spirecive: 3a05
spirecive: 100
spirecive: 0
spirecive: 9d76
1s定时到。
spirecive: 3a05
spirecive: 10a
spirecive: 100
spirecive: 0
spirecive: 9d76
1s定时到。
spirecive: 3a05
spirecive: 10a
spirecive: 100
spirecive: 0
spirecive: 9d76
1s定时到。

几次中会有一次,连续读取到两个3a05。
不知道是什么原因造成的,忘朋友们指教。

------------------------------------------------------------

SPI2中断部分:
void SPI2_IRQHandler(void)
{
      static u8 spi2Num;
      u16 spi2Temp;
      
      spi2Temp = SPI_I2S_ReceiveData(SPI2);      
      if(spi2Num == 0)
      {
                if(spi2Temp == 0x3a05)
                {
                        spi2RecivBuff = spi2Temp;
                        spi2Num = 1;
                }
      }
      else
      {
                spi2RecivBuff = spi2Temp;
                if(spi2Num++ > 4)
                {
                        spi2Num = 0;
                        spi2RecivOk = 1;
                }
      }
}
主函数:
int main(void)
{
      Init();
      TIM_Cmd(TIM3, ENABLE);                                                      //¿ªÆô¶¨Ê±Æ÷
      
      while(1)
      {
                if(flag_1ms)
                {
                        flag_1ms = 0;
                        printf("\r\n1s¶¨Ê±µ½¡£");
                        SPI_I2S_ITConfig(SPI2, SPI_I2S_IT_RXNE, ENABLE);
                        while(spi2RecivOk == 0);
                        spi2RecivOk = 0;
                        for(i = 0; i < 5; i++)
                              printf("\r\nspirecive[%d]: %x", i, spi2RecivBuff);
                        SPI_I2S_ITConfig(SPI2, SPI_I2S_IT_RXNE, DISABLE);
                }
      }
}


any012 发表于 2016-5-23 17:41:51

虽然感觉也有可能确实是连续收到了0x3a05,不过用示波器观察了一阵子,感觉这5个数据是间隔不远传输过来的。示波器观察基本上没观察到连续的0x3a05。

any012 发表于 2016-6-15 09:25:37

改成下面这样就没事了。主要是进入SPI中断后,SPI发送数据尽量靠前一点。也不知道为什么会这样。
在接收完帧首以后的中断处理里,就是else语句,需要将SPI发送语句放在紧靠else语句的位置。
这样的话,原来想只用spi2RecvNum这个变量控制接收和发送的数据位,现在不那么好实现了,于是又加了个变量spi2SendNum。

void SPI2_IRQHandler(void)
{
        static u8 n;
        static u16 spi2Temp;
        spi2Temp = SPI_I2S_ReceiveData(SPI2);
       
        if(spi2RecvOk == 0)
        {
                if(spi2RecvNum == 0)
                {
                        if((spi2Temp & 0xff00)== 0x3a00)
                        {
                                SPI_I2S_SendData(SPI2, spi2SendBuff);
                                spi2RecvBuff = spi2Temp;
                                spi2RecvNum = 1;
                                spi2SendNum = 2;                               
                        }
                }
                else
                {
                        SPI_I2S_SendData(SPI2, spi2SendBuff);
                        spi2RecvBuff = spi2Temp;
                        spi2RecvNum++;
                        if(spi2RecvNum > 4)
                                spi2RecvOk = 1;
                        spi2SendNum += 1;
                        spi2SendNum %= 5;
                }
        }       
}
页: [1]
查看完整版本: STM32做从设备,循环读取主设备发送的数据,两次中有一次错