You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

基于STM32F767的SPI DMA触发读取ADS1282问题求助

STM32F767 结合SPI+DMA读取ADS1282的配置问题

我需要使用STM32F767通过SPI接口搭配DMA读取32位Sigma Delta ADC(ADS1282),这款ADC带有Data Ready引脚,用于指示新数据已就绪。

ADS1282连接示意图

我的实现思路是通过Data Ready引脚触发外部中断,在中断中启动DMA传输。当前代码混合了裸机编程与Cube IDE自动配置的内容:

void EXTI1_IRQHandler(void)
{
  /* USER CODE BEGIN EXTI1_IRQn 0 */

  /* USER CODE END EXTI1_IRQn 0 */
  HAL_GPIO_EXTI_IRQHandler(GPIO_PIN_1);
  /* USER CODE BEGIN EXTI1_IRQn 1 */

  data_ready_flag = 1;

  DMA2_Stream0->CR |= DMA_SxCR_EN; // 启用DMA传输

  SPI1->CR2 |= SPI_CR2_TXDMAEN; // 启用TX DMA请求
  SPI1->CR1 |= SPI_CR1_SPE; // 启用SPI


  EXTI->PR |= EXTI_PR_PR1;
  /* USER CODE END EXTI1_IRQn 1 */
}

void DMA2_Stream0_IRQHandler(void)
{
  /* USER CODE BEGIN DMA2_Stream0_IRQn 0 */

  /* USER CODE END DMA2_Stream0_IRQn 0 */
  HAL_DMA_IRQHandler(&hdma_spi1_rx);
  /* USER CODE BEGIN DMA2_Stream0_IRQn 1 */
  if (DMA2->LISR & DMA_LISR_TCIF0)
     {
      for (int i = 0; i < SPI_BUF_LEN; i++)
      {
          receivedDataX[i] = destinationBuffer[i];
      }
        
      DMA2->LIFCR |= DMA_LIFCR_CTCIF0;

      SPI1->CR2 &= ~SPI_CR2_TXDMAEN;
     }
  /* USER CODE END DMA2_Stream0_IRQn 1 */
}


int main(void)
{
  /* USER CODE BEGIN 1 */

  /* USER CODE END 1 */

  /* MCU Configuration--------------------------------------------------------*/

  /* Reset of all peripherals, Initializes the Flash interface and the Systick. */
  HAL_Init();

  /* USER CODE BEGIN Init */

  /* USER CODE END Init */

  /* Configure the system clock */
  SystemClock_Config();

  /* USER CODE BEGIN SysInit */

  /* USER CODE END SysInit */

  /* Initialize all configured peripherals */
  MX_GPIO_Init();
  MX_DMA_Init();
  MX_SPI1_Init();
  MX_ETH_Init();
  MX_USART3_UART_Init();
  MX_USB_OTG_FS_PCD_Init();
  MX_TIM3_Init();
  MX_TIM4_Init();
  MX_TIM9_Init();
  /* USER CODE BEGIN 2 */

  HAL_GPIO_WritePin(GPIOA, GPIO_PIN_3, GPIO_PIN_RESET); // 拉低片选1

  TIM3->CCR1 = 10;
  HAL_TIM_PWM_Start(&htim3, TIM_CHANNEL_1);

  /// 步骤3:启用SPI1的DMA时钟
  RCC->AHB1ENR |= RCC_AHB1ENR_DMA2EN;

  // 步骤4:DMA配置
  DMA2_Stream0->PAR = (uint16_t)(&(SPI1->DR)); // 外设地址:SPI1数据寄存器
  DMA2_Stream0->M0AR = (uint16_t)destinationBuffer; // 内存地址:目标缓冲区
  DMA2_Stream0->NDTR = SPI_BUF_LEN; // 传输数据长度
  DMA2_Stream0->CR = DMA_SxCR_CHSEL_0 | DMA_SxCR_MINC | DMA_SxCR_DIR_0; // 通道0,内存增量模式,内存到外设模式

  // 步骤5:配置并启用DMA流
  DMA2_Stream0->CR |= DMA_SxCR_TCIE; // 启用传输完成中断
  NVIC_EnableIRQ(DMA2_Stream0_IRQn); // 启用DMA流的NVIC中断

  /* USER CODE END 2 */

  /* Infinite loop */
  /* USER CODE BEGIN WHILE */
  while (1)
  {
    /* USER CODE END WHILE */

    /* USER CODE BEGIN 3 */

  }
  /* USER CODE END 3 */
}

目前使用轮询方式读取数据时一切正常,但DMA方式无论采用纯Cube IDE配置还是裸机代码实现都无法正常工作。以下是Cube IDE生成的SPI初始化代码:

static void MX_SPI1_Init(void)
{

  /* USER CODE BEGIN SPI1_Init 0 */

  /* USER CODE END SPI1_Init 0 */

  /* USER CODE BEGIN SPI1_Init 1 */

  /* USER CODE END SPI1_Init 1 */
  /* SPI1 parameter configuration*/
  hspi1.Instance = SPI1;
  hspi1.Init.Mode = SPI_MODE_MASTER;
  hspi1.Init.Direction = SPI_DIRECTION_2LINES;
  hspi1.Init.DataSize = SPI_DATASIZE_8BIT;
  hspi1.Init.CLKPolarity = SPI_POLARITY_LOW;
  hspi1.Init.CLKPhase = SPI_PHASE_1EDGE;
  hspi1.Init.NSS = SPI_NSS_SOFT;
  hspi1.Init.BaudRatePrescaler = SPI_BAUDRATEPRESCALER_4;
  hspi1.Init.FirstBit = SPI_FIRSTBIT_MSB;
  hspi1.Init.TIMode = SPI_TIMODE_DISABLE;
  hspi1.Init.CRCCalculation = SPI_CRCCALCULATION_DISABLE;
  hspi1.Init.CRCPolynomial = 7;
  hspi1.Init.CRCLength = SPI_CRC_LENGTH_DATASIZE;
  hspi1.Init.NSSPMode = SPI_NSS_PULSE_DISABLE;
  if (HAL_SPI_Init(&hspi1) != HAL_OK)
  {
    Error_Handler();
  }
  /* USER CODE BEGIN SPI1_Init 2 */

  /* USER CODE END SPI1_Init 2 */

}

请问如何正确配置DMA与SPI,实现由Data Ready中断触发的接收流程?


内容的提问来源于stack exchange,提问作者Ruffy

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.07 22:35:55