你的浏览器版本过低,可能导致网站不能正常访问!
为了你能正常使用网站功能,请使用这些浏览器。

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

[复制链接]
any012 提问时间:2016-5-23 17:21 /
悬赏3ST金币未解决
主设备发送的是:0x3a05,0x010a,0x0100,0x0000,0x9d76
现在用stm32做为spi的从设备,用到的资源有,定时器,串口1,spi2,dma;
定时器用来做1s基准,每1秒开启一次spi2中断使能,中断函数里判断帧首,帧首正确后接收5个16位数据,然后置个标志位。主函数里等待这个标志位被置位,然后关断中断,并将接收到的数据通过串口发送出来。
DMA是用来不停的将另组5个16位数据通过SPI2发送出去(SPI2接收主设备数据时同时将自身的数据发送出去)。

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

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

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

SPI2中断部分:
  1. void SPI2_IRQHandler(void)
  2. {
  3.         static u8 spi2Num;
  4.         u16 spi2Temp;
  5.         
  6.         spi2Temp = SPI_I2S_ReceiveData(SPI2);        
  7.         if(spi2Num == 0)
  8.         {
  9.                 if(spi2Temp == 0x3a05)
  10.                 {
  11.                         spi2RecivBuff[0] = spi2Temp;
  12.                         spi2Num = 1;
  13.                 }
  14.         }
  15.         else
  16.         {
  17.                 spi2RecivBuff[spi2Num] = spi2Temp;
  18.                 if(spi2Num++ > 4)
  19.                 {
  20.                         spi2Num = 0;
  21.                         spi2RecivOk = 1;
  22.                 }
  23.         }
  24. }
复制代码

主函数:
  1. int main(void)
  2. {
  3.         Init();
  4.         TIM_Cmd(TIM3, ENABLE);                                                        //¿ªÆô¶¨Ê±Æ÷
  5.         
  6.         while(1)
  7.         {
  8.                 if(flag_1ms)
  9.                 {
  10.                         flag_1ms = 0;
  11.                         printf("\r\n1s¶¨Ê±µ½¡£");
  12.                         SPI_I2S_ITConfig(SPI2, SPI_I2S_IT_RXNE, ENABLE);
  13.                         while(spi2RecivOk == 0);
  14.                         spi2RecivOk = 0;
  15.                         for(i = 0; i < 5; i++)
  16.                                 printf("\r\nspirecive[%d]: %x", i, spi2RecivBuff[i]);
  17.                         SPI_I2S_ITConfig(SPI2, SPI_I2S_IT_RXNE, DISABLE);
  18.                 }
  19.         }
  20. }
复制代码



收藏 评论2 发布时间:2016-5-23 17:21

举报

2个回答
any012 回答时间:2016-5-23 17:41:51
虽然感觉也有可能确实是连续收到了0x3a05,不过用示波器观察了一阵子,感觉这5个数据是间隔不远传输过来的。示波器观察基本上没观察到连续的0x3a05。
any012 回答时间:2016-6-15 09:25:37
改成下面这样就没事了。主要是进入SPI中断后,SPI发送数据尽量靠前一点。也不知道为什么会这样。
在接收完帧首以后的中断处理里,就是else语句,需要将SPI发送语句放在紧靠else语句的位置。
这样的话,原来想只用spi2RecvNum这个变量控制接收和发送的数据位,现在不那么好实现了,于是又加了个变量spi2SendNum。

[mw_shl_code=c,true]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[1]);
                                spi2RecvBuff[0] = spi2Temp;
                                spi2RecvNum = 1;
                                spi2SendNum = 2;                               
                        }
                }
                else
                {
                        SPI_I2S_SendData(SPI2, spi2SendBuff[spi2SendNum]);
                        spi2RecvBuff[spi2RecvNum] = spi2Temp;
                        spi2RecvNum++;
                        if(spi2RecvNum > 4)
                                spi2RecvOk = 1;
                        spi2SendNum += 1;
                        spi2SendNum %= 5;
                }
        }       
}[/mw_shl_code]

所属标签

相似问题

关于意法半导体
我们是谁
投资者关系
意法半导体可持续发展举措
创新和工艺
招聘信息
联系我们
联系ST分支机构
寻找销售人员和分销渠道
社区
媒体中心
活动与培训
隐私策略
隐私策略
Cookies管理
行使您的权利
关注我们
st-img 微信公众号
st-img 手机版