两个STM32F427之间的SPI通信问题

2019-07-20 01:00发布

用的标准库。
问题1、硬件设计是否有问题?连线如图1所示: 微信图片_20190628103642.jpg

问题2、NSS这根数据线的电平信号在数据传输的过程中需要设置嘛?主从都设计成SPI_NSS_Soft 软件模式。在各大论坛上看到的这个实验,主从配置没有什么区别,关键是主程序的读数据和写数据。以下是配置文件和主程序。这配置是否有问题?主程序能不能这样写?
主从都是SPI2.

主机配置:
  1. void SPI2_Init(void)
  2. {
  3. SPI_Cmd(SPI2, DISABLE);
  4. GPIO_InitTypeDef GPIO_InitStructure;
  5. SPI_InitTypeDef SPI2_InitStructure;

  6. RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOB, ENABLE);//ê1ÄüGPIODê±Öó
  7. RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOD, ENABLE);//ê1ÄüGPIOBê±Öó

  8. SPI_I2S_DeInit(SPI2);
  9. //GPIOs initialize
  10. GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9|GPIO_Pin_14| GPIO_Pin_15;//PB3~5¸′óÃ1|Äüêä3ö       
  11. GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;//¸′óÃ1|Äü
  12. GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;//íÆíìêä3ö
  13. GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;//100MHz
  14. GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;//éÏà-
  15. GPIO_Init(GPIOB, &GPIO_InitStructure);//3õê¼»ˉ

  16. GPIO_InitStructure.GPIO_Pin = GPIO_Pin_3;//Master CLK_Pin
  17. GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;//ÆÕí¨êä3öÄ£ê½
  18. GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;//íÆíìêä3ö
  19. GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
  20. GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;//éÏà-
  21. GPIO_Init(GPIOD, &GPIO_InitStructure);//3õê¼»ˉGPIO
  22. //GPIO AF
  23. GPIO_PinAFConfig(GPIOB,GPIO_PinSource9,GPIO_AF_SPI2);
  24. GPIO_PinAFConfig(GPIOB,GPIO_PinSource14,GPIO_AF_SPI2);
  25. GPIO_PinAFConfig(GPIOB,GPIO_PinSource15,GPIO_AF_SPI2);
  26. GPIO_PinAFConfig(GPIOD,GPIO_PinSource3,GPIO_AF_SPI2);

  27. GPIO_SetBits(GPIOB,GPIO_Pin_9|GPIO_Pin_14| GPIO_Pin_15);
  28. GPIO_SetBits(GPIOD,GPIO_Pin_3); //3õê¼»ˉà-¸ßμçƽ

  29. RCC_APB1PeriphClockCmd(RCC_APB1Periph_SPI2, ENABLE);//ê1ÄüSPI2ê±Öó

  30. SPI2_InitStructure.SPI_Direction = SPI_Direction_2Lines_FullDuplex; //éèÖÃSPIμ¥Ïò»òÕßË«ÏòμÄêy¾YÄ£ê½:SPIéèÖÃÎaË«ÏßË«Ïòè«Ë«1¤
  31. SPI2_InitStructure.SPI_Mode = SPI_Mode_Master;        //éèÖÃSPI1¤×÷Ä£ê½:éèÖÃÎaÖ÷SPI
  32. SPI2_InitStructure.SPI_DataSize = SPI_DataSize_8b;        //éèÖÃSPIμÄêy¾Y′óD¡:SPI·¢Ëí½óêÕ8λ֡½á11
  33. SPI2_InitStructure.SPI_CPOL = SPI_CPOL_Low;        //′®DDí¬2½ê±ÖóμÄ¿ÕÏD×′ì¬μíμçƽ
  34. SPI2_InitStructure.SPI_CPHA = SPI_CPHA_2Edge;        //′®DDí¬2½ê±ÖóμÄμú¶t¸öìø±äÑØ£¨éÏéy»òϽ죩êy¾Y±»2éÑù
  35. SPI2_InitStructure.SPI_NSS = SPI_NSS_Soft;        //NSSDÅoÅóéó2¼t£¨NSS1ü½Å£©»1êÇèí¼t£¨ê1óÃSSI룩1üàí:Äú2¿NSSDÅoÅóDSSIλ¿ØÖÆ
  36. SPI2_InitStructure.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_64;        //¶¨òå2¨ìØÂêÔ¤·ÖÆμμÄÖμ:2¨ìØÂêÔ¤·ÖÆμÖμÎa256
  37. SPI2_InitStructure.SPI_FirstBit = SPI_FirstBit_MSB;        //Ö¸¶¨êy¾Y′«êä′óMSBλ»1êÇLSBλ¿aê¼:êy¾Y′«êä′óMSBλ¿aê¼
  38. SPI2_InitStructure.SPI_CRCPolynomial = 7;        //CRCÖμ¼ÆËãμĶàÏîê½       

  39. SPI_Init(SPI2, &SPI2_InitStructure); //¸ù¾YSPI_InitStructÖDÖ¸¶¨μÄ2Îêy3õê¼»ˉíaéèSPIx¼Ä′æÆ÷
  40. SPI_Cmd(SPI2, ENABLE); //ê1ÄüSPIíaéè       
  41. //        SPI2_ReadWriteByte(0xff);//Æô¶ˉ′«ê䣬¿éòa¿é2»òa       
  42. }
复制代码

从机配置
  1. void SPI2_Init(void)
  2. {
  3.         SPI_Cmd(SPI2, DISABLE);
  4.         GPIO_InitTypeDef  GPIO_InitStructure;
  5.   SPI_InitTypeDef  SPI2_InitStructure;
  6.        
  7.   RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOB, ENABLE);//ê1ÄüGPIODê±Öó

  8.   //GPIOs initialize
  9.   GPIO_InitStructure.GPIO_Pin = GPIO_Pin_14| GPIO_Pin_15|GPIO_Pin_13;
  10.   GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;//
  11.   GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;//íÆíìêä3ö
  12.   GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;//100MHz
  13.   GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;//éÏà-
  14.   GPIO_Init(GPIOB, &GPIO_InitStructure);//3õê¼»ˉ
  15.        
  16.         GPIO_InitStructure.GPIO_Pin = GPIO_Pin_12;// NSS
  17.   GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN;//êäèë
  18. //  GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;//íÆíìêä3ö
  19.   GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
  20.   GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;//éÏà-
  21.   GPIO_Init(GPIOB, &GPIO_InitStructure);//3õê¼»ˉGPIO
  22.         //GPIO AF
  23.         GPIO_PinAFConfig(GPIOB,GPIO_PinSource12|GPIO_PinSource14|GPIO_PinSource15|GPIO_PinSource13,GPIO_AF_SPI2);


  24.         //ÕaàïÖ»Õë¶ÔSPI¿ú3õê¼»ˉ
  25.   RCC_APB1PeriphClockCmd(RCC_APB1Periph_SPI2, ENABLE);//ê1ÄüSPI2ê±Öó

  26.         SPI2_InitStructure.SPI_Direction = SPI_Direction_2Lines_FullDuplex;  //éèÖÃSPIμ¥Ïò»òÕßË«ÏòμÄêy¾YÄ£ê½:SPIéèÖÃÎaË«ÏßË«Ïòè«Ë«1¤
  27.         SPI2_InitStructure.SPI_Mode = SPI_Mode_Slave;                //éèÖÃSPI1¤×÷Ä£ê½:éèÖÃÎaÖ÷SPI
  28.         SPI2_InitStructure.SPI_DataSize = SPI_DataSize_8b;                //éèÖÃSPIμÄêy¾Y′óD¡:SPI·¢Ëí½óêÕ8λ֡½á11
  29.         SPI2_InitStructure.SPI_CPOL = SPI_CPOL_Low;                //′®DDí¬2½ê±ÖóμÄ¿ÕÏD×′ì¬Îa¸ßμçƽ
  30.         SPI2_InitStructure.SPI_CPHA = SPI_CPHA_2Edge;        //′®DDí¬2½ê±ÖóμÄμú¶t¸öìø±äÑØ£¨éÏéy»òϽ죩êy¾Y±»2éÑù
  31.         SPI2_InitStructure.SPI_NSS = SPI_NSS_Soft;                //NSSDÅoÅóéó2¼t£¨NSS1ü½Å£©»1êÇèí¼t£¨ê1óÃSSI룩1üàí:Äú2¿NSSDÅoÅóDSSIλ¿ØÖÆ
  32.         SPI2_InitStructure.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_64;                //¶¨òå2¨ìØÂêÔ¤·ÖÆμμÄÖμ:2¨ìØÂêÔ¤·ÖÆμÖμÎa256
  33.         SPI2_InitStructure.SPI_FirstBit = SPI_FirstBit_MSB;        //Ö¸¶¨êy¾Y′«êä′óMSBλ»1êÇLSBλ¿aê¼:êy¾Y′«êä′óMSBλ¿aê¼
  34.         SPI2_InitStructure.SPI_CRCPolynomial = 7;        //CRCÖμ¼ÆËãμĶàÏîê½
  35.        

  36.         SPI_Init(SPI2, &SPI2_InitStructure);  //¸ù¾YSPI_InitStructÖDÖ¸¶¨μÄ2Îêy3õê¼»ˉíaéèSPIx¼Ä′æÆ÷
  37.         SPI_Cmd(SPI2, ENABLE); //ê1ÄüSPIíaéè       
  38. }
复制代码
主机的主程序
  1. int main(void)
  2. {       
  3.         SPI2_Init();       
  4.         while(1)
  5.         {
  6.                 for( i=0;i<4;i++)
  7.                 {               
  8.                         while(SPI_I2S_GetFlagStatus(SPI2,SPI_I2S_FLAG_TXE)==RESET)
  9.                         {
  10.                                 retry++;
  11.                                 if (retry>200)
  12.                                 {
  13.                                         return 0;
  14.                                 }
  15.                         }
  16.                         SPI_I2S_SendData(SPI2,txbuffer[i]);
  17.                         while(SPI_I2S_GetFlagStatus(SPI2,SPI_I2S_FLAG_RXNE)==RESET)
  18.                         {
  19.                                 retry++;
  20.                                 if (retry>200)
  21.                                 {
  22.                                         return 0;
  23.                                 }
  24.                         }
  25.                          SPI_I2S_ReceiveData(SPI2);       
  26.                 }               
  27.         }
  28. }
复制代码从机的主程序
  1. int main(void)
  2. {       
  3.         Uart3_init(115200);       
  4.         SPI2_Init();
  5.         printf(" %x ",rxbuffer[0]);               
  6.         while(1)
  7.         {               
  8.                 for(int i=0;i<4;i++)
  9.                 {
  10.                         while(SPI_I2S_GetFlagStatus(SPI2,SPI_I2S_FLAG_RXNE)==RESET){}
  11.                         rxbuffer[i]=SPI_I2S_ReceiveData(SPI2);
  12.                         while(SPI_I2S_GetFlagStatus(SPI2,SPI_I2S_FLAG_TXE)==RESET){}
  13.                         SPI_SendData(SPI2,0x11);
  14.                 }
  15.                 for(int i=0;i<4;i++)
  16.                 {
  17.                         printf(" %x ",rxbuffer[i]);                       
  18.                 }
  19.                  
  20.         }
  21. }
复制代码问题3、在debug主机的过程中,只要执行SPI_I2S_SendData(SPI2,txbuffer);这么一句话,MOSI和SCK数据线,用示波器测量,可以得到正确的数据波形图和时钟信号波形图,但是测试MISO数据线上的话,永远都是高电平,得出从器件的问题。但是不知道哪里问题。
问题4、看完SPI的原理后,最主要是:主器件发起数据的传输,然后从器件同时往miso信号线上发送数据,但是不太明白在程序里面如何体现出这个循环移位过程。我这个是属于查询的方式,中断也尝试过,中断模仿的是原子论坛里面的一个精帖。但是仍然不通。
论坛的各位带哥帮忙看看。









友情提示: 此问题已得到解决,问题已经关闭,关闭后问题禁止继续编辑,回答。
该问题目前已经被作者或者管理员关闭, 无法添加新回复
12条回答
edmund1234
1楼-- · 2019-07-20 05:50
当spi配置为SPI_Direction_2Lines_FullDuplex时
主机要读数据, 需要同时发送数据。没有只读不发的
LeBron
2楼-- · 2019-07-20 10:07
edmund1234 发表于 2019-6-28 13:13
当spi配置为SPI_Direction_2Lines_FullDuplex时
主机要读数据, 需要同时发送数据。没有只读不发的

你好,那主机那一块的主程序应该怎么写呢?还有我这个硬件设计没问题吧  NSS这根数据线不需要操作吧?比如set或者reset?
正点原子
3楼-- · 2019-07-20 15:55
 精彩回答 2  元偷偷看……
edmund1234
4楼-- · 2019-07-20 20:29
本帖最后由 edmund1234 于 2019-6-29 08:50 编辑
LeBron 发表于 2019-6-28 17:11
你好,那主机那一块的主程序应该怎么写呢?还有我这个硬件设计没问题吧  NSS这根数据线不需要操作吧?比 ...

随便写个0或者0xFF(从需要忽略它),SPI1->DR=0xFF, 然后再读 data=SPI1->DR。
一主一从可以不接NSS, 配置时把SPI1->CR1的SSM设为1就可以。


edmund1234
5楼-- · 2019-07-21 01:17
正点原子 发表于 2019-6-29 02:42
MISO接MOSI。
接错了你

MISO接MISO是对的
正点原子
6楼-- · 2019-07-21 07:06
 精彩回答 2  元偷偷看……

一周热门 更多>