香主,请教STM32 的两个SPI通信的问题

[复制链接]
 楼主| achang85 发表于 2012-2-21 16:38 | 显示全部楼层 |阅读模式
本帖最后由 achang85 于 2012-2-21 16:43 编辑

我要用一个STM32主机,控制N个STM32从机,我现在还在调试一主一从,都有问题啊
我用的是两块板子,都用的SPI2,接收都是用的中断
连线:
主          从
MOSI——MOSI
MISO——MISO
SCK ——SCK
主机的NSS悬空,从机的NSS接地
主机配置
void SPI2_Configuration(void)
{
  SPI_InitTypeDef   SPI_InitStructure;
  SPI_InitStructure.SPI_Direction = SPI_Direction_2Lines_FullDuplex;
  SPI_InitStructure.SPI_Mode = SPI_Mode_Master;
  SPI_InitStructure.SPI_DataSize = SPI_DataSize_8b;
  SPI_InitStructure.SPI_CPOL = SPI_CPOL_Low;
  SPI_InitStructure.SPI_CPHA = SPI_CPHA_2Edge;
  SPI_InitStructure.SPI_NSS = SPI_NSS_Soft; //内部NSS信号由SSI位控制
  SPI_InitStructure.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_64;
  SPI_InitStructure.SPI_FirstBit = SPI_FirstBit_MSB;
// SPI_InitStructure.SPI_CRCPolynomial = 7;
  SPI_Init(SPI2, &SPI_InitStructure);
  SPI_I2S_ITConfig(SPI2, SPI_I2S_IT_RXNE, ENABLE);
  SPI_Cmd(SPI2, ENABLE);
}

void GPIO_Configuration(void)
{
   GPIO_InitTypeDef GPIO_InitStructure;
/* Configure SPI2 pins: NSS, SCK, MISO and MOSI ----------------------------*/
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_12 | GPIO_Pin_13 | GPIO_Pin_14 | GPIO_Pin_15;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
GPIO_Init(GPIOB, &GPIO_InitStructure);
}

void SPI2_IRQHandler(void)
{
   u8 SPI_RxData;
u8 i,sum;
if(SPI_I2S_GetITStatus(SPI2, SPI_I2S_IT_RXNE) != RESET);//SPI 接受缓存非空,收到数据
{
  SPI_RxData= SPI_I2S_ReceiveData(SPI2); //接受一个字节RXData是接收变量
  if(SPI_RxData == 0xaa)
  SPI_RxCount=0;
  SPI_RxBuffer[SPI_RxCount]=SPI_RxData;
  SPI_RxCount++;
  if((SPI_RxCount>2)&&(SPI_RxCount>=(SPI_RxBuffer[1]+2))&&(SPI_RxBuffer[0]!=0x00))
     {
       sum = 0;
    for(i=0;i<SPI_RxBuffer[1]+1;i++)
     sum+=SPI_RxBuffer;
       if(SPI_RxBuffer==sum)
    {
     SPI_RxFlag = 0xff;
      
     jieshou=0xff;
     USART_TX(SPI_RxBuffer,SPI_RxCount);
     }
    SPI_RxCount = 0;
     }

}
}

void SPI2_TX(u8 *Data,u8 Len)  //SPI发送函数
{
u8 x;
for(x=0;x<Len;x++)
{
  while (SPI_I2S_GetFlagStatus(SPI2, SPI_I2S_FLAG_TXE) == RESET);
  SPI_I2S_SendData(SPI2, Data[x]);
  //Delay_1ms(1);
  
}
}


从机配置:

void SPI1_Configuration(void)
{
SPI_InitTypeDef   SPI_InitStructure;
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_Low;
  SPI_InitStructure.SPI_CPHA = SPI_CPHA_2Edge;
  SPI_InitStructure.SPI_NSS = SPI_NSS_Hard;
  SPI_InitStructure.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_16;
  SPI_InitStructure.SPI_FirstBit = SPI_FirstBit_MSB;
// SPI_InitStructure.SPI_CRCPolynomial = 7;
  SPI_Init(SPI1, &SPI_InitStructure);
  SPI_I2S_ITConfig(SPI1, SPI_I2S_IT_RXNE, ENABLE);
  SPI_Cmd(SPI1, ENABLE);
}
其他的都一样

我程序是每次主机给从机发送一个命令,从机就给主机返回一包数据。
但是每次从机通过void SPI2_TX(u8 *Data,u8 Len) 给主机返回数据的时候,第一个字节可以发送成功,但是第二字节就会一直卡死在  while (SPI_I2S_GetFlagStatus(SPI2, SPI_I2S_FLAG_TXE) == RESET);这一句。当我单步,让主机一个字节一个字节的给从机发送,发现主机没给从机发送一个字节,从机就可以执行一步SPI2_TX(u8 *Data,u8 Len)中的SPI_I2S_SendData(SPI2, Data[x]);然后再跳到从机中断函数void SPI2_IRQHandler(void)。这是什么问题啊,怎么这么奇怪。也就是每次主机给从机发送一次数据,从机才可以给主机发送一次数据,否则就会一直等待  while (SPI_I2S_GetFlagStatus(SPI2, SPI_I2S_FLAG_TXE) == RESET)。请香主指点啊
void SPI2_TX(u8 *Data,u8 Len)  //SPI发送函数
{
u8 x;
for(x=0;x<Len;x++)
{
  while (SPI_I2S_GetFlagStatus(SPI2, SPI_I2S_FLAG_TXE) == RESET);
  SPI_I2S_SendData(SPI2, Data[x]);
  //Delay_1ms(1);
  
}
}
 楼主| achang85 发表于 2012-2-21 17:33 | 显示全部楼层
是不是因为从机没有时钟了啊。因为主机给从机发送完命令之后,就不管了。而从机的SCK需要主机来给。死在那个地方,是不是因为从机没有时钟了。而下一次主机给从机发送的时候,因为有时钟,所以从机就又能给主机发送一个字节?
 楼主| achang85 发表于 2012-2-21 17:42 | 显示全部楼层
我发现主机给从机发送一个字节,从机就能给主机发送一个字节。我觉得是因为从机没有时钟。因为主机给从机发送完命令之后就不管了,而从机的时钟需要主机来给。所以每次主机给从机发送一个字节的同时,从机就可以给主机发送一个字节。因为他们是全向双工的,可以同时收发。这样就有个问题啊。就是主机给从机发送完命令之后,从机没有时钟,怎么给主机发送数据呢?难道要让主机不停的给从机发送没用的数据,好供给从机SCK?
lxyppc 发表于 2012-2-21 17:47 | 显示全部楼层
3楼领悟到了SPI的一个特点
把你最后的那个疑問句的"难道"和后面的问号去掉,就是你要的答案
香水城 发表于 2012-2-21 18:32 | 显示全部楼层
哈哈,俺帮你把"难道"去掉,这个道不难, :lol

要让主机不停的给从机发送没用的数据,好供给从机SCK。
wangkangming 发表于 2012-7-23 13:36 | 显示全部楼层
嘛情况啊?为了给从机SCK信号,主机可以发送无用信号给从机啊??
捡漏王子 发表于 2012-7-23 17:03 | 显示全部楼层
学习了
jianweixu 发表于 2013-7-20 14:23 | 显示全部楼层
一年前的帖子,帮了大忙,我最近也在弄两个STM32的SPI通信,遇到和楼主一样的问题,现在一看豁然开朗啊,哈哈
zxm19820916 发表于 2013-7-30 11:49 | 显示全部楼层
呵呵,我也是不久前才知道的。
hxb20122012 发表于 2013-7-30 12:43 | 显示全部楼层
经典呀,这点到没注意过,还没用过SPI主从通信,学习了!
21世纪黄毛 发表于 2013-7-30 13:04 | 显示全部楼层
hxb20122012 发表于 2013-7-30 12:43
经典呀,这点到没注意过,还没用过SPI主从通信,学习了!

这就是全双工啊。发无用的数据丛机接受了不要就行了
hxb20122012 发表于 2013-7-30 18:13 | 显示全部楼层
恩,以前没用过SPI做为从机,学习了。
ranqingfa 发表于 2013-8-12 15:32 | 显示全部楼层
说到点子上了啊
chuangpu 发表于 2013-8-12 19:27 | 显示全部楼层
好帖子   比较不错   谢谢了   楼主  先顶一个   不错
fuluoce 发表于 2013-12-2 22:49 | 显示全部楼层
连线:
主          从
MOSI——MOSI
MISO——MISO
SCK ——SCK
怎么硬件是这样连接的呢? 不是
MOSI——MISO
MISO——MOSI
SCK ——SCK
吗?
lhchen922 发表于 2013-12-3 08:58 | 显示全部楼层
没这么用过。有时间试试,,谢谢先。
lycanthia 发表于 2014-4-23 13:54 | 显示全部楼层
如果两个MCU通信,互相都有数据发送请求的话,最好用串口,别用SPI。
feiji323 发表于 2015-7-7 09:34 | 显示全部楼层
原来是这样,那么从机是不能主动发数据给主机的咯
z755924843 发表于 2015-7-7 14:42 | 显示全部楼层
貌似SPI通信协议就是这么规定的吧。。。。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

0

主题

6

帖子

0

粉丝
快速回复 在线客服 返回列表 返回顶部