硬汉嵌入式论坛

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

[STM32H7] STM32H743定时器触发ADC,最高采样率测得只有1MHz的问题

[复制链接]

6

主题

24

回帖

42

积分

新手上路

积分
42
发表于 2025-2-24 13:14:20 | 显示全部楼层 |阅读模式
有没有老哥告诉我一下哪里出问题了,研究了好久,都是发现16bit的时候采样率最高1MHz,12bit的时候才有2MHz,不应该呀。下面就是主要代码:




#include "main.h"
#include "adc.h"
#include "dac.h"
#include "dma.h"
#include "memorymap.h"
#include "spi.h"
#include "tim.h"
#include "usart.h"
#include "gpio.h"
#include "fmc.h"

/* Private includes ----------------------------------------------------------*/
/* USER CODE BEGIN Includes */

/* USER CODE END Includes */

/* Private typedef -----------------------------------------------------------*/
/* USER CODE BEGIN PTD */

/******* ADC *******/
uint32_t ADC_SamplingRate;                                                                                                                        /* 期望采样率,单位:Hz */
uint32_t ADC_DMA_Buffer_A[ADC_DMA_SAMPLE_LENGTH];                                /* DMA缓冲A */
uint32_t ADC_DMA_Buffer_B[ADC_DMA_SAMPLE_LENGTH];                                /* DMA缓冲B */
uint32_t ADC_DMA_intData[ADC_DMA_SAMPLE_LENGTH];                                /* 定义ADC整形数据存储数组 */
float32_t ADC_DMA_floatData[ADC_DMA_SAMPLE_LENGTH];                        /* 定义ADC浮点数据存储数组 */
float32_t ADC_DMA_Windowed_Data[ADC_DMA_SAMPLE_LENGTH];        /* 定义ADC加窗后数据存储数组 */
uint8_t ADC_Active_Buffer_Flag;                                                                                                 /* 当前活动缓冲区标志 */
uint8_t Last_Completed_Buffer_Flag;                                                                                        /* 上一次完成的DMA缓冲区 */
unsigned char ADC_ConvEnd_Flag;                                                                                                        /* ADC采集结束标志位 */

//struct  compx s[MAX_FFT_N];
/* USER CODE END PTD */

/* Private define ------------------------------------------------------------*/
/* USER CODE BEGIN PD */

/* USER CODE END PD */

/* Private macro -------------------------------------------------------------*/
/* USER CODE BEGIN PM */

/* USER CODE END PM */

/* Private variables ---------------------------------------------------------*/

/* USER CODE BEGIN PV */

/* USER CODE END PV */

/* Private function prototypes -----------------------------------------------*/
void SystemClock_Config(void);
void PeriphCommonClock_Config(void);
static void MPU_Config(void);
/* USER CODE BEGIN PFP */

/* USER CODE END PFP */

/* Private user code ---------------------------------------------------------*/
/* USER CODE BEGIN 0 */

/* TIMER3时钟频率为200MHz
* PSC:2        ARR:10
* 分频后时钟为:10MHz
*
* 调整采样率:增大则可扩大频谱谱长
* 调整FFT运算点数:增大则可提高运算精度
*
* 最好就是通过按键去调节采样率,以及采样的点数,可以根据实际需要去设置
* 常用的采样率:{500000、200000、100000、50000、20000、10000、5000、2000、1000、500、200},可以通过数组索引来使用
* 要想使用以上方法得到以上采样率,那么PSC必须使得时钟频率位1MHz
*
*/
void HAL_ADC_ConvCpltCallback(ADC_HandleTypeDef* hadc)
{
        if(hadc->Instance == ADC1){
                HAL_ADC_Stop_DMA(&hadc1);                // 停止DMA以防止数据覆盖
                Last_Completed_Buffer_Flag = ADC_Active_Buffer_Flag; // 保存当前完成的缓冲区
                ADC_Active_Buffer_Flag ^= 1; // 切换缓冲区               
                ADC_ConvEnd_Flag = 1;        /* ADC采集DMA搬运结束标志位置一*/
               
                if (ADC_Active_Buffer_Flag == 0){
                        HAL_ADC_Start_DMA(&hadc1, (uint32_t*)ADC_DMA_Buffer_A, ADC_DMA_SAMPLE_LENGTH);
                }else{
                        HAL_ADC_Start_DMA(&hadc1, (uint32_t*)ADC_DMA_Buffer_B, ADC_DMA_SAMPLE_LENGTH);
                }
                if(Last_Completed_Buffer_Flag == 1){
                        for(int i=0;i<ADC_DMA_SAMPLE_LENGTH;i++)
                        ADC_DMA_intData[i] = ADC_DMA_Buffer_B[i];
                }else{
                        for(int i=0;i<ADC_DMA_SAMPLE_LENGTH;i++)
                        ADC_DMA_intData[i] = ADC_DMA_Buffer_A[i];
                }
        }
}

/* USER CODE END 0 */

/**
  * @brief  The application entry point.
  * @retval int
  */
int main(void)
{

  /* USER CODE BEGIN 1 */

  /* USER CODE END 1 */

  /* MPU Configuration--------------------------------------------------------*/
  MPU_Config();

  /* Enable the CPU Cache */

  /* Enable I-Cache---------------------------------------------------------*/
  SCB_EnableICache();

  /* Enable D-Cache---------------------------------------------------------*/
  SCB_EnableDCache();

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

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

  /* USER CODE BEGIN Init */
  delay_init(400);                /* 延时函数初始化 主频:400MHz */
  /* USER CODE END Init */

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

  /* Configure the peripherals common clocks */
  PeriphCommonClock_Config();

  /* USER CODE BEGIN SysInit */

  /* USER CODE END SysInit */

  /* Initialize all configured peripherals */
  MX_GPIO_Init();
  MX_DMA_Init();
  MX_USART1_UART_Init();
  MX_TIM6_Init();
  MX_USART2_UART_Init();
  MX_DAC1_Init();
  MX_ADC1_Init();
  MX_TIM3_Init();
  MX_TIM7_Init();
  MX_FMC_Init();
  MX_SPI4_Init();
  /* USER CODE BEGIN 2 */
        /***** ADC *****/
        ADC_SamplingRate = Set_SamplingRate(&htim3,200000000,1000000);                                                                                /* 必须要在定时器启动前进行设置!*/
  delay_ms(20);                                                                                                                                                                                                                                                                                /* 给ADC时间校准 */
  HAL_ADCEx_Calibration_Start(&hadc1, ADC_CALIB_OFFSET, ADC_SINGLE_ENDED);                                /* ADC 校准 */
  HAL_ADC_Start_DMA(&hadc1,(uint32_t*)&ADC_DMA_Buffer_A, ADC_DMA_SAMPLE_LENGTH);        /* 启动DMA转换ADC_DMA_SAMPLE_LENGTH次,完成后回调callback */
  HAL_TIM_Base_Start(&htim3);                                                                                                                                                                                                                /* 启动定时器3 */
  Set_Current_USART(USART1_IDX);
       
  /* USER CODE END 2 */

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

    /* USER CODE BEGIN 3 */
  }

  /* USER CODE END 3 */
}

哪里出问题了呀


ADC1IN3的配置

ADC1IN3的配置

DMA配置

DMA配置

开启DMA中断

开启DMA中断
回复

使用道具 举报

1万

主题

7万

回帖

11万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
116226
QQ
发表于 2025-2-24 14:27:09 | 显示全部楼层
最关键的一条,楼主的用的那个具体那个型号H743和封装。

不同封装的最大速度是不同的。
回复

使用道具 举报

6

主题

24

回帖

42

积分

新手上路

积分
42
 楼主| 发表于 2025-2-28 18:27:01 | 显示全部楼层
eric2013 发表于 2025-2-24 14:27
最关键的一条,楼主的用的那个具体那个型号H743和封装。

不同封装的最大速度是不同的。

谢谢回答,我知道了,就是因为V版和Y版芯片的ADC的时钟区别有一个二分频,搞得我最高才1.8M
回复

使用道具 举报

1

主题

4

回帖

7

积分

新手上路

积分
7
发表于 2025-5-24 08:23:09 | 显示全部楼层
请问你是用TIM TRGO单次触发ADC+DMA转运的模式吗?这样ADC(采样+转换)的频率最高能到多少?我的到1.6MHz就上不去了,也不知为啥。
回复

使用道具 举报

1万

主题

7万

回帖

11万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
116226
QQ
发表于 2025-5-25 08:56:12 | 显示全部楼层
wangzz 发表于 2025-5-24 08:23
请问你是用TIM TRGO单次触发ADC+DMA转运的模式吗?这样ADC(采样+转换)的频率最高能到多少?我的到1.6MHz ...

注意这个问题

STM32H7中ADC功能被ST玩出花,现在分直接通道,快速通道和慢速通道,不同封装最高速不同, LQFP封装速度最低
https://www.armbbs.cn/forum.php?mod=viewthread&tid=97343
回复

使用道具 举报

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

本版积分规则

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

GMT+8, 2025-6-10 15:48 , Processed in 0.275105 second(s), 28 queries .

Powered by Discuz! X3.4 Licensed

Copyright © 2001-2023, Tencent Cloud.

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