打印

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

[复制链接]
10546|18
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
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的一个特点
把你最后的那个疑問句的"难道"和后面的问号去掉,就是你要的答案

使用特权

评论回复
5
香水城| | 2012-2-21 18:32 | 只看该作者
哈哈,俺帮你把"难道"去掉,这个道不难, :lol

要让主机不停的给从机发送没用的数据,好供给从机SCK。

使用特权

评论回复
6
wangkangming| | 2012-7-23 13:36 | 只看该作者
嘛情况啊?为了给从机SCK信号,主机可以发送无用信号给从机啊??

使用特权

评论回复
7
捡漏王子| | 2012-7-23 17:03 | 只看该作者
学习了

使用特权

评论回复
8
jianweixu| | 2013-7-20 14:23 | 只看该作者
一年前的帖子,帮了大忙,我最近也在弄两个STM32的SPI通信,遇到和楼主一样的问题,现在一看豁然开朗啊,哈哈

使用特权

评论回复
9
zxm19820916| | 2013-7-30 11:49 | 只看该作者
呵呵,我也是不久前才知道的。

使用特权

评论回复
10
hxb20122012| | 2013-7-30 12:43 | 只看该作者
经典呀,这点到没注意过,还没用过SPI主从通信,学习了!

使用特权

评论回复
11
21世纪黄毛| | 2013-7-30 13:04 | 只看该作者
hxb20122012 发表于 2013-7-30 12:43
经典呀,这点到没注意过,还没用过SPI主从通信,学习了!

这就是全双工啊。发无用的数据丛机接受了不要就行了

使用特权

评论回复
12
hxb20122012| | 2013-7-30 18:13 | 只看该作者
恩,以前没用过SPI做为从机,学习了。

使用特权

评论回复
13
ranqingfa| | 2013-8-12 15:32 | 只看该作者
说到点子上了啊

使用特权

评论回复
14
chuangpu| | 2013-8-12 19:27 | 只看该作者
好帖子   比较不错   谢谢了   楼主  先顶一个   不错

使用特权

评论回复
15
fuluoce| | 2013-12-2 22:49 | 只看该作者
连线:
主          从
MOSI——MOSI
MISO——MISO
SCK ——SCK
怎么硬件是这样连接的呢? 不是
MOSI——MISO
MISO——MOSI
SCK ——SCK
吗?

使用特权

评论回复
16
lhchen922| | 2013-12-3 08:58 | 只看该作者
没这么用过。有时间试试,,谢谢先。

使用特权

评论回复
17
lycanthia| | 2014-4-23 13:54 | 只看该作者
如果两个MCU通信,互相都有数据发送请求的话,最好用串口,别用SPI。

使用特权

评论回复
18
feiji323| | 2015-7-7 09:34 | 只看该作者
原来是这样,那么从机是不能主动发数据给主机的咯

使用特权

评论回复
19
z755924843| | 2015-7-7 14:42 | 只看该作者
貌似SPI通信协议就是这么规定的吧。。。。

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

0

主题

6

帖子

0

粉丝