硬汉嵌入式论坛

 找回密码
 立即注册
查看: 476|回复: 5
收起左侧

[技术讨论] 关于定时器+DMA的采样问题,求助!

[复制链接]

1

主题

9

回帖

12

积分

新手上路

积分
12
发表于 2023-5-7 23:48:29 | 显示全部楼层 |阅读模式
本帖最后由 Conice 于 2023-5-7 23:58 编辑

采集20kHz和18kHz交错的波形,想用360kHz的采样率去采样。采用TIM7产生360kHz的更新事件触发ADC,并采用DMA(选择normal模式)搬运到含有180个元素的数组中,想每搬运完一次,打印一次数据。现在打印出来的数据中前90个数是正弦波,后90个数全是0,请大神帮忙看一下代码。万分感谢!
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_ADC1_Init();
  MX_TIM7_Init();
  MX_DAC1_Init();
  MX_TIM6_Init();
  MX_USART2_UART_Init();
  MX_TIM4_Init();
  /* USER CODE BEGIN 2 */
        /* 对数组进行处理,防止载波信号底部失真 */
        for (uint16_t Idx=0; Idx<100; Idx++)
        {
                sin_12bit[Idx]=sin_12bit[Idx]*8/10+500;
        }         
        
         /* 开启TIM6,触发DAC */
        HAL_TIM_Base_Start(&htim6);
        
        /* 开启TIM7,触发ADC采样 */
        HAL_TIM_Base_Start(&htim7);
        
        HAL_DAC_Start_DMA(&hdac1,DAC1_CHANNEL_1,(uint32_t*)sin_12bit,100,DAC_ALIGN_12B_R);
        
        HAL_ADCEx_Calibration_Start(&hadc1,ADC_SINGLE_ENDED);
        HAL_ADC_Start_DMA(&hadc1,(uint32_t*)ADC_ConvertedValue, LENGTH);
        
  /* USER CODE END 2 */

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

    /* USER CODE BEGIN 3 */        
                if(flag==1)
                {
                        for(int i=0; i<LENGTH; i++)
                        {
                                printf("%d, %d\r\n", i, ADC_ConvertedValue);
                        }
                        HAL_TIM_Base_Start(&htim7);        //重新启动定时器7
                        HAL_ADC_Start_DMA(&hadc1,(uint32_t*)ADC_ConvertedValue, LENGTH); //重新开始下一轮采集
                        flag=0;
                }
   }
  /* USER CODE END 3 */
}



/* 下面是DMA1_Channel1中断函数的代码*/
void DMA1_Channel1_IRQHandler(void)
{
  /* USER CODE BEGIN DMA1_Channel1_IRQn 0 */

  /* USER CODE END DMA1_Channel1_IRQn 0 */
  HAL_DMA_IRQHandler(&hdma_adc1);
  /* USER CODE BEGIN DMA1_Channel1_IRQn 1 */

/******************************************************************************/
        HAL_TIM_Base_Stop(&htim7);//定时器7停止
        HAL_ADC_Stop_DMA(&hadc1);//停止ADC的DMA传输
        flag=1;//标志位置1,表示本次采样结束
/******************************************************************************/
}
[/mw_shl_code]

DAC产生波形(被采样的波形)

DAC产生波形(被采样的波形)

采样后的波形

采样后的波形
回复

使用道具 举报

1万

主题

6万

回帖

10万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
106934
QQ
发表于 2023-5-8 08:58:11 | 显示全部楼层
DMA中断里面的处理不好,使用HAL一定要在它的中断回调里面处理,像你这里应该是DMA半传输中断完成就进去了,导致仅采集了一半就被你关闭了。
回复

使用道具 举报

1

主题

9

回帖

12

积分

新手上路

积分
12
 楼主| 发表于 2023-5-8 09:25:39 | 显示全部楼层
eric2013 发表于 2023-5-8 08:58
DMA中断里面的处理不好,使用HAL一定要在它的中断回调里面处理,像你这里应该是DMA半传输中断完成就进去了 ...

硬汉哥,是在DMA1_Channel1_IRQHandler这个中断函数中处理吗?搞了两天也没搞好
void DMA1_Channel1_IRQHandler(void)
{
  /* USER CODE BEGIN DMA1_Channel1_IRQn 0 */

  /* USER CODE END DMA1_Channel1_IRQn 0 */
  HAL_DMA_IRQHandler(&hdma_adc1);
  /* USER CODE BEGIN DMA1_Channel1_IRQn 1 */
        HAL_TIM_Base_Stop(&htim7);//定时器7停止
        HAL_ADC_Stop_DMA(&hadc1);//停止ADC的DMA传输
        flag=1;//标志位置1,表示本次采样结束
}
回复

使用道具 举报

1

主题

9

回帖

12

积分

新手上路

积分
12
 楼主| 发表于 2023-5-8 09:53:33 | 显示全部楼层
eric2013 发表于 2023-5-8 08:58
DMA中断里面的处理不好,使用HAL一定要在它的中断回调里面处理,像你这里应该是DMA半传输中断完成就进去了 ...

    百度了一下,DMA半传输中断。
    CPU 会在收到这个中断请求后执行相应的中断处理程序来进一步处理已经传输完成的数据。当·DMA·完成数据传输后,它会发送一个中断请求给·CPU,这个中断请求就是半传输中断。CPU·收到中断请求后会暂停当前的操作,并执行与该中断对应的中断处理程序,也就是处理这个中断事件的代码。在半传输中断处理程序中,通常会对已经传输完成的数据进行进一步处理,例如将其复制到其他内存区域或者进行其他的数据处理操作。“
    请问怎么改成全传输中断请求呢
回复

使用道具 举报

1万

主题

6万

回帖

10万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
106934
QQ
发表于 2023-5-8 14:44:06 | 显示全部楼层
Conice 发表于 2023-5-8 09:25
硬汉哥,是在DMA1_Channel1_IRQHandler这个中断函数中处理吗?搞了两天也没搞好
void DMA1_Channel1_I ...

DMA有传输完成回调API的,还有一个半传输完成回调API。
回复

使用道具 举报

1万

主题

6万

回帖

10万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
106934
QQ
发表于 2023-5-8 14:45:14 | 显示全部楼层
Conice 发表于 2023-5-8 09:53
百度了一下,DMA半传输中断。
    CPU 会在收到这个中断请求后执行相应的中断处理程序来进一步处理 ...

DMA有传输完成回调API的,还有一个半传输完成回调API。

你的关闭放在DMA传输完成回调里面即可,你在HAL_DMA_IRQHandler源码里面就看到那个回调函数了。是个弱定义的,你可以在其它地方重定向它
回复

使用道具 举报

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

本版积分规则

QQ|小黑屋|Archiver|手机版|硬汉嵌入式论坛

GMT+8, 2024-5-10 23:34 , Processed in 0.172392 second(s), 28 queries .

Powered by Discuz! X3.4 Licensed

Copyright © 2001-2023, Tencent Cloud.

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