硬汉嵌入式论坛

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

[ADC] STM32H750的3ADC采样问题

[复制链接]

21

主题

66

回帖

129

积分

初级会员

积分
129
发表于 2024-11-19 23:02:16 | 显示全部楼层 |阅读模式
当前准备用STM32H750的3个ADC分别对三个交流信号进行采样,请问:


1.是否可以通过一个定时器同时触发三个ADC去同步采样三个不同的交流信号?
2.三个ADC都开DMA并使用循环模式将的采样值推送到内存中?


目前测试通过定时器ADC_EXTERNALTRIG_T1_CC1好像只能触发ADC1和ADC2,ADC3无法没有动作,另外ADC1首次采样了几百个点后也停下来了,没有数据更新,只有ADC2能持续更新数据,请问大概可能是什么原因?
回复

使用道具 举报

1万

主题

7万

回帖

11万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
115490
QQ
发表于 2024-11-20 09:39:00 | 显示全部楼层
1、使用同一个定时器的不同CH通道去触发。
2、对。

方便的话,贴下你的配置看下。
回复

使用道具 举报

21

主题

66

回帖

129

积分

初级会员

积分
129
 楼主| 发表于 2024-11-20 23:07:39 | 显示全部楼层
本帖最后由 mojinpan 于 2024-11-20 23:23 编辑


现象:只有ADC2能周期触发,/ADC13都是只能触发一次(几百个点),后面就再也没有变化了


感觉想是DMA触发异常

回复

使用道具 举报

21

主题

66

回帖

129

积分

初级会员

积分
129
 楼主| 发表于 2024-11-20 23:11:48 | 显示全部楼层
对应代码如下:


[C] 纯文本查看 复制代码

初始化

ADC_dev  adc1 = {
    .adc      = ADC1,
    .ch[0]    = ADC_CH16,
    .ch[1]    = ADC_CH17,
    .ch_num   = 2,
    .buf.data = adc1_buf,
    .buf.len  = sizeof(adc1_buf)/2,
};

ADC_dev adc2 = {
    .adc      = ADC2,
    .ch[0]    = ADC_CH3,
    .ch[1]    = ADC_CH4,
    .ch_num   = 2,
    .buf.data = adc2_buf,
    .buf.len  = sizeof(adc2_buf)/2,
};

ADC_dev adc3 = {
    .adc      = ADC3,
    .ch[0]    = ADC_CH0,
    .ch[1]    = ADC_CH1,
    .ch_num   = 2,
    .buf.data = adc3_buf,
    .buf.len  = sizeof(adc3_buf)/2,
};


    ADC_Init(&adc1);
    ADC_Init(&adc2);
    ADC_Init(&adc3);
    ADC_InitTimer(&adc1,500);
    ADC_InitTimer(&adc2,500);
    ADC_InitTimer(&adc3,500);
	

获取数据

    SCB_InvalidateDCache_by_Addr((uint32_t *)(obj->cur.ch1.adc->buf.data),obj->cur.ch1.adc->buf.len*4 + 32);
    SCB_InvalidateDCache_by_Addr((uint32_t *)(obj->cur.ch3.adc->buf.data),obj->cur.ch3.adc->buf.len*4 + 32);
    SCB_InvalidateDCache_by_Addr((uint32_t *)(obj->tmp.adc->buf.data),obj->tmp.adc->buf.len*4 + 32);
    for (int i = 0; i < ADC_BUF_LEN; i=i+2)
    {
        UART_Printf(WAVE_UART,"%f,%f,%f,%f,%f,%f,%f\n",(float)i,
        (float)obj->cur.ch1.adc->buf.data[i],
        (float)obj->cur.ch1.adc->buf.data[i+1],
        (float)obj->cur.ch3.adc->buf.data[i],
        (float)obj->cur.ch3.adc->buf.data[i+1],
        (float)obj->tmp.adc->buf.data[i],
        (float)obj->tmp.adc->buf.data[i+1]
        );
    }





ADC.C
[C] 纯文本查看 复制代码
/*******************************************************************************
						Header Files 头文件
*******************************************************************************/
#include "bsp.h"
#include "adc.h"

/*******************************************************************************
						Macro Definition 宏定义
*******************************************************************************/

/*******************************************************************************
						Variable declarations 变量声明
*******************************************************************************/
//ADC通道
uint32_t AdcCh[] = {
ADC_CHANNEL_0 , ADC_CHANNEL_1 , ADC_CHANNEL_2 , ADC_CHANNEL_3 , ADC_CHANNEL_4 , 
ADC_CHANNEL_5 , ADC_CHANNEL_6 , ADC_CHANNEL_7 , ADC_CHANNEL_8 , ADC_CHANNEL_9 , 
ADC_CHANNEL_10, ADC_CHANNEL_11, ADC_CHANNEL_12, ADC_CHANNEL_13, ADC_CHANNEL_14, 
ADC_CHANNEL_15, ADC_CHANNEL_16, ADC_CHANNEL_17, ADC_CHANNEL_18, ADC_CHANNEL_19
};
//ADC 采样优先级
uint32_t ADCRank[] = {
ADC_REGULAR_RANK_1 , ADC_REGULAR_RANK_2 , ADC_REGULAR_RANK_3 , ADC_REGULAR_RANK_4 , 
ADC_REGULAR_RANK_5 , ADC_REGULAR_RANK_6 , ADC_REGULAR_RANK_7 , ADC_REGULAR_RANK_8 , 
ADC_REGULAR_RANK_9 , ADC_REGULAR_RANK_10, ADC_REGULAR_RANK_11, ADC_REGULAR_RANK_12,
ADC_REGULAR_RANK_13, ADC_REGULAR_RANK_14, ADC_REGULAR_RANK_15, ADC_REGULAR_RANK_16
};
//ADC1管脚
GPIO_TypeDef * ADC1Gpio[] = {
GPIOA, GPIOA, GPIOF, GPIOA, GPIOC, GPIOB, GPIOF, GPIOA, GPIOC, GPIOB,
GPIOC, GPIOC, GPIOC, GPIOC, GPIOA, GPIOA, GPIOA, GPIOA, GPIOA, GPIOA
};	
uint16_t	ADC1Pin[] = {
GPIO_PIN_0, GPIO_PIN_1, GPIO_PIN_11, GPIO_PIN_6, GPIO_PIN_4, GPIO_PIN_1, GPIO_PIN_12, GPIO_PIN_7, GPIO_PIN_5, GPIO_PIN_0,
GPIO_PIN_0, GPIO_PIN_1, GPIO_PIN_2 , GPIO_PIN_3, GPIO_PIN_2, GPIO_PIN_3, GPIO_PIN_0 , GPIO_PIN_1, GPIO_PIN_4, GPIO_PIN_5
};	
//ADC2管脚
GPIO_TypeDef * ADC2Gpio[] = {
GPIOA, GPIOA, GPIOF, GPIOA, GPIOC, GPIOB, GPIOF, GPIOA, GPIOC, GPIOB,
GPIOC, GPIOC, GPIOC, GPIOC, GPIOA, GPIOA, NULL , NULL , GPIOA, GPIOA
};	
uint16_t	ADC2Pin[] = {
GPIO_PIN_0, GPIO_PIN_1, GPIO_PIN_13, GPIO_PIN_6, GPIO_PIN_4, GPIO_PIN_1, GPIO_PIN_14, GPIO_PIN_7, GPIO_PIN_5, GPIO_PIN_0, 
GPIO_PIN_0, GPIO_PIN_1, GPIO_PIN_2 , GPIO_PIN_3, GPIO_PIN_2, GPIO_PIN_3, NULL       , NULL      , GPIO_PIN_4, GPIO_PIN_5
};
//ADC3管脚
GPIO_TypeDef * ADC3Gpio[] = {
GPIOC, GPIOC, GPIOF, GPIOF, GPIOF, GPIOF, GPIOF, GPIOF, GPIOF, GPIOF, 
GPIOC, GPIOC, GPIOC, GPIOH, GPIOH, GPIOH, GPIOH, NULL , NULL , NULL
};	
uint16_t	ADC3Pin[] = {
GPIO_PIN_2, GPIO_PIN_3, GPIO_PIN_9, GPIO_PIN_7, GPIO_PIN_5, GPIO_PIN_3, GPIO_PIN_10, GPIO_PIN_8, GPIO_PIN_6, GPIO_PIN_4, 
GPIO_PIN_8, GPIO_PIN_1, GPIO_PIN_2, GPIO_PIN_2, GPIO_PIN_3, GPIO_PIN_4, GPIO_PIN_5 , NULL      , NULL      , NULL
};

TIM_HandleTypeDef gTimer;

/** ****************************************************************************
* @brief  初始化adc的gpio
* @param dev 设备对象
*******************************************************************************/
static uint32_t ADC_IoInit(ADC_dev* dev, uint8_t idx)
{
	if(dev->adc == ADC1)
	{
		GPIO_Init(ADC1Gpio[idx], ADC1Pin[idx], GPIO_AN_PN_L);
	}
	else if(dev->adc == ADC2)
	{
		GPIO_Init(ADC2Gpio[idx], ADC2Pin[idx], GPIO_AN_PN_L);
	}
	else if (dev->adc == ADC3)
	{
		GPIO_Init(ADC3Gpio[idx], ADC3Pin[idx], GPIO_AN_PN_L);
	}
		
	return ADC_OK;	
}
/** ****************************************************************************
* @brief   获取adc当前count
*******************************************************************************/
uint32_t ADC_GetCount(ADC_dev *dev)
{
	uint32_t idx;
	idx = dev->buf.len - __HAL_DMA_GET_COUNTER(&dev->hdma_adc);
	return idx;
}
/** ****************************************************************************
* @brief   获取通道采样结果
*******************************************************************************/
void ADC_GetChVal(ADC_dev* dev, uint32_t* buf, uint32_t len, uint32_t ch)
{
    uint32_t idx1, idx2,rank,buflen;
    uint8_t i;
    buflen = dev->buf.len - (dev->buf.len % dev->ch_num);
    idx1 = ADC_GetCount(dev);
    idx2 =  (buflen + idx1 - len * dev->ch_num) - 1; //多减1防止拿到DMA推送不全的数据

	for(i = 0; i < dev->ch_num; i++)
	{
		if(dev->ch[i] == AdcCh[ch])
		break;
	}
    rank = i;
    while(idx2 % dev->ch_num != rank) idx2--;
    SCB_InvalidateDCache_by_Addr((uint32_t *)dev->buf.data,dev->buf.len *4 +32);

	for(uint32_t i=0; i < len;i++)
	{
		idx2 = idx2 % buflen;
		buf[i] = dev->buf.data[idx2];
		idx2 += dev->ch_num;
	}
}
/** ****************************************************************************
* @brief ADC初始化
* @param dev ADC对象
*******************************************************************************/
int ADC_InitDma(ADC_dev* dev)
{ 
    if(dev->adc == ADC1)
    {
        __HAL_RCC_DMA1_CLK_ENABLE();
        dev->hdma_adc.Instance      = DMA1_Stream0;
        dev->hdma_adc.Init.Request  = DMA_REQUEST_ADC1;
    }
    else if(dev->adc == ADC2)
    {
        __HAL_RCC_DMA1_CLK_ENABLE();
        dev->hdma_adc.Instance      = DMA1_Stream1;
        dev->hdma_adc.Init.Request  = DMA_REQUEST_ADC2;
    }
    else if(dev->adc == ADC3)
    {
        __HAL_RCC_BDMA_CLK_ENABLE();
        dev->hdma_adc.Instance      = BDMA_Channel0;
        dev->hdma_adc.Init.Request  = BDMA_REQUEST_ADC3;
    }
    dev->hdma_adc.Init.Direction            = DMA_PERIPH_TO_MEMORY;         //外设到内存
    dev->hdma_adc.Init.PeriphInc            = DMA_PINC_DISABLE;             //外设地址不递增
    dev->hdma_adc.Init.MemInc               = DMA_MINC_ENABLE;              //内存地址递增
    dev->hdma_adc.Init.PeriphDataAlignment  = DMA_PDATAALIGN_HALFWORD;      //外设数据宽度:字节
    dev->hdma_adc.Init.MemDataAlignment     = DMA_PDATAALIGN_HALFWORD;      //内存数据宽度:字节
    dev->hdma_adc.Init.Mode                 = DMA_CIRCULAR;                 //传输模式(循环)
    dev->hdma_adc.Init.Priority             = DMA_PRIORITY_MEDIUM;          //优先级
	dev->hdma_adc.Init.FIFOMode             = DMA_FIFOMODE_DISABLE;         //禁用fifo
    if (HAL_DMA_Init(&dev->hdma_adc) != HAL_OK)
    {
        ADC_ERR("ADC DMA init err!");
        return ADC_INIT_DMA_ERR;
    }
    __HAL_LINKDMA(&dev->hadc,DMA_Handle,dev->hdma_adc);

	return ADC_OK;
}
/** ****************************************************************************
* @brief  ADC通道初始化
* @param dev ADC对象
* @param ch ADC通道
* @param rank 采样顺序
*******************************************************************************/
int ADC_InitCh(ADC_dev* dev,uint8_t ch,uint32_t rank)
{
    ADC_ChannelConfTypeDef sConfig = {0};  

    ADC_IoInit(dev,ch);
    
    sConfig.Channel         = AdcCh[ch];                    //采样通道                          
    sConfig.Rank            = rank;                         //规则通道,即采样顺序
    sConfig.SamplingTime    = ADC_SAMPLETIME_8CYCLES_5;    //采样时间
    sConfig.SingleDiff      = ADC_SINGLE_ENDED;             //单端采样
    sConfig.OffsetNumber    = ADC_OFFSET_NONE;              //偏移校准
    sConfig.Offset = 0;
    if (HAL_ADC_ConfigChannel(&dev->hadc, &sConfig) != HAL_OK)
    {
        ADC_ERR("ADC CH init err!");
        return ADC_INIT_CH_ERR;
    }  
	return ADC_OK;
}
/** ****************************************************************************
* @brief 初始化ADC
*******************************************************************************/
int ADC_Init(ADC_dev* dev)
{
    RCC_PeriphCLKInitTypeDef RCC_PeriphClkInit;
    ADC_MultiModeTypeDef multimode = {0};
    uint16_t pll2m,pll2n,PLL2P;
    //根据外部晶振选择分频系数
    switch (HSE_VALUE)
    {
    case 25000000 : pll2m = 5;pll2n = 72;PLL2P = 10; break;
    case 24000000 : pll2m = 4;pll2n = 60;PLL2P = 10; break;
    case  8000000 : pll2m = 1;pll2n = 45;PLL2P = 10; break; 
    default: return -1;
    }
    //ADC设置为最高频率36MHz
    RCC_PeriphClkInit.PeriphClockSelection = RCC_PERIPHCLK_ADC;         //外设时钟
	RCC_PeriphClkInit.AdcClockSelection    = RCC_ADCCLKSOURCE_PLL2;        //ADC时钟
	RCC_PeriphClkInit.PLL2.PLL2FRACN       = 0;
	RCC_PeriphClkInit.PLL2.PLL2M           = pll2m;
	RCC_PeriphClkInit.PLL2.PLL2N           = pll2n;
	RCC_PeriphClkInit.PLL2.PLL2P           = PLL2P;
	RCC_PeriphClkInit.PLL2.PLL2RGE         = RCC_PLL2VCIRANGE_2;
	RCC_PeriphClkInit.PLL2.PLL2VCOSEL      = RCC_PLL2VCOWIDE;
	HAL_RCCEx_PeriphCLKConfig(&RCC_PeriphClkInit);

    //配置ADC
    HAL_ADC_DeInit(&(dev->hadc));

    if(dev->adc == ADC2)
    {
        __HAL_RCC_ADC12_CLK_ENABLE();
	    dev->hadc.Init.ExternalTrigConv = ADC_EXTERNALTRIG_T1_CC1;                              //触发源
    }
    else if(dev->adc == ADC1)
    {
        __HAL_RCC_ADC12_CLK_ENABLE();
	    dev->hadc.Init.ExternalTrigConv = ADC_EXTERNALTRIG_T1_CC2;                              //触发源
    }
    else
    {
        __HAL_RCC_ADC3_CLK_ENABLE();
	    dev->hadc.Init.ExternalTrigConv = ADC_EXTERNALTRIG_T1_CC3;                              //触发源
    }
    dev->hadc.Instance = dev->adc;
    dev->hadc.Init.ConversionDataManagement = ADC_CONVERSIONDATA_DMA_CIRCULAR;              //采样结果通过DMA传输到指定地址                   
    dev->hadc.Init.DiscontinuousConvMode = DISABLE;                                         //禁用不连续采样模式        
	dev->hadc.Init.ClockPrescaler = ADC_CLOCK_ASYNC_DIV1;                                   //ADC时钟不分频
	dev->hadc.Init.Resolution = ADC_RESOLUTION_16B;                                         //16位采样模式
	dev->hadc.Init.ScanConvMode = ((dev->ch_num < 2) ? ADC_SCAN_DISABLE : ADC_SCAN_ENABLE); //扫描模式(多通道模式)
	dev->hadc.Init.EOCSelection = ADC_EOC_SINGLE_CONV;                                      //转换结束标识(序列转换结束)
	dev->hadc.Init.LowPowerAutoWait = DISABLE;                                              //禁用低功耗等待模式
	dev->hadc.Init.ContinuousConvMode = DISABLE;                                            //禁用连续采样模式(由定时器单次触发)
	dev->hadc.Init.NbrOfConversion = dev->ch_num;                                           //规则采样通道数
	dev->hadc.Init.NbrOfDiscConversion = 1;                                                 //采样组数量
	dev->hadc.Init.ExternalTrigConvEdge = ADC_EXTERNALTRIGCONVEDGE_RISING;                  //触发类型
	dev->hadc.Init.Overrun = ADC_OVR_DATA_OVERWRITTEN;                                      //数据溢出处理方式(覆盖写入)
	dev->hadc.Init.LeftBitShift = ADC_LEFTBITSHIFT_NONE;                                    //ADC转换结果左移位数
	dev->hadc.Init.OversamplingMode = DISABLE;                                               //使能过采样
	dev->hadc.Init.Oversampling.Ratio = 16;                                                 //16x过采样
    dev->hadc.Init.Oversampling.RightBitShift = ADC_RIGHTBITSHIFT_4;                        //采样结果/16获得平均值
    dev->hadc.Init.Oversampling.TriggeredMode = ADC_TRIGGEREDMODE_SINGLE_TRIGGER;           //触发模式(单次触发)
	dev->hadc.Init.Oversampling.OversamplingStopReset = ADC_REGOVERSAMPLING_RESUMED_MODE; //过采样被中断的处理方案(保持缓冲区)

	if (HAL_ADC_Init(&(dev->hadc)) != HAL_OK)
	{
		ADC_DBUG("ADC Init error!");
		return ADC_INIT_ERR;
	}

	//配置ADC通道
    for(int i=0;i<dev->ch_num;i++)
    {
        ADC_InitCh(dev,dev->ch[i],ADCRank[i]);
    }
    //启动ADC
    if (HAL_ADCEx_Calibration_Start(&dev->hadc,ADC_CALIB_OFFSET, ADC_SINGLE_ENDED) !=  HAL_OK)
    {
        ADC_ERR("ADC adj err!");
        return ADC_INIT_ERR;
    }
    //设置DMA
    ADC_InitDma(dev);
    //DMA启动后续进一步设置定时器才会真正开始采样
    HAL_ADC_Start_DMA(&dev->hadc,(uint32_t*)dev->buf.data,dev->buf.len);

    return ADC_OK;

}

/** ****************************************************************************
* @brief  初始化adc的定时器
* @Freq 采样频率(Hz)
*******************************************************************************/
int ADC_InitTimer(ADC_dev* dev,uint32_t Freq)
{
    TIM_OC_InitTypeDef sConfig = {0};	
    RCC_ClkInitTypeDef fclk = {0};
    uint32_t latency; //flash延迟,仅用于满足函数接口,本函数用不上  
    uint32_t clk = 0;
    uint32_t div = 0;
    uint16_t Period;

       if(dev->adc == ADC2)
    {
        __HAL_RCC_TIM1_CLK_ENABLE();
        gTimer.Instance               = TIM1;
    }

    else if(dev->adc == ADC1)
    {
        __HAL_RCC_TIM1_CLK_ENABLE();
        gTimer.Instance               = TIM1;
    }
    else
    {
         __HAL_RCC_TIM1_CLK_ENABLE();
        gTimer.Instance               = TIM1;
    } 
    HAL_RCC_GetClockConfig(&fclk, &latency);  
    clk = HAL_RCC_GetPCLK1Freq() *(fclk.APB1CLKDivider== RCC_HCLK_DIV1 ? 1 : 2);

	//计算定时器分频和重载计数
	div =  (clk / ((0xFFFF-1U) * Freq)) +1;
    Period = ((clk / (div * Freq)) - 1);
    gTimer.Init.Period            = Period;
    gTimer.Init.Prescaler         = div-1;
    gTimer.Init.ClockDivision     = TIM_CLOCKDIVISION_DIV1;
    gTimer.Init.CounterMode       = TIM_COUNTERMODE_UP;
    gTimer.Init.RepetitionCounter = 0x0;                                                   //重复计数器,每次溢出-1,至0时触发定时事件
    gTimer.Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_ENABLE;                        //自动重载模式(立刻生效)
	if (HAL_TIM_PWM_Init(&gTimer) != HAL_OK)
	{
        ADC_ERR("ADC timer init err!");
        return ADC_INIT_TIMER_ERR;
	}

	/* 配置定时器PWM输出通道 */
    sConfig.OCMode       = TIM_OCMODE_PWM1;
	sConfig.OCPolarity   = TIM_OCPOLARITY_HIGH;
	sConfig.OCFastMode   = TIM_OCFAST_DISABLE;
	sConfig.OCNPolarity  = TIM_OCNPOLARITY_HIGH;
	sConfig.OCNIdleState = TIM_OCNIDLESTATE_RESET;
	sConfig.OCIdleState  = TIM_OCIDLESTATE_RESET;
	sConfig.Pulse = Period; // 50%占空比

    if(dev->adc == ADC2)
    {
        HAL_TIM_PWM_ConfigChannel(&gTimer, &sConfig, TIM_CHANNEL_1);
        HAL_TIM_PWM_Start(&gTimer, TIM_CHANNEL_1);
    }
    else if(dev->adc == ADC1)
    {
        HAL_TIM_PWM_ConfigChannel(&gTimer, &sConfig, TIM_CHANNEL_2);
        HAL_TIM_PWM_Start(&gTimer, TIM_CHANNEL_2);
    }
    else
    {
        HAL_TIM_PWM_ConfigChannel(&gTimer, &sConfig, TIM_CHANNEL_3);
        HAL_TIM_PWM_Start(&gTimer, TIM_CHANNEL_3);
    }
    return ADC_OK;
}
/** ****************************************************************************
* @brief  ADC停止采样
*******************************************************************************/
void ADC_Stop(void)
{
    HAL_TIM_PWM_Stop(&gTimer,TIM_CHANNEL_1);
}
/** ****************************************************************************
* @brief  ADC开始采样
*******************************************************************************/
void ADC_Start(void)
{
    HAL_TIM_PWM_Start(&gTimer,TIM_CHANNEL_1); 
}


ADC.h
[C] 纯文本查看 复制代码
#ifndef __ADC_H
#define	__ADC_H

/*******************************************************************************
                        Header Files 头文件
*******************************************************************************/
#include <stdio.h> 
#include "ctype.h"

/*******************************************************************************
                        Macro Definition 宏定义
*******************************************************************************/

#define ADC_Assert(expr)        UlogAssert(expr,while(1))
#define ADC_ERR(fmt,...)        ULOG_E(fmt,##__VA_ARGS__)
#define ADC_WRNG(fmt,...)       ULOG_W(fmt,##__VA_ARGS__)
#define ADC_INFO(fmt,...)       ULOG_I(fmt,##__VA_ARGS__)
#define ADC_DBUG(fmt,...)       ULOG_D(fmt,##__VA_ARGS__)

/*******************************************************************************
                        Type declaration 类型声明
********************************************************************************/
/// ADC错误代码
typedef enum
{
	ADC_OK			    =  0,
	ADC_INIT_ERR	    = -1,	
	ADC_INIT_CH_ERR	    = -2,
	ADC_INIT_AWDOG_ERR	= -3,
	ADC_INIT_DMA_ERR	= -4,
	ADC_INIT_TIMER_ERR	= -5,
}ADC_Err;
/// ADC通道代码(最大通道数量虽然有20个通道,但是常规转换顺序只有1~16)
typedef enum
{
	ADC_CH0,
	ADC_CH1,
	ADC_CH2,	
	ADC_CH3,
	ADC_CH4,
	ADC_CH5,
	ADC_CH6,
	ADC_CH7,
	ADC_CH8,
	ADC_CH9,
	ADC_CH10,
	ADC_CH11, 
	ADC_CH12,
	ADC_CH13,
	ADC_CH14,
	ADC_CH15,
	ADC_CH16,
	ADC_CH17,
	ADC_CH18,
	ADC_CH19,
    ADC_CH_MAX_NUM,
}ADC_Ch;

typedef struct adc_dev
{
    ADC_TypeDef*    adc;
    uint32_t ch[ADC_CH_MAX_NUM];      //ADC通道配置
    uint8_t ch_num;                   //ADC通道数量 
    ADC_HandleTypeDef hadc;
    DMA_HandleTypeDef hdma_adc; 
	struct							 //环形buf									
	{
        uint16_t*	data;	
        size_t      len;
	}buf;  
}ADC_dev;

/*******************************************************************************
                                Function declaration 函数声明
*******************************************************************************/
int ADC_Init(ADC_dev* dev);
int ADC_InitTimer(ADC_dev* dev,uint32_t Freq);
void ADC_Stop(void);
void ADC_Start(void);
void ADC_GetChVal(ADC_dev* dev, uint32_t* buf, uint32_t len, uint32_t ch);

#endif


执行过程


回复

使用道具 举报

21

主题

66

回帖

129

积分

初级会员

积分
129
 楼主| 发表于 2024-11-20 23:38:30 | 显示全部楼层
花了三天时间发现问题了MA通道和UART冲突,导致DMA工作异常
回复

使用道具 举报

1万

主题

7万

回帖

11万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
115490
QQ
发表于 2024-11-21 10:14:34 | 显示全部楼层
mojinpan 发表于 2024-11-20 23:38
花了三天时间发现问题了MA通道和UART冲突,导致DMA工作异常

回复

使用道具 举报

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

本版积分规则

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

GMT+8, 2025-4-28 20:05 , Processed in 0.544079 second(s), 25 queries .

Powered by Discuz! X3.4 Licensed

Copyright © 2001-2023, Tencent Cloud.

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