[N32L4xx] SPI从机在接收中断返回接收到的数据

[复制链接]
1015|2
 楼主| sy12138 发表于 2022-9-8 17:57 | 显示全部楼层 |阅读模式
最近在学习SPI做了一个小实验,从机接收主机的数据并将其返回给主机,算是个SPI的回环实验吧
但是这个实验并没有实际应用的意义,在实际应用中SPI从机发送数据需要配合DMA,片选NSS使用。因为今天只是简单测试一下,就不要DMA了
SPI主机想必大家都有了解,但是SPI从机可能接触的比较少,比如像我之前就没接触过这方面的代码配置。之前一直奇怪SPI从机是怎么产生时钟,后来查阅资料才发现,时钟信号只有SPI主机才能产生,从机也只能在主机产生时钟的时候收发数据。
话不多说,我们来看主机代码
  1. uint8_t cmd1 = 0xF1;
  2. GPIO_InitType GPIO_InitStructure;

  3. GPIO_InitStruct(&GPIO_InitStructure);
  4.    
  5. GPIO_InitStructure.Pin        = GPIO_PIN_6|GPIO_PIN_5|GPIO_PIN_7;
  6. GPIO_InitStructure.GPIO_Mode  = GPIO_Mode_AF_PP;
  7. GPIO_InitStructure.GPIO_Alternate = GPIO_AF0_SPI1;
  8. GPIO_InitPeripheral(SPI_MASTER_GPIO, &GPIO_InitStructure);

  9. SPI_InitStructure.DataDirection = SPI_DIR_DOUBLELINE_FULLDUPLEX;
  10. SPI_InitStructure.SpiMode       = SPI_MODE_MASTER;
  11. SPI_InitStructure.DataLen       = SPI_DATA_SIZE_8BITS;
  12. SPI_InitStructure.CLKPOL        = SPI_CLKPOL_LOW;
  13. SPI_InitStructure.CLKPHA        = SPI_CLKPHA_SECOND_EDGE;
  14. SPI_InitStructure.NSS           = SPI_NSS_SOFT;
  15. SPI_InitStructure.BaudRatePres  = SPI_BR_PRESCALER_16;
  16. SPI_InitStructure.FirstBit      = SPI_FB_MSB;
  17. SPI_InitStructure.CRCPoly       = 7;
  18. SPI_Init(SPI1, &SPI_InitStructure);

  19. SPI_Enable(SPI1, ENABLE);
  20.        
  21. SPI_I2S_TransmitData(SPI1,cmd1);

  22. Delay(200);
  23.        
  24. for(i=1; i<100 ;i++)
  25. {
  26. while(SPI_I2S_GetStatus(SPI1, SPI_I2S_TE_FLAG) == RESET){}                       
  27. SPI_I2S_TransmitData(SPI1,i);                       
  28. }
  29.        
这里我们从机利用接收中断来回主机数据
  1. SPI_InitStructure.DataDirection = SPI_DIR_DOUBLELINE_FULLDUPLEX;
  2. SPI_InitStructure.SpiMode       = SPI_MODE_SLAVE;
  3. SPI_InitStructure.DataLen       = SPI_DATA_SIZE_8BITS;
  4. SPI_InitStructure.CLKPOL        = SPI_CLKPOL_LOW;
  5. SPI_InitStructure.CLKPHA        = SPI_CLKPHA_SECOND_EDGE;
  6. SPI_InitStructure.NSS           = SPI_NSS_SOFT;
  7. SPI_InitStructure.BaudRatePres  = SPI_BR_PRESCALER_8;
  8. SPI_InitStructure.FirstBit      = SPI_FB_MSB;
  9. SPI_InitStructure.CRCPoly       = 7;
  10. SPI_Init(SPI1, &SPI_InitStructure);

  11. SPI_I2S_EnableInt(SPI1, SPI_I2S_INT_RNE, ENABLE);       

  12. SPI_Enable(SPI1, ENABLE);
这里需要注意SPI主机从机配置要保持一致
  1. void GPIO_Configuration(void)
  2. {
  3. GPIO_InitType GPIO_InitStructure;

  4. GPIO_InitStruct(&GPIO_InitStructure);
  5.    
  6. GPIO_InitStructure.Pin        = GPIO_PIN_6 ;
  7. GPIO_InitStructure.GPIO_Mode  = GPIO_Mode_AF_PP;
  8. GPIO_InitStructure.GPIO_Alternate = GPIO_AF0_SPI1;
  9. GPIO_InitPeripheral(SPI_MASTER_GPIO, &GPIO_InitStructure);
  10.        
  11. GPIO_InitStructure.Pin        = GPIO_PIN_5|GPIO_PIN_7;
  12. GPIO_InitStructure.GPIO_Mode  = GPIO_Mode_Input;
  13. GPIO_InitStructure.GPIO_Alternate = GPIO_AF0_SPI1;
  14. GPIO_InitPeripheral(SPI_MASTER_GPIO, &GPIO_InitStructure);
  15. }
GPIO配置时SCK脚配置为输入模式
  1. void SPI1_IRQHandler(void)
  2. {
  3. if (SPI_I2S_GetIntStatus(SPI1, SPI_I2S_INT_RNE) != RESET)
  4. {
  5.                
  6. test = SPI_I2S_ReceiveData(SPI1);
  7. SPI1->DAT = 0;
  8. SPI_I2S_TransmitData(SPI1,test);
  9. SPI_I2S_ClrITPendingBit(SPI1,SPI_I2S_INT_RNE);                                             
  10. }
  11. }
OK,软件配置完成,接下来我们用逻辑分析仪抓一下数据看从机收发的数据是否一致
可以看到从机收发数据一致,测试pass
下次可以SPI从机通过DMA方式发送数据

bbea2bc35d450c9dd3423ba2db7df38.png
天天向善 发表于 2022-9-9 13:04 | 显示全部楼层
所以主机程序和从机程序都要你自己写咯
zcllom 发表于 2023-6-6 10:37 | 显示全部楼层
不知道为什么,我的SPI从机设置后,既不能接收,又不能发送
您需要登录后才可以回帖 登录 | 注册

本版积分规则

92

主题

404

帖子

19

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