找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 1174|回复: 8
打印 上一主题 下一主题
收起左侧

两个芯片的SPI通信问题?

[复制链接]
跳转到指定楼层
楼主
我使用的是STM32F103C8T6和PCAP01来做SPI1通讯。在使用的过程中发现,SPI1有的时候使用没有问题,通讯正常,有的时候通信失败,SPI1用不了。如果是代码或者硬件有问题,那应该不能通讯,为什么有的时候好用,有的时候不好用。想问问大家,有没有遇到这种情况的?
这是我的代码:
unsigned char Send_24Bit_Opcode(unsigned char command, unsigned short address, unsigned char data)
{

  unsigned char    Result_read = 0;

  // x >> y, mean x is shifted by y bit-positions to the right
  unsigned char Byte_0  = data;
  unsigned char Byte_1  = address;
  unsigned char Byte_2  = address>>8 | command;
  // SPIx BUS_TYPE -------------------------------------------------------------

  // Deactivating Reset SPIx
  GPIO_WriteBit(GPIOA, GPIO_Pin_4, Bit_RESET);
  // GPIO_WriteBit(GPIOB, GPIO_Pin_12, Bit_RESET);

   while (SPI_I2S_GetFlagStatus(SPI1, SPI_I2S_FLAG_TXE)==0) {}
   SPI_I2S_SendData(SPI1, Byte_2);     // send byte 2

   while (SPI_I2S_GetFlagStatus(SPI1, SPI_I2S_FLAG_TXE)==0) {}
   SPI_I2S_SendData(SPI1, Byte_1);     // send byte 1
   if (command==0x90) // write command
   {
     while (SPI_I2S_GetFlagStatus(SPI1, SPI_I2S_FLAG_TXE)==0) {}
     SPI_I2S_SendData(SPI1, Byte_0);     // send byte 0

    while (SPI_I2S_GetFlagStatus(SPI1, SPI_I2S_FLAG_TXE)==0) {}
    Simple_delay_43ns((void*)10); // important delay (16) at SPI freq.=750kHz
   }

   if (command==0x10) // read command
   {
     while (SPI_I2S_GetFlagStatus(SPI1, SPI_I2S_FLAG_TXE)==RESET) {};
     Simple_delay_43ns((void*)10); // important delay (16) at SPI freq.=750kHz

     //Compulsory reads to DR and SR to clear OVR,
     //so that next incoming data is saved
     SPI_I2S_ReceiveData(SPI1);                     // To clear OVR
     SPI_I2S_GetFlagStatus(SPI1, SPI_I2S_FLAG_TXE); // To clear OVR

     //Reading byte1
     SPI_I2S_SendData(SPI1, 0xFF);  // DUMMY WRITE
     // Wait until RX buffer is not empty, then read the received data
     while (SPI_I2S_GetFlagStatus(SPI1, SPI_I2S_FLAG_RXNE)==0) {}

     Result_read = SPI_I2S_ReceiveData(SPI1); //  Read
    }

     // Reset to device SPIx
     GPIO_WriteBit(GPIOA, GPIO_Pin_4, Bit_SET);
     //GPIO_WriteBit(GPIOB, GPIO_Pin_12, Bit_SET);
  return Result_read;
}


Send_24Bit_Opcode(0x90,1,0x55);//0x90 写
err =  Send_24Bit_Opcode(0x10,1,0xff);//err = 0x55 0x10读

读不回0x55 每次都是0xFF。是代码问题吗?

2(1)(1).png (157.04 KB, 下载次数: 54)

2(1)(1).png
分享到:  QQ好友和群QQ好友和群 QQ空间QQ空间 腾讯微博腾讯微博 腾讯朋友腾讯朋友
收藏收藏 分享淘帖 顶 踩
回复

使用道具 举报

沙发
ID:624769 发表于 2022-10-11 18:41 来自手机 | 只看该作者
主机需要考虑从机的响应和处理速度。从机需要考虑在做任何处理时,都能停下手头的工作,响应主机的要求。
回复

使用道具 举报

板凳
ID:391219 发表于 2022-10-11 19:36 | 只看该作者
188610329 发表于 2022-10-11 18:41
主机需要考虑从机的响应和处理速度。从机需要考虑在做任何处理时,都能停下手头的工作,响应主机的要求。

那您的意思是速度太快了吗?可是有的时候,我再重新烧录程序的时候,会全部复位在进行烧录。有的时候能通信,有的时候就不行。要是因为速度的话,每次重新开始的时候,不应该时好时坏。
回复

使用道具 举报

地板
ID:624769 发表于 2022-10-11 22:21 | 只看该作者
不是指 SPI 的传输速度 快慢,而是指  SPI  传指令 给 从机, 从机 接受到 指令, 处理,准备数据 回传给主机,这个过程需要时间的, 但是,时钟是主机发出的,主机是不知道 从机 准备没准备好的。 所以,这个指令的复杂程度,从机需要处理的时间, 主机这边要有  充分的等待, 才能 发出时钟 取数据。
同样,主机发出 CE/SS  信号,然后发数据 给从机, 这个时候,从机在干什么?  你能不能确保,这个时候从机就 等在 SPI 线程上 等待指令接收完毕,立刻处理? 如果,这个时候,从机在处理别的事情,你又没有机制,让从机停止工作,来处理SPI 发来的指令? 这是  双机通讯中必须考虑的问题。

因为,不知道你  双机 SPI 通讯 具体进行什么 数据交互,就只能推测这些了。
回复

使用道具 举报

5#
ID:123289 发表于 2022-10-12 08:27 | 只看该作者
你要保证,当你发送的时候,对方在收!!
建议用中断方式解决这个问题。
回复

使用道具 举报

6#
ID:391219 发表于 2022-10-12 10:46 | 只看该作者
本帖最后由 1123qqw 于 2022-10-12 10:59 编辑
188610329 发表于 2022-10-11 22:21
不是指 SPI 的传输速度 快慢,而是指  SPI  传指令 给 从机, 从机 接受到 指令, 处理,准备数据 回传给主 ...

交换的数据为21位的浮点数。我怎么确保从机能收到呢?芯片手册并没有给如何设置,只是给了一个端口,设置为低电平就能启动SPI通信。
回复

使用道具 举报

7#
ID:391219 发表于 2022-10-12 10:58 | 只看该作者
yzwzfyz 发表于 2022-10-12 08:27
你要保证,当你发送的时候,对方在收!!
建议用中断方式解决这个问题。

从机是PCAP01芯片,说明手册并没有给我如何设置,只是给了一个启动SPI的方式。
回复

使用道具 举报

8#
ID:624769 发表于 2022-10-12 12:49 | 只看该作者
1123qqw 发表于 2022-10-12 10:46
交换的数据为21位的浮点数。我怎么确保从机能收到呢?芯片手册并没有给如何设置,只是给了一个端口,设置 ...

晕死,被带沟里去了, 你说两个芯片SPI通讯, 潜意识就认为 是两个单片机了。弄了半天是 控制器件。

PCAP01 没有用过,不清楚,不过SPI 操控器件, 时好时坏, 无非3个原因
1,线路没接好,有干扰,器件的供电没有,有效的滤波。(检查线路,排除干扰,增加滤波电容,从你的原理图上看,6脚这里应该添加 104电容)
2,主机的 SPI 驱动力不够,距离较远,1/0转换不及时  (添加上拉电阻)
3,SPI 设定的传输速度过快,接近器件的极限值。(降低SPI的速度,测试时建议调到最慢速度。)

回复

使用道具 举报

9#
ID:391219 发表于 2022-10-12 21:12 | 只看该作者
188610329 发表于 2022-10-12 12:49
晕死,被带沟里去了, 你说两个芯片SPI通讯, 潜意识就认为 是两个单片机了。弄了半天是 控制器件。

P ...

我都在一个板上,距离很近。我将速度降低,设置为:SPI_BaudRatePrescaler_256。今天试了一天,还是连接不上,前两天还好好的。现在将数值写入,读出来全是0xFF。还有没有其他可能?这个我的初始化代码。
void SPIx_I2Cx_GPIOs_Init(void* bus_type)
{
        GPIO_InitTypeDef GPIO_InitStructure;
        RCC_APB2PeriphResetCmd(RCC_APB2Periph_GPIOA | RCC_APB2Periph_GPIOB |
                         RCC_APB2Periph_GPIOC | RCC_APB2Periph_GPIOD |
                         RCC_APB2Periph_GPIOE | RCC_APB2Periph_AFIO,  DISABLE);
        RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA | RCC_APB2Periph_GPIOB |
                         RCC_APB2Periph_GPIOC | RCC_APB2Periph_GPIOD |
                         RCC_APB2Periph_GPIOE | RCC_APB2Periph_AFIO,  ENABLE);
       
        //SPI1_NSS
        GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
        GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
        GPIO_InitStructure.GPIO_Pin = GPIO_Pin_4;//PA4
        GPIO_Init(GPIOA,&GPIO_InitStructure);
  //SPI1_CLK
        GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
        GPIO_InitStructure.GPIO_Pin = GPIO_Pin_5;//PA5
  GPIO_Init(GPIOA, &GPIO_InitStructure);
        //SPI_MISO
        GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;
        GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6;//PA6
  GPIO_Init(GPIOA, &GPIO_InitStructure);
        //SPI_MOSI
        GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
        GPIO_InitStructure.GPIO_Pin = GPIO_Pin_7;//PA7
  GPIO_Init(GPIOA, &GPIO_InitStructure);
       
        SPI_I2S_DeInit(bus_type);
        //ía2¿ÖD¶Ïêäèë
        GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;   
        GPIO_InitStructure.GPIO_Pin = GPIO_Pin_4;//PD4
  GPIO_Init(GPIOD, &GPIO_InitStructure);
        //SPI ENABLE Æà1à1¤¾ßêä3ö
        GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
        GPIO_InitStructure.GPIO_Pin = GPIO_Pin_3;//PD3
  GPIO_Init(GPIOD, &GPIO_InitStructure);
        // SPIx Enable = 0 for SPI Mode // SPIx Enable = RSN for GP22
        GPIO_WriteBit(GPIOD, GPIO_Pin_3, Bit_RESET);
}

void SPIx_I2Cx_Interface_Init(void* bus_type)
{
        //3õê¼»ˉSPIx½ó¿ú
        SPI_InitTypeDef SPI_InitStructure;
        //RCC_SYSCLKConfig (RCC_SYSCLKSource_HSI);
        //RCC_HCLKConfig (RCC_SYSCLK_Div1);
        RCC_APB2PeriphResetCmd (RCC_APB2Periph_SPI1, DISABLE);
  RCC_APB2PeriphClockCmd (RCC_APB2Periph_SPI1, ENABLE);
       
        // All are defined in stm32f10x_spi.h
  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;
  // SPI frequence devider
  SPI_InitStructure.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_256;
  SPI_InitStructure.SPI_FirstBit          = SPI_FirstBit_MSB;

  // Apply SPIx configuration
  SPI_Init(bus_type, &SPI_InitStructure);
  // Enabling the SPIx Interface
  SPI_Cmd(bus_type, ENABLE);

  // Enabling the NSS Output during transmission
  SPI_SSOutputCmd (bus_type, ENABLE);
       
        GPIO_WriteBit(GPIOA, GPIO_Pin_4, Bit_SET);
       
}
回复

使用道具 举报

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

本版积分规则

手机版|小黑屋|51黑电子论坛 |51黑电子论坛6群 QQ 管理员QQ:125739409;技术交流QQ群281945664

Powered by 单片机教程网

快速回复 返回顶部 返回列表