[STM32F4] f4与f1/f4 硬件spi双机通信问题!

[复制链接]
 楼主| KC_CEC 发表于 2014-4-11 16:15 | 显示全部楼层 |阅读模式
本帖最后由 KC_CEC 于 2014-4-11 16:24 编辑

现有一个主机stm32f4,两个从机stm32f4和stm32f1。经过硬件spi进行全双工通信。

现在有两个问题:
1、我分别与两个从机相连接,通信比较正常。但是用示波器观察引脚,发现从机返回数据线(也就是MISO)会出现中间电平。中间电平在1.2V的样子!

2、但是为什么主机会正常稳定接收从机数据呢?
我猜因为GPIO内置TTL施密特触发器,所以能稳定忽视中间电平。但是如果主机CMOS的话那会不会导致数据错乱呢?

下面我贴上代码希望大家分析一下:
主机配置如下(stm32f4)
  1. static void SPI_GPIO_Configuration(void)
  2. {
  3.         GPIO_InitTypeDef GPIO_InitStructure;

  4.         RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOB ,ENABLE);
  5.         GPIO_StructInit(&GPIO_InitStructure);

  6.         GPIO_InitStructure.GPIO_Pin = GPIO_Pin_13 | GPIO_Pin_14 | GPIO_Pin_15;
  7.         GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
  8.         GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
  9.         GPIO_InitStructure.GPIO_PuPd  = GPIO_PuPd_UP;
  10.         GPIO_InitStructure.GPIO_Speed = GPIO_Speed_2MHz;
  11.         GPIO_Init(GPIOB, &GPIO_InitStructure);

  12.         GPIO_PinAFConfig(GPIOB, GPIO_PinSource13, GPIO_AF_SPI2);
  13.         GPIO_PinAFConfig(GPIOB, GPIO_PinSource14, GPIO_AF_SPI2);
  14.         GPIO_PinAFConfig(GPIOB, GPIO_PinSource15, GPIO_AF_SPI2);

  15.         GPIO_InitStructure.GPIO_Pin = GPIO_Pin_12;
  16.         GPIO_InitStructure.GPIO_Mode=GPIO_Mode_OUT ;
  17.         GPIO_InitStructure.GPIO_OType=GPIO_OType_PP;
  18.         GPIO_InitStructure.GPIO_PuPd=GPIO_PuPd_NOPULL;
  19.         GPIO_Init(GPIOB, &GPIO_InitStructure);
  20. }

  21. static void SPI_Mode_Configuration(void)
  22. {
  23.         SPI_InitTypeDef  SPI_InitStructure;

  24.         RCC_APB1PeriphClockCmd(RCC_APB1Periph_SPI2, ENABLE);
  25.         SPI_I2S_DeInit(SPI2);

  26.         SPI_InitStructure.SPI_Direction = SPI_Direction_2Lines_FullDuplex;
  27.         SPI_InitStructure.SPI_DataSize = SPI_DataSize_8b;
  28.         SPI_InitStructure.SPI_CPOL = SPI_CPOL_High;
  29.         SPI_InitStructure.SPI_CPHA = SPI_CPHA_2Edge;
  30.         SPI_InitStructure.SPI_NSS = SPI_NSS_Soft;
  31.         SPI_InitStructure.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_256;
  32.         SPI_InitStructure.SPI_FirstBit = SPI_FirstBit_MSB;
  33.         SPI_InitStructure.SPI_CRCPolynomial = 7;
  34.         SPI_InitStructure.SPI_Mode = SPI_Mode_Master;
  35.         SPI_Init(SPI2, &SPI_InitStructure);
  36.         SPI_Cmd(SPI2, ENABLE);
  37. }
从机配置1(stm32f1)
  1. void SPI1_Init(void)
  2. {
  3.         GPIO_InitTypeDef GPIO_InitStructure;
  4.   
  5.         RCC_APB2PeriphClockCmd(        RCC_APB2Periph_GPIOA|RCC_APB2Periph_SPI1, ENABLE );        

  6.         GPIO_InitStructure.GPIO_Pin = GPIO_Pin_4|GPIO_Pin_5 | GPIO_Pin_6 | GPIO_Pin_7;
  7.         GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
  8.         GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
  9.         GPIO_Init(GPIOA, &GPIO_InitStructure);

  10.          GPIO_SetBits(GPIOA,GPIO_Pin_4|GPIO_Pin_5|GPIO_Pin_6|GPIO_Pin_7);

  11.         SPI_InitStructure.SPI_Direction = SPI_Direction_2Lines_FullDuplex;
  12.         SPI_InitStructure.SPI_Mode = SPI_Mode_Slave;
  13.         SPI_InitStructure.SPI_DataSize = SPI_DataSize_8b;
  14.         SPI_InitStructure.SPI_CPOL = SPI_CPOL_High;
  15.         SPI_InitStructure.SPI_CPHA = SPI_CPHA_2Edge;
  16.         SPI_InitStructure.SPI_NSS = SPI_NSS_Hard;
  17.         SPI_InitStructure.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_256;
  18.         SPI_InitStructure.SPI_FirstBit = SPI_FirstBit_MSB;
  19.         SPI_InitStructure.SPI_CRCPolynomial = 7;
  20.         SPI_Init(SPI1, &SPI_InitStructure);
  21.         SPI_Cmd(SPI1, ENABLE);
  22. }   
从机配置2(stm32f4)
  1. static void SPI_GPIO_Configuration(void)
  2. {
  3.         GPIO_InitTypeDef GPIO_InitStructure;

  4.         RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOB ,ENABLE);
  5.         RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOC ,ENABLE);
  6.         GPIO_StructInit(&GPIO_InitStructure);

  7.         GPIO_InitStructure.GPIO_Pin = GPIO_Pin_12|GPIO_Pin_13 | GPIO_Pin_14 | GPIO_Pin_15;
  8.         GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
  9.         GPIO_InitStructure.GPIO_OType = GPIO_OType_OD;//GPIO_OType_PP;
  10.         GPIO_InitStructure.GPIO_PuPd  = GPIO_PuPd_UP;
  11.         GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
  12.         GPIO_Init(GPIOB, &GPIO_InitStructure);

  13.         GPIO_PinAFConfig(GPIOB, GPIO_PinSource12, GPIO_AF_SPI2);
  14.         GPIO_PinAFConfig(GPIOB, GPIO_PinSource13, GPIO_AF_SPI2);
  15.         GPIO_PinAFConfig(GPIOB, GPIO_PinSource14, GPIO_AF_SPI2);
  16.         GPIO_PinAFConfig(GPIOB, GPIO_PinSource15, GPIO_AF_SPI2);
  17.         
  18.         GPIO_SetBits(GPIOB,GPIO_Pin_12|GPIO_Pin_13|GPIO_Pin_14|GPIO_Pin_15);

  19.         GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6| GPIO_Pin_7 | GPIO_Pin_8| GPIO_Pin_9;
  20.         GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT;
  21.         GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
  22.         GPIO_InitStructure.GPIO_PuPd  = GPIO_PuPd_UP;
  23.         GPIO_InitStructure.GPIO_Speed = GPIO_Speed_2MHz;
  24.         GPIO_Init(GPIOC, &GPIO_InitStructure);
  25. }

  26. static void SPI_Mode_Configuration(void)
  27. {
  28.         SPI_InitTypeDef  SPI_InitStructure;

  29.         RCC_APB1PeriphClockCmd(RCC_APB1Periph_SPI2, ENABLE);
  30.         SPI_I2S_DeInit(SPI2);
  31.         SPI_InitStructure.SPI_Direction = SPI_Direction_2Lines_FullDuplex;
  32.         SPI_InitStructure.SPI_DataSize = SPI_DataSize_8b;
  33.         SPI_InitStructure.SPI_CPOL = SPI_CPOL_High;
  34.         SPI_InitStructure.SPI_CPHA = SPI_CPHA_2Edge;
  35.         SPI_InitStructure.SPI_NSS = SPI_NSS_Hard;//SPI_NSS_Hard;//SPI_NSS_Soft;
  36.         SPI_InitStructure.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_256;
  37.         SPI_InitStructure.SPI_FirstBit = SPI_FirstBit_MSB;
  38.         SPI_InitStructure.SPI_CRCPolynomial = 7;
  39.         SPI_InitStructure.SPI_Mode = SPI_Mode_Slave;//SPI_Mode_Master;
  40.         SPI_Init(SPI2, &SPI_InitStructure);
  41.         SPI_Cmd(SPI2, ENABLE);
  42. }


 楼主| KC_CEC 发表于 2014-4-11 16:22 | 显示全部楼层
本帖最后由 KC_CEC 于 2014-4-11 16:25 编辑

下面是主机测试程序(stm32f4)
  1. while(1)
  2.         {
  3.                 printf("************************************\r\n");
  4.                 printf("select the stm32f1..........\r\n");
  5.                 SPI_Send(0xf1);
  6.                 printf("now send stm32f1  data:0xf1........\r\n");
  7.                 printf("read stm32f1 data=%#X\r\n",SPI_Send(0xff));
  8.                 SPI_Send(0xf2);
  9.                 printf("now send stm32f1 data:0xf2........\r\n");
  10.                 printf("read stm32f1 data=%#X\r\n",SPI_Send(0xff));
  11.                 printf("************************************\r\n");
  12.                 printf("select the stm32f4..........\r\n");
  13.                 SPI_Send(0x11);
  14.                 printf("now send stm32f4  data:0x11........\r\n");
  15.                 printf("read stm32f4 data==%#X\r\n",SPI_Send(0xff));
  16.                 SPI_Send(0x12);
  17.                 printf("now send stm32f4 data:0x12........\r\n");
  18.                 printf("read stm32f4 data==%#X\r\n",SPI_Send(0xff));
  19.                 printf("************************************\r\n");
  20.                 SysTick_DelayMS(1000);
  21.                 printf("\r\n");
  22.                 printf("\r\n");
  23.                 printf("\r\n");
  24.         }
实际上从机返回:
f1依次返回:0xf1,0xf2
f4依次返回:0x11,0x12
airwill 发表于 2014-4-11 20:42 | 显示全部楼层
中间电平在1.2V的样子!

说明其中应该存在问题. 硬件上有没有上拉电阻, 是不是拉得太厉害, 另外从机的 IO 口设置 GPIO_Speed_2MHz 适当加大.

 楼主| KC_CEC 发表于 2014-4-14 10:09 | 显示全部楼层
airwill 发表于 2014-4-11 20:42
中间电平在1.2V的样子!

说明其中应该存在问题. 硬件上有没有上拉电阻, 是不是拉得太厉害, 另外从机的 IO  ...

外部硬件没有上拉,直通方式的。SPI的速度已经256分频了。就是42M/256约为164K 所以从机2M的反转速度已经够了哦。
我试了一下用FPGA读取电平,果然会将MISO的中间电平随机的读为高或者低。
然后,我干脆主机模拟SPI,FPGA读取的电平就稳定了
您需要登录后才可以回帖 登录 | 注册

本版积分规则

20

主题

169

帖子

1

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

20

主题

169

帖子

1

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