我们从2011年坚守至今,只想做存粹的技术论坛。  由于网站在外面,点击附件后要很长世间才弹出下载,请耐心等待,勿重复点击不要用Edge和IE浏览器下载,否则提示不安全下载不了

 找回密码
 立即注册
搜索
查看: 1147|回复: 9

[资料贡献] STM32 spi与FPGA的通信

[复制链接]

该用户从未签到

126

主题

239

回帖

0

积分

二级逆天

积分
0

终身成就奖金点子奖原创先锋奖

发表于 2020-5-20 17:48:01 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能,让你轻松玩转社区

您需要 登录 才可以下载或查看,没有账号?立即注册

×
最近在研究SPI总线,至于协议和硬件描述就不多说了
四线包括时钟、片选、接收、发送


初始化SP
  SPI_InitStructure.SPI_Direction = SPI_Direction_2Lines_FullDuplex;  //全双工
  SPI_InitStructure.SPI_Mode = SPI_Mode_Master;                       //主模式
  SPI_InitStructure.SPI_DataSize = SPI_DataSize_16b;                  //16bit宽度
  SPI_InitStructure.SPI_CPOL = SPI_CPOL_Low;
  SPI_InitStructure.SPI_CPHA = SPI_CPHA_2Edge;
  SPI_InitStructure.SPI_NSS = SPI_NSS_Soft;
  SPI_InitStructure.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_2;     //2--18MHz; 4--9MHz;  8--4.5MHz
  SPI_InitStructure.SPI_FirstBit = SPI_FirstBit_MSB;                    //高位在前
  SPI_InitStructure.SPI_CRCPolynomial = 7;
  SPI_Init(SPIx, &SPI_InitStructure);
  SPI_Cmd(SPIx, ENABLE);
  
SPI不能硬件控制CS,只能软件来控,就是通过将NSS设为外部GPIO来控制。
像我所做的项目是使用STM32与FPGA通信,而FPGA的SPI工作在这种一直状态
作为主设备的STM32,CS在传输数据的时候为低,传输完毕后必须拉高,这样FPGA可以判断出SPI的传输起止状态。


FPGA的数据传输格式是16bit地址+16bit数据
对于读16bit,实现如下


uint16_t spi_read(SPI_TypeDef* SPIx,uint32_t addr)
{  
  uint16_t value;
  uint16_t spi_nss;
  uint16_t add;
  uint32_t level;


  if(SPI1 == SPIx)
    spi_nss = SPI1_PIN_NSS;
  else if(SPI2 == SPIx)
    spi_nss = SPI2_PIN_NSS;


  while (SPI_I2S_GetFlagStatus(SPIx, SPI_I2S_FLAG_TXE) == RESET);
  GPIO_ResetBits(GPIOA, spi_nss);  
  SPI_I2S_SendData(SPIx, addr); //0xf014 >> 2


  while (SPI_I2S_GetFlagStatus(SPIx, SPI_I2S_FLAG_TXE) == RESET);
  SPI_I2S_SendData(SPIx, 0x0);


  while (SPI_I2S_GetFlagStatus(SPIx, SPI_I2S_FLAG_RXNE) == RESET);
  SPI_I2S_ReceiveData(SPIx);


  while (SPI_I2S_GetFlagStatus(SPIx, SPI_I2S_FLAG_TXE) == RESET);
  GPIO_SetBits(GPIOA, spi_nss);
     
  while (SPI_I2S_GetFlagStatus(SPIx, SPI_I2S_FLAG_RXNE) == RESET);
  value = SPI_I2S_ReceiveData(SPIx);


  return value;
}
  
写函数


void spi_write(SPI_TypeDef* SPIx,uint32_t addr, uint16_t value)
{


  uint16_t spi_nss;


  uint32_t level;


  if(SPI1 == SPIx)
    spi_nss = SPI1_PIN_NSS;
  else if(SPI2 == SPIx)
    spi_nss = SPI2_PIN_NSS;



  while (SPI_I2S_GetFlagStatus(SPIx, SPI_I2S_FLAG_TXE) == RESET);
  GPIO_ResetBits(GPIOA, spi_nss);  
  SPI_I2S_SendData(SPIx, addr);


  while (SPI_I2S_GetFlagStatus(SPIx, SPI_I2S_FLAG_TXE) == RESET);
  SPI_I2S_SendData(SPIx, value);


  while (SPI_I2S_GetFlagStatus(SPIx, SPI_I2S_FLAG_RXNE) == RESET);
  SPI_I2S_ReceiveData(SPIx);


  while (SPI_I2S_GetFlagStatus(SPIx, SPI_I2S_FLAG_TXE) == RESET);
  GPIO_SetBits(GPIOA, spi_nss);


  while (SPI_I2S_GetFlagStatus(SPIx, SPI_I2S_FLAG_RXNE) == RESET);
  SPI_I2S_ReceiveData(SPIx);


}  
拿write函数举例
只所以这么设计是因为
如果是函数一开始就将NSS脚拉低,然后再去send,如下
  GPIO_ResetBits(GPIOA, spi_nss);  
  while (SPI_I2S_GetFlagStatus(SPIx, SPI_I2S_FLAG_TXE) == RESET);
  SPI_I2S_SendData(SPIx, addr);
  
这样在CS拉低一段时间后(时间大概有16个时钟周期),才有CLK,这样延时就会降低SPI的传输效率  
之前那种方式会在CS拉底后很快就有clk时钟出来


之所以写两次再读两次而不是读一次写一次也是考虑到效率的问题


如果先写一次再读一次,看波形每个数据之间有比较大的空隙是没有clk的,就是说在传输完一个数据后再
传第二个会要等一段时间,这个对速度要求比较高的设备是不允许的


还有值得注意的是:
如果SPI是主模式,那么GPIO设置为
NSS是GPIO_Mode_Out_PP
CLK是GPIO_Mode_AF_PP
MOSI是GPIO_Mode_AF_PP
MISO是GPIO_Mode_IN_FLOATING


如果SPI是从模式,那么GPIO设置为
NSS是GPIO_Mode_Out_PP
CLK是GPIO_Mode_IN_FLOATING
MOSI是GPIO_Mode_IN_FLOATING
MISO是GPIO_Mode_AF_PP[sub][/sub][sup][/sup][strike][/strike]
回复

使用道具 举报

该用户从未签到

0

主题

311

回帖

0

积分

二级逆天

积分
0

终身成就奖

发表于 2020-5-20 17:53:03 | 显示全部楼层
回复

使用道具 举报

该用户从未签到

12

主题

7221

回帖

100

积分

游客

积分
100

终身成就奖特殊贡献奖原创先锋奖优秀斑竹奖

QQ
发表于 2020-5-20 19:46:08 | 显示全部楼层
回复

使用道具 举报

该用户从未签到

80

主题

373

回帖

0

积分

二级逆天

积分
0

终身成就奖特殊贡献奖原创先锋奖

发表于 2020-5-21 08:06:22 | 显示全部楼层
回复

使用道具 举报

该用户从未签到

32

主题

611

回帖

492

积分

二级逆天

积分
492

终身成就奖

发表于 2020-5-21 08:42:38 | 显示全部楼层
回复

使用道具 举报

该用户从未签到

32

主题

611

回帖

492

积分

二级逆天

积分
492

终身成就奖

发表于 2020-5-28 08:29:36 | 显示全部楼层
回复

使用道具 举报

该用户从未签到

3

主题

13

回帖

0

积分

一级逆天

积分
0

终身成就奖

发表于 2020-5-29 20:37:58 | 显示全部楼层
回复

使用道具 举报

  • TA的每日心情
    郁闷
    9 小时前
  • 签到天数: 105 天

    [LV.6]常住居民II

    2

    主题

    7206

    回帖

    1万

    积分

    三级逆天

    积分
    10617

    终身成就奖特殊贡献奖原创先锋奖

    QQ
    发表于 2020-6-3 08:56:51 | 显示全部楼层
    回复

    使用道具 举报

    该用户从未签到

    38

    主题

    395

    回帖

    1808

    积分

    PADS-241024高级班

    积分
    1808

    终身成就奖特殊贡献奖

    发表于 2020-6-3 16:01:50 | 显示全部楼层
    ~只要思想不滑坡,办法总比困难多~
    回复

    使用道具 举报

    该用户从未签到

    1

    主题

    295

    回帖

    0

    积分

    二级逆天

    积分
    0

    终身成就奖

    发表于 2020-6-5 08:19:07 | 显示全部楼层
    回复

    使用道具 举报

    您需要登录后才可以回帖 登录 | 立即注册

    本版积分规则

    公告:服务器刚移机,
    大家请不要下载东西。
    会下载失败


    Copyright ©2011-2024 NTpcb.com All Right Reserved.  Powered by Discuz! (NTpcb)

    本站信息均由会员发表,不代表NTpcb立场,如侵犯了您的权利请发帖投诉

    ( 闽ICP备2024076463号-1 ) 论坛技术支持QQ群171867948 ,论坛问题,充值问题请联系QQ1308068381

    平平安安
    TOP
    快速回复 返回顶部 返回列表