stm32 H7 ADC DMA采集

学习记录一下

简单实现了adc采集波形数据,并通过vofa打印出波形

 定时器配置

 ADC配置

根据板子原理图,配置差分模式 

 设置dma

然后配置一下串口和时钟,生成工程,注意DMA搬运数据是需要时间的,因此需要有AdcConvEnd这样一个标志位,搬运完成之后再进下一次采集传输

/* Private define ------------------------------------------------------------*/
/* USER CODE BEGIN PD */
#define SAMP_NUM 1024
/* USER CODE END PD */


/* USER CODE BEGIN PV */
	uint16_t ADC_1_buff[SAMP_NUM];
	//uint16_t ADC_2_buff[SAMP_NUM];
	__IO uint8_t AdcConvEnd = 0;  // ADC DMA搬运完成标志
/* USER CODE END PV */
  /* USER CODE BEGIN WHILE */
  while (1)
  {
    /* USER CODE END WHILE */
    /* USER CODE BEGIN 3 */
	 HAL_ADC_Start_DMA(&hadc1,(uint32_t *)ADC_1_buff,SAMP_NUM);  // 开启ADC DMA采样
     HAL_TIM_Base_Start(&htim1); 		// 使能定时器
		while(!AdcConvEnd);             // DMA搬运完成标志
    // 打印波形数据
	  for(int i=0;i<SAMP_NUM;i++)
	  {
		  printf("%d\n",ADC_1_buff[i]);
	  }
  }
  /* USER CODE END 3 */

在stm32h7xx_it.c文件中找到

void DMA1_Stream1_IRQHandler(void)
{
  /* USER CODE BEGIN DMA1_Stream1_IRQn 0 */

  /* USER CODE END DMA1_Stream1_IRQn 0 */
  HAL_DMA_IRQHandler(&hdma_adc1);
  /* USER CODE BEGIN DMA1_Stream1_IRQn 1 */
		AdcConvEnd = 1;    // DMA传输完成
  /* USER CODE END DMA1_Stream1_IRQn 1 */
}

串口重定向 

// 串口重定向	
    int fputc(int ch, FILE *f)
	{
		HAL_UART_Transmit(&huart1, (uint8_t *)&ch, 1, 0xffff);
		return ch;
	}
	 
	int fgetc(FILE *f)
	{
		uint8_t ch = 0;
		HAL_UART_Receive(&huart1, &ch, 1, 0xffff);
		return ch;
	}

 实际测试

上述只是实现的方式之一,实际应用也有很多其他的选择

    // ADC校准
    HAL_ADCEx_Calibration_Start(&hadc1, ADC_CALIB_OFFSET_LINEARITY, ADC_DIFFERENTIAL_ENDED);
    HAL_ADCEx_Calibration_Start(&hadc2, ADC_CALIB_OFFSET_LINEARITY, ADC_DIFFERENTIAL_ENDED);
   // 启动ADC转换
    HAL_ADC_Start_DMA(&hadc1,(uint32_t *)adcBuff_1,FFT_LENGTH);  // enable ADC_1 DMA采样
    HAL_ADC_Start_DMA(&hadc2,(uint32_t *)adcBuff_2,FFT_LENGTH);  // enable ADC_2 DMA采样
    HAL_TIM_Base_Start(&htim3); 		// 使能定时器3

比如将处理逻辑放在ADC中断回调函数中 



// ADC中断回调函数
 void HAL_ADC_ConvCpltCallback(ADC_HandleTypeDef *hadc)
{
    /* Prevent unused argument(s) compilation warning */
    UNUSED(hadc);
    HAL_ADC_Stop_DMA(&hadc1);  // 关闭 ADC_1 DMA采样
    HAL_ADC_Stop_DMA(&hadc2);  // 关闭 ADC_2 DMA采样
    HAL_TIM_Base_Stop(&htim3);  // 失能定时器3
// ----------------------------------------------------------------------------------数据处理开始----------------------------------------------------------------------------------//
    for(int i=0;i<FFT_LENGTH;i++)
    {
//        adcBuff_1_f[i] =(float) (adcBuff_1[i] - 7075)/605 - 2;
//        adcBuff_2_f[i] =(float) (adcBuff_2[i] - 7075)/605 - 2;  // ADC数据转化为浮点数
        adcBuff_1_f[i] =(float) (1.0 *adcBuff_1[i] - 8520);
        adcBuff_2_f[i] =(float) (1.0 *adcBuff_2[i] - 8520 );  // ADC数据转化为浮点数
    }
    //  加窗处理
    Add_Win_Fun(adcBuff_1_f, adcBuff_1_f_WIN, hanning_win_norm, FFT_LENGTH);  // 对ADC_1数据加窗
    Add_Win_Fun(adcBuff_2_f, adcBuff_2_f_WIN, hanning_win_norm, FFT_LENGTH);  // 对ADC_2数据加窗
    FFT_Cal(adcBuff_1_f_WIN,fft_inputbuf_1,fft_outputbuf_1,FFT_LENGTH);
    FFT_Cal(adcBuff_2_f_WIN,fft_inputbuf_2,fft_outputbuf_2,FFT_LENGTH);

//    for(int i =0;i<5;i++)
//    {
//        phase_diff[i] = phase_diff_1[i] - phase_diff_2[i];  // 相位差计算
//        printf("%f\n",phase_diff[i]);
//    }
//    for(int i=0;i<FFT_LENGTH/2;i++)  // 取一半长度的有用信息打印
//    {
//         //printf("%f\n",adcBuff_1_f[i]);
//         //printf("%d\n",adcBuff_1[i]);
//       printf("%f\n",fft_outputbuf_1[i]);  // 打印FFT结果
//    }
    Phase = AP_FFT(adcBuff_1_f ,adcBuff_2_f ,FFT_LENGTH );
    printf("%f\n",Phase);
//    for(int i=0;i<FFT_LENGTH/2;i++)  // 取一半长度的有用信息打印
//    {
//         printf("%f\n",adcBuff_2_f[i]);
//          printf("%d\n",adcBuff_2[i]);
//      //  printf("%f\n",fft_outputbuf_1[i]);  // 打印FFT结果
//    }

 //---------------------------------------------------------------------  数据处理完成后,再开始启动下一次同步采样-------------------------------------------------------------------//
    HAL_ADC_Start_DMA(&hadc1,(uint32_t *)adcBuff_1,FFT_LENGTH);  // enable ADC_1 DMA采样
    HAL_ADC_Start_DMA(&hadc2,(uint32_t *)adcBuff_2,FFT_LENGTH);  // enable ADC_2 DMA采样
    HAL_TIM_Base_Start(&htim3);  // 重新使能定时器3
    /* NOTE : This function should not be modified. When the callback is needed,
              function HAL_ADC_ConvCpltCallback must be implemented in the user file.
     */
}


评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值