硬汉嵌入式论坛

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

[ADC] STM32H7三个ADC,每个ADC三个通道,要如何实现同步采集?

[复制链接]

5

主题

16

回帖

31

积分

新手上路

积分
31
发表于 2024-1-31 10:08:39 | 显示全部楼层 |阅读模式
使用STM32H7系列,使用ADC1、ADC2、和ADC3,其中每个ADC各使用两个通道,共三个ADC 六个通道,使用定时器触发,DMA双缓冲传输,如何实现多通道数的同步采样?
回复

使用道具 举报

1万

主题

7万

回帖

11万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
117546
QQ
发表于 2024-1-31 10:20:50 | 显示全部楼层
使用同一个定时器的三个CC通道。这样就保证同步了。

另外每个ADC的两个通道是依次采集的,不是同步的,注意这点。
回复

使用道具 举报

11

主题

123

回帖

156

积分

初级会员

积分
156
发表于 2024-1-31 13:40:49 | 显示全部楼层
硬汉哥您好,看您的建议是用同一个定时器的三个CC通道, 为何不是同一个定时器的同一个CC通道? 我看CUBEMX可以这么配置,这里用不同的CC通道是有什么具体原因吗? 我用LPTIM的同一个信号触发,还是没有同步起来。多谢!
回复

使用道具 举报

1万

主题

7万

回帖

11万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
117546
QQ
发表于 2024-1-31 14:14:51 | 显示全部楼层
szjdb 发表于 2024-1-31 13:40
硬汉哥您好,看您的建议是用同一个定时器的三个CC通道, 为何不是同一个定时器的同一个CC通道? 我看CUBEMX ...

同一个不知道行不行,我没实测。

我一直是三个CC,这个是确定可以的。
回复

使用道具 举报

5

主题

16

回帖

31

积分

新手上路

积分
31
 楼主| 发表于 2024-2-2 17:25:07 | 显示全部楼层
eric2013 发表于 2024-1-31 10:20
使用同一个定时器的三个CC通道。这样就保证同步了。

另外每个ADC的两个通道是依次采集的,不是同步的, ...

硬汉哥我还有个疑问,三个ADC采集的数据放置在三个Buffer中,那么我如何能实现这三个buffer中的数据同步传输到上位机中呢?如果使用usb VCP传输的话,会不会造成三个buffer数据之间的迟滞?
回复

使用道具 举报

1万

主题

7万

回帖

11万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
117546
QQ
发表于 2024-2-3 08:17:13 | 显示全部楼层
langlangago 发表于 2024-2-2 17:25
硬汉哥我还有个疑问,三个ADC采集的数据放置在三个Buffer中,那么我如何能实现这三个buffer中的数据同步 ...

这就看你ADC最大数据量和USB最大传输速度了。

比如你每秒ADC是10KB,那USB完全无压力。
回复

使用道具 举报

2

主题

4

回帖

10

积分

新手上路

积分
10
发表于 2024-2-7 11:24:57 | 显示全部楼层
可以使用ADC1和ADC2的双ADC常规同步模式,但H7不支持三ADC同步模式,如下图描述

回复

使用道具 举报

1万

主题

7万

回帖

11万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
117546
QQ
发表于 2024-2-13 14:56:11 | 显示全部楼层
taokingfly 发表于 2024-2-7 11:24
可以使用ADC1和ADC2的双ADC常规同步模式,但H7不支持三ADC同步模式,如下图描述

三ADC要使用同一个定时器的CC1,CC2,CC3触发ADC1,ADC2和ADC3来实现。
回复

使用道具 举报

4

主题

12

回帖

24

积分

新手上路

积分
24
发表于 2025-2-18 13:00:36 | 显示全部楼层
eric2013 发表于 2024-2-13 14:56
三ADC要使用同一个定时器的CC1,CC2,CC3触发ADC1,ADC2和ADC3来实现。

管理员您好,我是小白,想请问一下具体该如何在cubemx上配置呢,你如果有时间大体说一下就好,还有一个问题就是3个CC通道触发三个ADC是说单次触发ADC连续采集还是CC通道控制ADC的每次采样呢?谢谢
回复

使用道具 举报

1万

主题

7万

回帖

11万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
117546
QQ
发表于 2025-2-18 15:38:31 | 显示全部楼层
你吃大葱吗 发表于 2025-2-18 13:00
管理员您好,我是小白,想请问一下具体该如何在cubemx上配置呢,你如果有时间大体说一下就好,还有一个问 ...

我们一代示波器的bsp_adc.c文件是采样的这种方式定义的。

https://forum.anfulai.cn/forum.p ... &extra=page%3D1

CubeMX里面的设置,我没弄过。
回复

使用道具 举报

4

主题

12

回帖

24

积分

新手上路

积分
24
发表于 2025-2-18 16:25:19 | 显示全部楼层
本帖最后由 你吃大葱吗 于 2025-2-18 18:58 编辑
eric2013 发表于 2025-2-18 15:38
我们一代示波器的bsp_adc.c文件是采样的这种方式定义的。

https://forum.anfulai.cn/forum.php?mod=viewt ...

好的,谢谢您的回复,可能我的表述不太清楚,我想问一下output compare还是PWM?
回复

使用道具 举报

1万

主题

7万

回帖

11万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
117546
QQ
发表于 2025-2-19 05:30:26 | 显示全部楼层
你吃大葱吗 发表于 2025-2-18 16:25
好的,谢谢您的回复,可能我的表述不太清楚,我想问一下output compare还是PWM?

用的OC
回复

使用道具 举报

4

主题

12

回帖

24

积分

新手上路

积分
24
发表于 2025-2-19 12:25:57 | 显示全部楼层

好的,谢谢您
回复

使用道具 举报

4

主题

12

回帖

24

积分

新手上路

积分
24
发表于 2025-2-19 20:28:28 | 显示全部楼层

管理员您好,请问您是用的OC的哪种模式呢,是toggle on match还是OPM1或2呢,如果您知道还希望您告诉我,我真的很需要答案,谢谢您
回复

使用道具 举报

5

主题

162

回帖

177

积分

初级会员

积分
177
发表于 2025-2-19 23:15:50 | 显示全部楼层
你吃大葱吗 发表于 2025-2-19 20:28
管理员您好,请问您是用的OC的哪种模式呢,是toggle on match还是OPM1或2呢,如果您知道还希望您告诉我, ...

OC no output,然后是toggle on match(只要是能触发就行)。关键的地方是每个通道的PWM占空比要合理的在一个周期内完整的触发ADC
回复

使用道具 举报

1万

主题

7万

回帖

11万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
117546
QQ
发表于 2025-2-20 06:37:45 | 显示全部楼层
你吃大葱吗 发表于 2025-2-19 20:28
管理员您好,请问您是用的OC的哪种模式呢,是toggle on match还是OPM1或2呢,如果您知道还希望您告诉我, ...

原始代码
[C] 纯文本查看 复制代码
/*
*********************************************************************************************************
*	函 数 名: TIM1_Config
*	功能说明: 配置定时器1,用于触发ADC1,ADC2和ADC3。
*             当外部触发信号被选为ADC规则或注入转换时,只有它的上升沿可以启动转换。
*	形    参: 无
*	返 回 值: 无
*********************************************************************************************************
*/
static void TIM1_Config(void)
{
    TIM_TimeBaseInitTypeDef  TIM_TimeBaseStructure;
    TIM_OCInitTypeDef  TIM_OCInitStructure;
    
	/* 使能定时器1 */
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_TIM1, ENABLE);	
    
	/* 先禁能再配置 */
    TIM_Cmd(TIM1, DISABLE);	
	
    /*
     ********************************************************************************
    system_stm32f4xx.c 文件中 void SetSysClock(void) 函数对时钟的配置如下:

    HCLK = SYSCLK / 1     (AHB1Periph)
    PCLK2 = HCLK / 2      (APB2Periph)
    PCLK1 = HCLK / 4      (APB1Periph)

    因为APB1 prescaler != 1, 所以 APB1上的TIMxCLK = PCLK1 x 2 = SystemCoreClock / 2;
    因为APB2 prescaler != 1, 所以 APB2上的TIMxCLK = PCLK2 x 2 = SystemCoreClock;

    APB1 定时器有 TIM2, TIM3 ,TIM4, TIM5, TIM6, TIM7, TIM12, TIM13, TIM14
    APB2 定时器有 TIM1, TIM8 ,TIM9, TIM10, TIM11
          
    TIM1 更新周期是 = TIM1CLK / (TIM_Period + 1)/(TIM_Prescaler + 1)
    ********************************************************************************
    */
    TIM_TimeBaseStructInit(&TIM_TimeBaseStructure); 	                                   //初始化定时器1的寄存器为复位值
    TIM_TimeBaseStructure.TIM_Period =  168000000/g_SampleFreqTable[TimeBaseId][0] - 1;    //ARR自动重装载寄存器周期的值(定时时间)到设置频率后产生个更新或者中断(也是说定时时间到)
    TIM_TimeBaseStructure.TIM_Prescaler = g_SampleFreqTable[TimeBaseId][1]-1;   		   //PSC时钟预分频数 例如:时钟频率=TIM1CLK/(时钟预分频+1)
    TIM_TimeBaseStructure.TIM_ClockDivision = 0x0;    	            //CR1->CKD时间分割值
    TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;     //CR1->CMS[1:0]和DIR定时器模式 向上计数
	TIM_TimeBaseStructure.TIM_RepetitionCounter = 0x0000;		    /* TIM1 和 TIM8 必须设置 */	
    TIM_TimeBaseInit(TIM1, &TIM_TimeBaseStructure);

    /**************ADC1的触发***********************************************/
    TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1; 				   //CCMR2在向上计数时,一旦TIMx_CNT<TIMx_CCR1时通道1为有效电平,否则为无效电平
    TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;      //CCER 输出使能          
    TIM_OCInitStructure.TIM_Pulse = TIM_TimeBaseStructure.TIM_Period/3;//CCR3同计数器TIMx_CNT的比较,并在OC1端口上产生输出信号 
    TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_Low;    	   //CCER输出极性设置
    TIM_OCInitStructure.TIM_OutputNState = TIM_OutputNState_Enable;	   /* only for TIM1 and TIM8. 此处和正相引脚不同 */	
	TIM_OCInitStructure.TIM_OCNPolarity = TIM_OCNPolarity_High;		   /* only for TIM1 and TIM8. */		 
	TIM_OCInitStructure.TIM_OCIdleState = TIM_OCIdleState_Reset;	   /* only for TIM1 and TIM8. */
	TIM_OCInitStructure.TIM_OCNIdleState = TIM_OCNIdleState_Reset;	   /* only for TIM1 and TIM8. */	
	TIM_OC1Init(TIM1, &TIM_OCInitStructure);
	
	 /**************ADC2的触发***********************************************/
	TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1; 				  
    TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;     
    TIM_OCInitStructure.TIM_Pulse = TIM_TimeBaseStructure.TIM_Period*2/3;
    TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_Low;
    TIM_OCInitStructure.TIM_OutputNState = TIM_OutputNState_Enable;	   /* only for TIM1 and TIM8. 此处和正相引脚不同 */	
	TIM_OCInitStructure.TIM_OCNPolarity = TIM_OCNPolarity_High;		   /* only for TIM1 and TIM8. */		 
	TIM_OCInitStructure.TIM_OCIdleState = TIM_OCIdleState_Reset;	   /* only for TIM1 and TIM8. */
	TIM_OCInitStructure.TIM_OCNIdleState = TIM_OCNIdleState_Reset;	   /* only for TIM1 and TIM8. */		
    TIM_OC2Init(TIM1, &TIM_OCInitStructure);
	
	/**************ADC3的触发***********************************************/
	TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1; 				  
    TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;     
    TIM_OCInitStructure.TIM_Pulse = TIM_TimeBaseStructure.TIM_Period-1;
    TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_Low; 
    TIM_OCInitStructure.TIM_OutputNState = TIM_OutputNState_Enable;	   /* only for TIM1 and TIM8. 此处和正相引脚不同 */	
	TIM_OCInitStructure.TIM_OCNPolarity = TIM_OCNPolarity_High;		   /* only for TIM1 and TIM8. */		 
	TIM_OCInitStructure.TIM_OCIdleState = TIM_OCIdleState_Reset;	   /* only for TIM1 and TIM8. */
	TIM_OCInitStructure.TIM_OCNIdleState = TIM_OCNIdleState_Reset;	   /* only for TIM1 and TIM8. */		
    TIM_OC3Init(TIM1, &TIM_OCInitStructure);
    //TIM_OC3PreloadConfig(TIM1, TIM_OCPreload_Enable);		//CMR2 设置预装载使能  更新事件产生时写入有效
    //TIM_ARRPreloadConfig(TIM1, ENABLE);		   		 	//CR1  设置ARR自动重装 更新事件产生时写入有效
    TIM_Cmd(TIM1, ENABLE);	
	
    /* 使能PWM输出 */	
    TIM_CtrlPWMOutputs(TIM1, ENABLE);  		
}
回复

使用道具 举报

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

本版积分规则

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

GMT+8, 2025-8-14 07:49 , Processed in 0.119749 second(s), 24 queries .

Powered by Discuz! X3.4 Licensed

Copyright © 2001-2023, Tencent Cloud.

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