OpenEdv-开源电子网

 找回密码
 立即注册
正点原子全套STM32/Linux/FPGA开发资料,上千讲STM32视频教程免费下载...
查看: 7672|回复: 4

【求助】STM32F407与双输出的ADC进行主从SPI通信

[复制链接]

2

主题

5

帖子

0

精华

新手入门

积分
14
金钱
14
注册时间
2019-8-7
在线时间
7 小时
发表于 2021-4-16 13:11:52 | 显示全部楼层 |阅读模式
10金钱
项目需要用到双路信号同步采样,于是选则了ADI的16位ADC AD7386,它是SPI接口,有片选、时钟、1输入、2输出。ADC芯片的工作模式大概是:拉低CS信号,芯片即开始转换,然后在两个输出引脚同时输出两个通道的转换结果。我用一块407核心板控制ADC芯片,示波器看芯片的两个输出口均有正常波形。SPI主机可以正常收发,从机却不行。在SPI接收中断里查看SPI4数据寄存器DR为空,而且SPI4的控制寄存器CR1也为空,但是明明经过初始化程序了,百思不得其解,附上程序求好心人帮忙分析一下



void SPI_ADC_Init(void)
{
  SPI_InitTypeDef  SPI_InitStructure;
  GPIO_InitTypeDef GPIO_InitStructure;

  /* GPIO时钟 */
  RCC_AHB1PeriphClockCmd (ADC_MASTER_SPI_SCK_GPIO_CLK | ADC_MASTER_SPI_MISO_GPIO_CLK | ADC_MASTER_SPI_MOSI_GPIO_CLK |
  ADC_MASTER_CS_GPIO_CLK | ADC_SLAVE_SPI_SCK_GPIO_CLK | ADC_SLAVE_SPI_MOSI_GPIO_CLK | ADC_SLAVE_CS_GPIO_CLK, ENABLE);

  /*SPI时钟*/
  RCC_APB2PeriphClockCmd(ADC_MASTER_SPI_CLK, ENABLE);
  RCC_APB2PeriphClockCmd(ADC_SLAVE_SPI_CLK, ENABLE);

  //GPIO复用
  GPIO_PinAFConfig(ADC_MASTER_SPI_SCK_GPIO_PORT,ADC_MASTER_SPI_SCK_PINSOURCE,ADC_MASTER_SPI_SCK_AF);
  GPIO_PinAFConfig(ADC_MASTER_SPI_MISO_GPIO_PORT,ADC_MASTER_SPI_MISO_PINSOURCE,ADC_MASTER_SPI_MISO_AF);
  GPIO_PinAFConfig(ADC_MASTER_SPI_MOSI_GPIO_PORT,ADC_MASTER_SPI_MOSI_PINSOURCE,ADC_MASTER_SPI_MOSI_AF);

  GPIO_PinAFConfig(ADC_SLAVE_SPI_SCK_GPIO_PORT,ADC_SLAVE_SPI_SCK_PINSOURCE,ADC_SLAVE_SPI_SCK_AF);
  GPIO_PinAFConfig(ADC_SLAVE_SPI_MOSI_GPIO_PORT,ADC_SLAVE_SPI_MOSI_PINSOURCE,ADC_SLAVE_SPI_MOSI_AF);
  GPIO_PinAFConfig(ADC_SLAVE_CS_GPIO_PORT,ADC_SLAVE_CS_PINSOURCE,ADC_SLAVE_CS_AF);
       
  /* ADC_MASTER_SPI_SCK*/
  GPIO_InitStructure.GPIO_Pin = ADC_MASTER_SPI_SCK_PIN;
  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
  GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
  GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;  
  GPIO_Init(ADC_MASTER_SPI_SCK_GPIO_PORT, &GPIO_InitStructure);

  /* ADC_MASTER_SPI_MISO */
  GPIO_InitStructure.GPIO_Pin = ADC_MASTER_SPI_MISO_PIN;
  GPIO_Init(ADC_MASTER_SPI_MISO_GPIO_PORT, &GPIO_InitStructure);

  /*ADC_MASTER_SPI_MOSI */
  GPIO_InitStructure.GPIO_Pin = ADC_MASTER_SPI_MOSI_PIN;
  GPIO_Init(ADC_MASTER_SPI_MOSI_GPIO_PORT, &GPIO_InitStructure);  

  /*ADC_MASTER_SPI_CS */
  GPIO_InitStructure.GPIO_Pin = ADC_MASTER_CS_PIN;
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT;
  GPIO_Init(ADC_MASTER_CS_GPIO_PORT, &GPIO_InitStructure);
       
  /*ADC_SLAVE_SPI_SCK */
  GPIO_InitStructure.GPIO_Pin = ADC_SLAVE_SPI_SCK_PIN;
  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
  GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
  GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;
  GPIO_Init(ADC_SLAVE_SPI_SCK_GPIO_PORT, &GPIO_InitStructure);
       
  /*ADC_SLAVE_SPI_MOSI */
  GPIO_InitStructure.GPIO_Pin = ADC_SLAVE_SPI_MOSI_PIN;
  GPIO_Init(ADC_SLAVE_SPI_MOSI_GPIO_PORT, &GPIO_InitStructure);  

  /*ADC_SLAVE_SPI_CS */
  GPIO_InitStructure.GPIO_Pin = ADC_SLAVE_CS_PIN;       
  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
  GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
  GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;       
  GPIO_Init(ADC_SLAVE_CS_GPIO_PORT, &GPIO_InitStructure);

  /*拉高片选信号*/
  SPI_ADC_CS_HIGH();

  /* ADC_MASTER_SPI SPI1主机模式配置 */
  SPI_InitStructure.SPI_Direction = SPI_Direction_2Lines_FullDuplex;
  SPI_InitStructure.SPI_Mode = SPI_Mode_Master;
  SPI_InitStructure.SPI_DataSize = SPI_DataSize_16b;
  SPI_InitStructure.SPI_CPOL = SPI_CPOL_High;
  SPI_InitStructure.SPI_CPHA = SPI_CPHA_1Edge;
  SPI_InitStructure.SPI_NSS = SPI_NSS_Soft;
  SPI_InitStructure.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_256;//
  SPI_InitStructure.SPI_FirstBit = SPI_FirstBit_MSB;
  SPI_InitStructure.SPI_CRCPolynomial = 7;
  SPI_Init(ADC_MASTER_SPI, &SPI_InitStructure);

  /* ADC_SLAVE_SPI SPI4从机模式配置 */
  SPI_InitStructure.SPI_Direction = SPI_Direction_2Lines_RxOnly;
  SPI_InitStructure.SPI_Mode = SPI_Mode_Slave;
  SPI_InitStructure.SPI_DataSize = SPI_DataSize_16b;
  SPI_InitStructure.SPI_CPOL = SPI_CPOL_High;
  SPI_InitStructure.SPI_CPHA = SPI_CPHA_1Edge;
  SPI_InitStructure.SPI_NSS = SPI_NSS_Hard;
  SPI_InitStructure.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_256;
  SPI_InitStructure.SPI_FirstBit = SPI_FirstBit_MSB;
  SPI_InitStructure.SPI_CRCPolynomial = 7;
  SPI_Init(ADC_SLAVE_SPI, &SPI_InitStructure);
       
  /* 使能SPI  */
  SPI_Cmd(ADC_MASTER_SPI, ENABLE);
  SPI_Cmd(ADC_SLAVE_SPI, ENABLE);
}




void SPI_Init(SPI_TypeDef* SPIx, SPI_InitTypeDef* SPI_InitStruct)
{
  uint16_t tmpreg = 0;

......


  tmpreg = SPIx->CR1;

  tmpreg &= CR1_CLEAR_MASK;

  tmpreg |= (uint16_t)((uint32_t)SPI_InitStruct->SPI_Direction | SPI_InitStruct->SPI_Mode |
                  SPI_InitStruct->SPI_DataSize | SPI_InitStruct->SPI_CPOL |  
                  SPI_InitStruct->SPI_CPHA | SPI_InitStruct->SPI_NSS |  
                  SPI_InitStruct->SPI_BaudRatePrescaler | SPI_InitStruct->SPI_FirstBit);
  /* Write to SPIx CR1 */
  SPIx->CR1 = tmpreg;   //SPI4初始化程序到这之前都没问题,tmpreg变量的值也没错,和SPI初始化结构体里设置的一样

  /* Activate the SPI mode (Reset I2SMOD bit in I2SCFGR register) */
  SPIx->I2SCFGR &= (uint16_t)~((uint16_t)SPI_I2SCFGR_I2SMOD);
/*---------------------------- SPIx CRCPOLY Configuration --------------------*/
  /* Write to SPIx CRCPOLY */
  SPIx->CRCPR = SPI_InitStruct->SPI_CRCPolynomial;
}


最后相同的初始化流程,在watch window里面查看SPI1->CR1配置数据正常,而SPI4->CR1里则是0,懵在这里
无标题.png

最佳答案

查看完整内容[请看2#楼]

主从spi的话可以参考下这个http://www.openedv.com/forum.php?mod=viewthread&tid=63358&highlight=%D6%F7%B4%D3%2Bspi
正点原子逻辑分析仪DL16劲爆上市
回复

使用道具 举报

15

主题

1061

帖子

0

精华

资深版主

Rank: 8Rank: 8

积分
3606
金钱
3606
注册时间
2019-8-14
在线时间
1052 小时
发表于 2021-4-16 13:11:53 | 显示全部楼层
回复

使用道具 举报

2

主题

5

帖子

0

精华

新手入门

积分
14
金钱
14
注册时间
2019-8-7
在线时间
7 小时
 楼主| 发表于 2021-4-16 18:59:47 | 显示全部楼层
hou18 发表于 2021-4-16 17:25
主从spi的话可以参考下这个http://www.openedv.com/forum.php?mod=viewthread&tid=63358&highlight=%D6%F7% ...

帖子已参考感谢回复,刚才顺便复习了一下资料,我的问题可能出在从机SPI模式配置成单向双线模式上了,等过两天把手上事情忙完了试试
回复

使用道具 举报

2

主题

5

帖子

0

精华

新手入门

积分
14
金钱
14
注册时间
2019-8-7
在线时间
7 小时
 楼主| 发表于 2021-4-17 20:32:11 | 显示全部楼层
问题查出来了,野火的教程害人,STM32F407只有spi1至spi3,没有spi4。正常接线,需要将SPI从机的NSS设置为硬件模式。不过标准库函数中的SPI_InitStructure.SPI_Direction = SPI_Direction_1Lines_RxOnly;这句并不能正确配置SPI3,需要手动设置SPI->CR1中BIDIMODE位的值,才能配置成单线只接收。
回复

使用道具 举报

0

主题

3

帖子

0

精华

新手上路

积分
36
金钱
36
注册时间
2020-6-13
在线时间
8 小时
发表于 2022-5-24 19:30:36 | 显示全部楼层
楼主我最近也在做7386的程序,能看一下你的源代码吗,我用的是f429
回复

使用道具 举报

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

本版积分规则



关闭

原子哥极力推荐上一条 /2 下一条

正点原子公众号

QQ|手机版|OpenEdv-开源电子网 ( 粤ICP备12000418号-1 )

GMT+8, 2025-2-25 18:24

Powered by OpenEdv-开源电子网

© 2001-2030 OpenEdv-开源电子网

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