STM32G030C8T6 使用(LL库)配置初始化ADC DMA传输后,DR正常,DMA数据错误

使用stm32G030C8T6芯片,配置ADC的DMA传输,ADC的DR寄存器数据正确,DMA数据错误
下面是配置代码

#if ADC_CONFIG_ENABLE
#define ADC_CHANNEL_COUN 1
#define ADC_ADD_COUN 1
#define ADC_DATA_COUNTER 1
#define CHANNEL        4
#define ADC_DELAY_CALIB_ENABLE_CPU_CYCLES  (LL_ADC_DELAY_CALIB_ENABLE_ADC_CYCLES * 32)
struct
{
        vu32 DataTemp[ADC_CHANNEL_COUN];
        vu16 DataCouter[ADC_CHANNEL_COUN];
        vu16 Buffer[ADC_CHANNEL_COUN * ADC_ADD_COUN];
        vu16 OutputData[ADC_CHANNEL_COUN];
        vu32 Max[ADC_CHANNEL_COUN];//最大值
        vu16 OUtputMax[ADC_CHANNEL_COUN];//最大值输出
        vs16 TemperatureBuffer[CHANNEL];
        vu16 VolumeBuffer[CHANNEL];
        vu16 Flag;
        vu32 SwitchCounter;
        vu16 OutputTemperature[CHANNEL];
        vu16 OutputVolume[CHANNEL];
    vu16 OutputAcVoltage;
} AdcData;
void ADC_Config(void)
{
    uint32_t wait_loop_index;
   
    LL_ADC_InitTypeDef ADC_InitStruct = {0};
    LL_ADC_REG_InitTypeDef ADC_REG_InitStruct = {0};
    LL_ADC_CommonInitTypeDef ADC_CommonInitStruct = {0};
    LL_GPIO_InitTypeDef GPIO_InitStruct = {0};

    /* Peripheral clock enable */
    LL_APB2_GRP1_EnableClock(LL_APB2_GRP1_PERIPH_ADC);

    LL_IOP_GRP1_EnableClock(LL_IOP_GRP1_PERIPH_GPIOA);
    LL_IOP_GRP1_EnableClock(LL_IOP_GRP1_PERIPH_GPIOB);
    /* DMA controller clock enable */
    LL_AHB1_GRP1_EnableClock(LL_AHB1_GRP1_PERIPH_DMA1);

    /* DMA interrupt init */
    /* DMA1_Channel1_IRQn interrupt configuration */
   
    /**ADC1 GPIO Configuration
    PA0   ------> ADC1_IN0
    PA1   ------> ADC1_IN1
    PA2   ------> ADC1_IN2
    PA3   ------> ADC1_IN3
    PA4   ------> ADC1_IN4
    PA5   ------> ADC1_IN5
    PA6   ------> ADC1_IN6
    PA7   ------> ADC1_IN7
    PB0   ------> ADC1_IN8
    PB1   ------> ADC1_IN9
    PB2   ------> ADC1_IN10
   
    */
    GPIO_InitStruct.Pin = LL_GPIO_PIN_0 | LL_GPIO_PIN_1 |LL_GPIO_PIN_2 |
                                                  LL_GPIO_PIN_3 | LL_GPIO_PIN_4 | LL_GPIO_PIN_5|
                          LL_GPIO_PIN_6 | LL_GPIO_PIN_7;
    GPIO_InitStruct.Mode = LL_GPIO_MODE_analog;
    GPIO_InitStruct.Pull = LL_GPIO_PULL_NO;
    LL_GPIO_Init(GPIOA, &GPIO_InitStruct);

    GPIO_InitStruct.Pin = LL_GPIO_PIN_0 | LL_GPIO_PIN_1 |LL_GPIO_PIN_2 ;
    GPIO_InitStruct.Mode = LL_GPIO_MODE_ANALOG;
    GPIO_InitStruct.Pull = LL_GPIO_PULL_NO;
    LL_GPIO_Init(GPIOB, &GPIO_InitStruct);

    /* ADC1 DMA Init */

    /* ADC1 Init */
   
        
    //LL_DMA_DeInit(DMA1,LL_DMA_CHANNEL_1);
    // DMA传输方向  外设->内存
    LL_DMA_SetDataTransferDirection(DMA1, LL_DMA_CHANNEL_1, LL_DMA_DIRECTION_PERIPH_TO_MEMORY);
     // 通道优先级 低
    LL_DMA_SetChannelPriorityLevel(DMA1, LL_DMA_CHANNEL_1, LL_DMA_PRIORITY_LOW);   
    // DMA模式 循环
    LL_DMA_SetMode(DMA1, LL_DMA_CHANNEL_1, LL_DMA_MODE_NORMAL);
    // 外设地址递增模式  失能
    LL_DMA_SetPeriphIncMode(DMA1, LL_DMA_CHANNEL_1, LL_DMA_PERIPH_NOINCREMENT);
    // 内存地址递增模式  使能
    LL_DMA_SetMemoryIncMode(DMA1, LL_DMA_CHANNEL_1, LL_DMA_MEMORY_INCREMENT);
    // 外设半字
    LL_DMA_SetPeriphSize(DMA1, LL_DMA_CHANNEL_1, LL_DMA_PDATAALIGN_HALFWORD);
    // 内存半字
    LL_DMA_SetMemorySize(DMA1, LL_DMA_CHANNEL_1, LL_DMA_MDATAALIGN_HALFWORD);
    //外设地址
    LL_DMA_SetPeriphAddress(DMA1,LL_DMA_CHANNEL_1,(uint32_t)&ADC1->DR);
    // 内存地址
        LL_DMA_SetMemoryAddress(DMA1, LL_DMA_CHANNEL_1, (uint32_t)&AdcData.Buffer[0]);
    //  DMA传输数据长度
    LL_DMA_SetDataLength(DMA1,LL_DMA_CHANNEL_1,ADC_ADD_COUN*ADC_CHANNEL_COUN);
                     
    LL_ADC_EnableInternalRegulator(ADC1);                           
                           
    LL_ADC_REG_SetSequencerChAdd(ADC1, LL_ADC_CHANNEL_0
                              #if 0         
                              |LL_ADC_CHANNEL_1
                              |LL_ADC_CHANNEL_2|LL_ADC_CHANNEL_3
                              |LL_ADC_CHANNEL_4|LL_ADC_CHANNEL_5
                              |LL_ADC_CHANNEL_6|LL_ADC_CHANNEL_7
                              |LL_ADC_CHANNEL_8|LL_ADC_CHANNEL_9
                              |LL_ADC_CHANNEL_10
                              #endif
                              );
    NVIC_SetPriority(DMA1_Channel1_IRQn, 0);
    NVIC_EnableIRQ(DMA1_Channel1_IRQn);
    LL_DMA_EnableIT_TC(DMA1, LL_DMA_CHANNEL_1);//使能DMA通道一完成中断
   
    /** Configure the global features of the ADC (Clock, Resolution, Data Alignment and number of conversion)
    */
    ADC_InitStruct.Clock = LL_ADC_CLOCK_SYNC_PCLK_DIV4;        //ADC时钟分频
    ADC_InitStruct.Resolution = LL_ADC_RESOLUTION_12B;          // 采样分辨率
    ADC_InitStruct.DataAlignment = LL_ADC_DATA_ALIGN_RIGHT;     // 对齐方式
    ADC_InitStruct.LowPowerMode = LL_ADC_LP_MODE_NONE;          // 低功耗模式,使用DMA的话无法使用,这里关闭
    LL_ADC_Init(ADC1, &ADC_InitStruct);   
   
    #define ADC_CHANNEL_CONF_RDY_TIMEOUT_MS ( 1U)
    #define USE_TIMEOUT 1
    #if (USE_TIMEOUT == 1)
    uint32_t Timeout ; /* Variable used for Timeout management */
    #endif /* USE_TIMEOUT */

    ADC_REG_InitStruct.triggerSource = LL_ADC_REG_TRIG_SOFTWARE;                // 软件触发方式
    //ADC_REG_InitStruct.SequencerLength = LL_ADC_REG_SEQ_SCAN_DISABLE;     
    ADC_REG_InitStruct.SequencerDiscont = LL_ADC_REG_SEQ_DISCONT_DISABLE;      
    ADC_REG_InitStruct.ContinuousMode = LL_ADC_REG_CONV_CONTINUOUS;             // 规则通道连续转换
    // 使能DMA,并使用无限传输,如果DMA保存方式为循环覆盖的话才可以使用无限传输
    ADC_REG_InitStruct.DMATransfer = LL_ADC_REG_DMA_TRANSFER_LIMITED;  
   
    ADC_REG_InitStruct.Overrun = LL_ADC_REG_OVR_DATA_PRESERVED;               // 采集的数据循环覆盖模式
    LL_ADC_REG_Init(ADC1, &ADC_REG_InitStruct);
    LL_ADC_SetOverSamplingScope(ADC1, LL_ADC_OVS_DISABLE);                      // 失能过采样
    LL_ADC_SetTriggeRFrequencyMode(ADC1, LL_ADC_CLOCK_FREQ_MODE_HIGH);          // 采样时钟使用高频模式
    //adc通道和硬件adc in是否强制对应,因为adc的io使用时是连续的,所以这里使用非完全配置
    LL_ADC_REG_SetSequencerConfigurable(ADC1, LL_ADC_REG_SEQ_FIXED);

    // 设置通道共用取样时间,根据需要自行选择     
    LL_ADC_SetSamplingTimeCommonChannels(ADC1, LL_ADC_SAMPLINGTIME_COMMON_1, LL_ADC_SAMPLINGTIME_160CYCLES_5);
    LL_ADC_DisableIT_EOC(ADC1);     // 禁用通道采样结束中断
    LL_ADC_DisableIT_EOS(ADC1);     // 禁用序列采样结束中断
    LL_ADC_REG_SetSequencerScanDirection(ADC1, LL_ADC_REG_SEQ_SCAN_DIR_FORWARD);  //扫描方向为通道数字从小到大
     /* Poll for ADC channel configuration ready */
   #if (USE_TIMEOUT == 1)
   Timeout = ADC_CHANNEL_CONF_RDY_TIMEOUT_MS;
   #endif /* USE_TIMEOUT */
   while (LL_ADC_IsActiveFlag_CCRDY(ADC1) == 0)
     {
       #if (USE_TIMEOUT == 1)
       /* Check Systick counter flag to decrement the time-out value */

       if(Timeout-- == 0)
             {
                //Error_Handler();
                break;
             }
       #endif /* USE_TIMEOUT */
     }
   /* Clear flag ADC channel configuration ready */
   LL_ADC_ClearFlag_CCRDY(ADC1);
   wait_loop_index = ((LL_ADC_DELAY_INTERNAL_REGUL_STAB_US * (SystemCoreClock / (100000 * 2))) / 10);
   while(wait_loop_index != 0)
     {
        wait_loop_index--;
     }
    //DMA通道请求
    LL_DMA_SetPeriphRequest(DMA1, LL_DMA_CHANNEL_1, LL_DMAMUX_REQ_ADC1);
    LL_ADC_StartCalibration(ADC1);
    while(LL_ADC_IsCalibrationOnGoing(ADC1));
     
    wait_loop_index = (ADC_DELAY_CALIB_ENABLE_CPU_CYCLES >> 1);
    while(wait_loop_index != 0)
    {
      wait_loop_index--;
    }//等待校准
   
    //启动ADC
    LL_ADC_Enable(ADC1);     
    LL_ADC_REG_StartConversion(ADC1);
    LL_DMA_EnableChannel(DMA1, LL_DMA_CHANNEL_1);   //使能
}

void ADC_GetValue(void)
{
        u32 temp = 0; u16 tempMax = 0;
        u8 i = 0;
        u8 ChannelTemp=0;

        for(ChannelTemp=0;ChannelTemp<ADC_CHANNEL_COUN;ChannelTemp++)
        {
                temp = 0;
                tempMax = 0;
        
        for(i = 0; i <ADC_ADD_COUN; i++)
            {
                    temp += AdcData.Buffer[i*ADC_CHANNEL_COUN+ChannelTemp];
            if(tempMax < AdcData.Buffer[i*ADC_CHANNEL_COUN+ChannelTemp])
            {tempMax = AdcData.Buffer[i*ADC_CHANNEL_COUN+ChannelTemp];}

            }
        temp = temp/ADC_ADD_COUN;
            if(temp>60000){temp=60000;}
            AdcData.DataTemp[ChannelTemp]+=temp;
        AdcData.Max[ChannelTemp] += tempMax;
            AdcData.DataCouter[ChannelTemp]++;
            if(AdcData.DataCouter[ChannelTemp]>=ADC_DATA_COUNTER)
            {
                    AdcData.OutputData[ChannelTemp]=(u16)(AdcData.DataTemp[ChannelTemp]/ADC_DATA_COUNTER);
            AdcData.OUtputMax[ChannelTemp] = (u16)(AdcData.Max[ChannelTemp] / ADC_DATA_COUNTER);
            AdcData.Max[ChannelTemp] = 0;
                    AdcData.DataTemp[ChannelTemp]=0;
                    AdcData.DataCouter[ChannelTemp]=0;
            }
        }
}

void DMA1_Channel1_IRQHandler(void)
{
    if(LL_DMA_IsActiveFlag_TC1(DMA1))
    {
        LL_DMA_ClearFlag_TC1(DMA1);
        LL_DMA_DisableChannel(DMA1, LL_DMA_CHANNEL_1);
        LL_ADC_Disable(ADC1);
        ADC_GetValue();
        
        //  DMA传输数据长度
            LL_DMA_SetDataLength(DMA1,LL_DMA_CHANNEL_1,ADC_ADD_COUN*ADC_CHANNEL_COUN);  
        //启动ADC
        LL_ADC_Enable(ADC1);
        LL_ADC_REG_StartConversion(ADC1);
        LL_DMA_EnableChannel(DMA1, LL_DMA_CHANNEL_1);//   
        }      
}
#endif

主程序输出串口查看数据

            USART1_SendData((u8*)&ADC1->DR,2);
            USART1_SendData((u8*)AdcData.Buffer[0],2);

数据情况
两个1k电阻分压3.3v输入,ad结果截图,DMA 一直不正确
[10:21:57.059]收←◆0B 08 68 EB
[10:21:58.058]收←◆0B 08 68 EB
[10:21:59.058]收←◆0A 08 A9 68
[10:22:00.058]收←◆0B 08 68 EB

[10:22:01.058]收←◆0B 08 68 EB
前两个为寄存器DR输出 的值,0x080b转为电压大概1.66v是正确数值,DMA一直不正确

不知道你这个问题是否已经解决, 如果还没有解决的话:

如果你已经解决了该问题, 非常希望你能够分享一下解决方案, 写成博客, 将相关链接放在评论区, 以帮助更多的人 ^-^