硬汉嵌入式论坛

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

[ADC] STM32H7的定时器触发ADC双缓冲方式波形效果验证

  [复制链接]

1万

主题

6万

回帖

10万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
106997
QQ
发表于 2020-2-14 01:53:55 | 显示全部楼层 |阅读模式
经常有网友反映说,波形效果不连续。

其实根本原因还是Cache的处理问题,简单起见,直接关闭ADC所使用的RAM空间的Cache即可。

下面是2Msps采集50KHz方波:

666.png

1.png







回复

使用道具 举报

13

主题

223

回帖

262

积分

高级会员

积分
262
发表于 2020-2-15 17:39:53 | 显示全部楼层
有工程代码?
回复

使用道具 举报

1万

主题

6万

回帖

10万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
106997
QQ
 楼主| 发表于 2020-2-15 17:42:35 | 显示全部楼层
回复

使用道具 举报

13

主题

223

回帖

262

积分

高级会员

积分
262
发表于 2020-5-2 20:31:32 | 显示全部楼层
老大 试一下采集低频信号看看 比如5Hz  10Hz
回复

使用道具 举报

1万

主题

6万

回帖

10万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
106997
QQ
 楼主| 发表于 2020-5-2 20:33:52 | 显示全部楼层
miaoqiongb 发表于 2020-5-2 20:31
老大 试一下采集低频信号看看 比如5Hz  10Hz

不测了,后面专门做个J-Scope版的,方便大家直接测试。
回复

使用道具 举报

13

主题

223

回帖

262

积分

高级会员

积分
262
发表于 2020-5-19 23:45:42 | 显示全部楼层
eric2013 发表于 2020-5-2 20:33
不测了,后面专门做个J-Scope版的,方便大家直接测试。

这个例子老大什么时候放出来?
回复

使用道具 举报

1万

主题

6万

回帖

10万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
106997
QQ
 楼主| 发表于 2020-5-19 23:53:48 | 显示全部楼层
miaoqiongb 发表于 2020-5-19 23:45
这个例子老大什么时候放出来?

有时间了。
回复

使用道具 举报

1

主题

11

回帖

14

积分

新手上路

积分
14
发表于 2020-9-16 15:38:45 | 显示全部楼层
你好,h743单通道独立模式可以到3mhz采样率吗?我这个始终上不去,我用的LQFP100的封装
回复

使用道具 举报

1

主题

11

回帖

14

积分

新手上路

积分
14
发表于 2020-9-16 15:41:23 | 显示全部楼层
miaoqiongb 发表于 2020-5-2 20:31
老大 试一下采集低频信号看看 比如5Hz  10Hz

你好,可以交流一下h743adc采样方面的问题吗?
回复

使用道具 举报

1万

主题

6万

回帖

10万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
106997
QQ
 楼主| 发表于 2020-9-16 16:22:11 | 显示全部楼层
bao292387701 发表于 2020-9-16 15:38
你好,h743单通道独立模式可以到3mhz采样率吗?我这个始终上不去,我用的LQFP100的封装

LQFP100封装,16分辨率,最高1.9MHz。
回复

使用道具 举报

1

主题

11

回帖

14

积分

新手上路

积分
14
发表于 2020-9-16 16:24:14 | 显示全部楼层
eric2013 发表于 2020-9-16 16:22
LQFP100封装,16分辨率,最高1.9MHz。

我现在用12位的,也是上不去,还需要修改哪吗?手册上应该能到4M多
回复

使用道具 举报

1

主题

11

回帖

14

积分

新手上路

积分
14
发表于 2020-9-16 21:03:36 | 显示全部楼层

h743的采样率能到多少,我现在已经12bit,快速通道5,ADC时钟源36MHz,按手册来说应该可以到3MHz采样率,可是还是不行,你试过吗
回复

使用道具 举报

1万

主题

6万

回帖

10万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
106997
QQ
 楼主| 发表于 2020-9-16 21:35:02 | 显示全部楼层
bao292387701 发表于 2020-9-16 21:03
h743的采样率能到多少,我现在已经12bit,快速通道5,ADC时钟源36MHz,按手册来说应该可以到3MHz采样率, ...

那就改成8bit试试,还是有问题,基本可以确定是配置问题了。
回复

使用道具 举报

1

主题

11

回帖

14

积分

新手上路

积分
14
发表于 2020-9-16 21:39:22
eric2013 发表于 2020-9-16 21:35
那就改成8bit试试,还是有问题,基本可以确定是配置问题了。

好,我改一下试试

1

主题

11

回帖

14

积分

新手上路

积分
14
发表于 2020-9-17 11:10:45 | 显示全部楼层
eric2013 发表于 2020-2-15 17:42
http://www.armbbs.cn/forum.php?m ... 6980&extra=page%3D1

您这个v7-019的例子,采样率可以到挺高的是吧
回复

使用道具 举报

1万

主题

6万

回帖

10万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
106997
QQ
 楼主| 发表于 2020-9-18 00:49:06 | 显示全部楼层
bao292387701 发表于 2020-9-17 11:10
您这个v7-019的例子,采样率可以到挺高的是吧

可以的。
回复

使用道具 举报

0

主题

2

回帖

2

积分

新手上路

积分
2
发表于 2020-11-15 14:53:18 | 显示全部楼层
请问下,如果ADC的采样率为2Msps,那个16位精度下,就会由32Mbit/s的数据产生,这么多的数据是如何传输出来的呢?
回复

使用道具 举报

1万

主题

6万

回帖

10万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
106997
QQ
 楼主| 发表于 2020-11-15 15:03:16 | 显示全部楼层
大杯小米不加糖 发表于 2020-11-15 14:53
请问下,如果ADC的采样率为2Msps,那个16位精度下,就会由32Mbit/s的数据产生,这么多的数据是如何传输出来 ...

保存了一段数据,导出来。

需要上位机那种,可看我们H7-TOOL即可。



回复

使用道具 举报

0

主题

2

回帖

2

积分

新手上路

积分
2
发表于 2020-11-15 15:13:37 | 显示全部楼层
想要做到实时显示的话,传输压力会不会太大?上位机和开发板之间是用网口传数据吗?
回复

使用道具 举报

1万

主题

6万

回帖

10万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
106997
QQ
 楼主| 发表于 2020-11-15 15:31:43 | 显示全部楼层
大杯小米不加糖 发表于 2020-11-15 15:13
想要做到实时显示的话,传输压力会不会太大?上位机和开发板之间是用网口传数据吗?

网口或者USB接口都支持,怎么玩都行。
回复

使用道具 举报

0

主题

9

回帖

9

积分

新手上路

积分
9
发表于 2020-11-17 10:47:33 | 显示全部楼层
大佬,这个上位机用的是什么软件啊
回复

使用道具 举报

1万

主题

6万

回帖

10万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
106997
QQ
 楼主| 发表于 2020-11-17 10:54:07 | 显示全部楼层
fanwei700615 发表于 2020-11-17 10:47
大佬,这个上位机用的是什么软件啊

matlab
回复

使用道具 举报

0

主题

2

回帖

2

积分

新手上路

积分
2
发表于 2021-3-22 09:36:40 | 显示全部楼层
仔细看了一下代码“”V7-ADC定时器触发+DMA双缓冲实现”, 代码中有几处没有看明白,感觉逻辑上貌似说不通啊,恳请作者能够解疑答惑:
1.我先说一下我对作者程序的理解:
确实定时器触发速度是100KHz,即ADC的采样率也是100KHz, 意味着10us采样一次, 因为开了DMA循环模式,所以每次采样完了后DMA很快(us级)就进入半传输完成中断,接着也
很快(us级)进入传输完成中断,进入半传输完成中断时,DMA会将半传输搬运完成的ADC数字量放在ADCxValues[0]~ADCxValues[63],进入传输完成中断时,DMA会将传输搬运完成的ADC数字量放在ADCxValues[64]~ADCxValues[127],这也是程序中所谓的“双缓冲”,但是这两个缓冲切换时间在us级别啊,非常非常快, bsp_GetAdcValues()这个函数500ms执行一次,按照缓冲切换速度500ms内缓冲已经切换了几千次有吧,bsp_GetAdcValues()怎么能得到准确的ADC数据量呢????
这样的双缓冲有啥意义呢?程序和中断都忙不过来,因为缓冲切换速度非常非常非常快。
2.ADCxValues前半部和后半部都是64个uint16_t的元素吧,为何算ADC的值时只取前面4个元素呢?这又是啥逻辑呢???

算ADC的值得原始代码如下:
void bsp_GetAdcValues(void)
{
        uint32_t values;
        float  temp;
       
        /* 当前DMA操作是后半个缓冲,读取前半个缓冲的前4个数值求平均 */
        if(s_DmaFlag == 1)
        {
                DISABLE_INT();
                s_DmaFlag = 0;
                values = (ADCxValues[0] + ADCxValues[1] + ADCxValues[2] + ADCxValues[3])/4;

                ENABLE_INT();
        }
        /* 当前DMA操作是后前个缓冲,读取后半个缓冲的前4个数值求平均 */
        else if(s_DmaFlag == 2)
        {
                DISABLE_INT();
                s_DmaFlag = 0;
                values = (ADCxValues[64] + ADCxValues[65] + ADCxValues[66] + ADCxValues[67])/4;
                ENABLE_INT();
        }
       
        /* 打印读出的串口值 */
        temp = values *3.3 / 65536;
       
        printf("ADCxValues = %d, %5.3f\r\n", values, temp);
}

回复

使用道具 举报

1

主题

26

回帖

29

积分

新手上路

积分
29
发表于 2021-3-22 16:29:53 | 显示全部楼层
yeasang 发表于 2021-3-22 09:36
仔细看了一下代码“”V7-ADC定时器触发+DMA双缓冲实现”, 代码中有几处没有看明白,感觉逻辑上貌似说不通 ...

我觉得第一个问题主要是代码点数还比较少吧,如果像1024点这样的采集,全部传输结束以后再进行处理可能信号的时延就更严重了。
回复

使用道具 举报

56

主题

131

回帖

299

积分

高级会员

积分
299
发表于 2021-4-12 17:06:15 | 显示全部楼层
参照H7的例子,使用STM32G070实现定时器触发ADC转换数据,使用HAL_ADC_Start_IT方式可以,
但使用HAL_ADC_Start_DMA就不成功

static void MX_ADC1_Init(void)
{
        ADC_AnalogWDGConfTypeDef AnalogWDGConfig;
  /* USER CODE BEGIN ADC1_Init 0 */

  /* USER CODE END ADC1_Init 0 */

  ADC_ChannelConfTypeDef sConfig = {0};

  /* USER CODE BEGIN ADC1_Init 1 */

  /* USER CODE END ADC1_Init 1 */
  /** Configure the global features of the ADC (Clock, Resolution, Data Alignment and number of conversion)
  */
  hadc1.Instance = ADC1;
  hadc1.Init.ClockPrescaler = ADC_CLOCK_SYNC_PCLK_DIV2;//ADC_CLOCK_ASYNC_DIV1;//
  hadc1.Init.Resolution = ADC_RESOLUTION_12B;
  hadc1.Init.DataAlign = ADC_DATAALIGN_RIGHT;
  hadc1.Init.ScanConvMode = ADC_SCAN_DISABLE;//¶àí¨μàé¨Ãèòaê1Äü
  hadc1.Init.EOCSelection = ADC_EOC_SINGLE_CONV;
  hadc1.Init.LowPowerAutoWait = DISABLE;//μè′y×a»»Ä£ê½
  hadc1.Init.LowPowerAutoPowerOff = DISABLE;//×Ô¶ˉ1رÕÄ£ê½
  hadc1.Init.ContinuousConvMode = DISABLE;//μ¥′λòá¬Dø×a»»Ä£ê½
  hadc1.Init.NbrOfConversion = 1;//×a»»í¨μà3¸ö
  hadc1.Init.DiscontinuousConvMode = DISABLE;//2»á¬DøÄ£ê½
       
//        hadc1.Init.ExternalTrigConv = ADC_SOFTWARE_START;//ADC_SOFTWARE_START;//ADC_EXTERNALTRIG_T3_TRGO;//
//  hadc1.Init.ExternalTrigConvEdge = ADC_EXTERNALTRIGCONVEDGE_NONE;//ADC_EXTERNALTRIGCONVEDGE_NONE;//ADC_EXTERNALTRIGCONVEDGE_RISING;//
       
  hadc1.Init.ExternalTrigConv = ADC_EXTERNALTRIG_T6_TRGO;//ADC_SOFTWARE_START;//ADC_EXTERNALTRIG_T3_TRGO;//
  hadc1.Init.ExternalTrigConvEdge = ADC_EXTERNALTRIGCONVEDGE_RISING;//ADC_EXTERNALTRIGCONVEDGE_NONE;//ADC_EXTERNALTRIGCONVEDGE_RISING;//
       
  hadc1.Init.DMAContinuousRequests = DISABLE;
  hadc1.Init.Overrun = ADC_OVR_DATA_OVERWRITTEN;//òç3ö¸2¸Çêy¾Y
  hadc1.Init.SamplingTimeCommon1 = ADC_SAMPLETIME_1CYCLE_5;
  hadc1.Init.SamplingTimeCommon2 = ADC_SAMPLETIME_160CYCLES_5;
  hadc1.Init.OversamplingMode = DISABLE;//1y2éÑùÆ÷ê1Äü
        //hadc1.Init.OversamplingMode      = ENABLE;
  hadc1.Init.Oversampling.Ratio         = ADC_OVERSAMPLING_RATIO_16;
  hadc1.Init.Oversampling.RightBitShift = ADC_RIGHTBITSHIFT_4;
  hadc1.Init.Oversampling.TriggeredMode = ADC_TRIGGEREDMODE_SINGLE_TRIGGER;
  hadc1.Init.TriggerFrequencyMode = ADC_TRIGGER_FREQ_HIGH;
  if (HAL_ADC_Init(&hadc1) != HAL_OK)
  {
    Error_Handler();
  }
  /** Configure Regular Channel
  */
  sConfig.Channel = ADC_CHANNEL_4;
  sConfig.Rank = ADC_REGULAR_RANK_1;
  sConfig.SamplingTime = ADC_SAMPLINGTIME_COMMON_2;
  if (HAL_ADC_ConfigChannel(&hadc1, &sConfig) != HAL_OK)
  {
    Error_Handler();
  }
}



int main(void)
{
  /* USER CODE BEGIN 1 */
  uint32_t tmp_index_adc_converted_data = 0;
  /* 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_TIM3_Init();
  MX_DMA_Init();
  MX_ADC1_Init();
       
  /* USER CODE BEGIN 2 */
  for (tmp_index_adc_converted_data = 0; tmp_index_adc_converted_data < ADC_CONVERTED_DATA_BUFFER_SIZE; tmp_index_adc_converted_data++)
  {
    aADCxConvertedData[tmp_index_adc_converted_data] = VAR_CONVERTED_DATA_INIT_VALUE;
  }
  
  /* Initialize LED on board */
  BSP_LED_Init(LED4);

  /* Run the ADC calibration */
  if (HAL_ADCEx_Calibration_Start(&hadc1) != HAL_OK)
  {
    /* Calibration Error */
    Error_Handler();
  }
  /* USER CODE END 2 */

  /* Infinite loop */
  /* USER CODE BEGIN WHILE */
  if (HAL_TIM_Base_Start_IT(&htim3) != HAL_OK)
  {
    /* Counter enable error */
    Error_Handler();
  }
       
  /*## Start ADC conversions ###############################################*/
  /* Start ADC group regular conversion with DMA */
  if (HAL_ADC_Start_DMA(&hadc1,
                        (uint32_t *)aADCxConvertedData,
                        8,
                       ) != HAL_OK)
  {
    /* ADC conversion start error */
    Error_Handler();
  }
  
               
  while (1)
  {
                ;
}

}
回复

使用道具 举报

1万

主题

6万

回帖

10万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
106997
QQ
 楼主| 发表于 2021-4-12 17:25:50 | 显示全部楼层
lindahnu 发表于 2021-4-12 17:06
参照H7的例子,使用STM32G070实现定时器触发ADC转换数据,使用HAL_ADC_Start_IT方式可以,
但使用HAL_ADC_ ...

你的DMA配置在那里
回复

使用道具 举报

56

主题

131

回帖

299

积分

高级会员

积分
299
发表于 2021-4-12 17:28:36 | 显示全部楼层
eric2013 发表于 2021-4-12 17:25
你的DMA配置在那里

void HAL_ADC_MspInit(ADC_HandleTypeDef* hadc)
{
  GPIO_InitTypeDef GPIO_InitStruct = {0};
  if(hadc->Instance==ADC1)
  {
  /* USER CODE BEGIN ADC1_MspInit 0 */
  RCC_PeriphCLKInitTypeDef PeriphClkInit;

  PeriphClkInit.PeriphClockSelection = RCC_PERIPHCLK_ADC;
  PeriphClkInit.AdcClockSelection = RCC_ADCCLKSOURCE_SYSCLK;
  if (HAL_RCCEx_PeriphCLKConfig(&PeriphClkInit) != HAL_OK)
  {
    Error_Handler();
  }
  /* USER CODE END ADC1_MspInit 0 */
    /* Peripheral clock enable */
    __HAL_RCC_ADC_CLK_ENABLE();
  
    __HAL_RCC_GPIOA_CLK_ENABLE();
    /**ADC1 GPIO Configuration   
    PA4     ------> ADC1_IN4
    */
    GPIO_InitStruct.Pin = GPIO_PIN_4;
    GPIO_InitStruct.Mode = GPIO_MODE_ANALOG;
    GPIO_InitStruct.Pull = GPIO_NOPULL;
    HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);

    /* ADC1 DMA Init */
    /* ADC1 Init */
    hdma_adc1.Instance = DMA1_Channel1;
    hdma_adc1.Init.Request = DMA_REQUEST_ADC1;
    hdma_adc1.Init.Direction = DMA_PERIPH_TO_MEMORY;
    hdma_adc1.Init.PeriphInc = DMA_PINC_DISABLE;
    hdma_adc1.Init.MemInc = DMA_MINC_ENABLE;
    hdma_adc1.Init.PeriphDataAlignment = DMA_PDATAALIGN_HALFWORD;
    hdma_adc1.Init.MemDataAlignment = DMA_MDATAALIGN_HALFWORD;
    hdma_adc1.Init.Mode = DMA_CIRCULAR;
    hdma_adc1.Init.Priority = DMA_PRIORITY_HIGH;
    if (HAL_DMA_Init(&hdma_adc1) != HAL_OK)
    {
      Error_Handler();
    }

    __HAL_LINKDMA(hadc,DMA_Handle,hdma_adc1);

    /* ADC1 interrupt Init */
    HAL_NVIC_SetPriority(ADC1_IRQn, 0, 0);
    HAL_NVIC_EnableIRQ(ADC1_IRQn);
  /* USER CODE BEGIN ADC1_MspInit 1 */

  /* USER CODE END ADC1_MspInit 1 */
  }

}
回复

使用道具 举报

1万

主题

6万

回帖

10万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
106997
QQ
 楼主| 发表于 2021-4-12 18:25:21 | 显示全部楼层
lindahnu 发表于 2021-4-12 17:28
void HAL_ADC_MspInit(ADC_HandleTypeDef* hadc)
{
  GPIO_InitTypeDef GPIO_InitStruct = {0};

看着没啥问题了,将DMA中断打开,看看能周期性的进入DMA中断不,另外你使用的DMA通道是指定的吧
回复

使用道具 举报

56

主题

131

回帖

299

积分

高级会员

积分
299
发表于 2021-4-13 09:54:00 | 显示全部楼层
eric2013 发表于 2021-4-12 18:25
看着没啥问题了,将DMA中断打开,看看能周期性的进入DMA中断不,另外你使用的DMA通道是指定的吧

能进DMA中断了,进一次半传输中断再进一次完成中断,之后就只进timer中断了,DMA不再传输了,这是为什么呢?
回复

使用道具 举报

1

主题

35

回帖

38

积分

新手上路

积分
38
发表于 2023-3-16 00:28:43 来自手机 | 显示全部楼层
拜读,谢谢硬汉提供的资料
回复

使用道具 举报

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

本版积分规则

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

GMT+8, 2024-5-14 05:33 , Processed in 0.267583 second(s), 28 queries .

Powered by Discuz! X3.4 Licensed

Copyright © 2001-2023, Tencent Cloud.

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