打印
[APM32F1]

apm32f103RBT6 多通道ADC+DMA传输时数据通道错乱

[复制链接]
1177|22
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
zylxcu|  楼主 | 2023-4-1 11:33 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
void adc_Init(void)
{
    ADC_Config_T adcConfig;
          RCM_ConfigADCCLK(RCM_PCLK2_DIV_4);
                RCM_EnableAPB2PeriphClock(RCM_APB2_PERIPH_ADC1);
                //ADC_EnableTempSensorVrefint(ADC1);
                ADC_Reset(ADC1);
    /* ADC1 configuration ------------------------------------------------------*/
                ADC_ConfigStructInit(&adcConfig);
    adcConfig.mode = ADC_MODE_INDEPENDENT;
    adcConfig.scanConvMode = ENABLE;
    adcConfig.continuosConvMode = ENABLE;
    adcConfig.externalTrigConv = ADC_EXT_TRIG_CONV_None;
    adcConfig.dataAlign = ADC_DATA_ALIGN_RIGHT;
    adcConfig.nbrOfChannel = 3;
    ADC_Config(ADC1, &adcConfig);
    /* Enable ADC1 external trigger conversion */
                //ADC_EnableExternalTrigConv(ADC1);
   // ADC_ExternalTrigConvCmd(ADC1,ENABLE);
    /* ADC1 regular channel configuration */
                ADC_ConfigRegularChannel(ADC1, ADC_CHANNEL_8, 0, ADC_SAMPLETIME_55CYCLES5);
    ADC_ConfigRegularChannel(ADC1, ADC_CHANNEL_9, 1, ADC_SAMPLETIME_55CYCLES5);
               
          ADC_ConfigRegularChannel(ADC1, ADC_CHANNEL_15, 2, ADC_SAMPLETIME_55CYCLES5);
    /* Enable ADC1 DMA */
                ADC_EnableDMA(ADC1);
    /* Enable ADC1 */
    ADC_Enable(ADC1);
    /* Enable ADC1 reset calibaration register */   
    ADC_ResetCalibration(ADC1);
    /* Check the end of ADC1 reset calibration register */
    while(ADC_ReadResetCalibrationStatus(ADC1));
    /* Start ADC1 calibaration */
    ADC_StartCalibration(ADC1);
    /* Check the end of ADC1 calibration */
    while(ADC_ReadCalibrationStartFlag(ADC1));
    /* Start ADC1 Software Conversion */
    //ADC_SoftwareStartConvCmd(ADC1, ENABLE);           //ADC转换启动最好放在DMA启动之后                  
}
void dma_Init(void)
{
  DMA_Config_T DMA_InitStructure;


        RCM_EnableAHBPeriphClock(RCM_AHB_PERIPH_DMA1);
  /* DMA channel1 configuration ----------------------------------------------*/

        DMA_Reset(DMA1_Channel1);
  DMA_InitStructure.peripheralBaseAddr = (uint32_t)&ADC1->REGDATA;
  DMA_InitStructure.memoryBaseAddr = (uint32_t)ADC_ConvertedValue;
  DMA_InitStructure.dir = DMA_DIR_PERIPHERAL_SRC;
  DMA_InitStructure.bufferSize = 3;
  DMA_InitStructure.peripheralInc = DMA_PERIPHERAL_INC_DISABLE;
  DMA_InitStructure.memoryInc = DMA_MEMORY_INC_ENABLE;
  DMA_InitStructure.peripheralDataSize = DMA_PERIPHERAL_DATA_SIZE_HALFWORD;
  DMA_InitStructure.memoryDataSize = DMA_MEMORY_DATA_SIZE_HALFWORD;
  DMA_InitStructure.loopMode = DMA_MODE_CIRCULAR;
  DMA_InitStructure.priority = DMA_PRIORITY_HIGH;
  DMA_InitStructure.M2M = DMA_M2MEN_DISABLE;
  DMA_Config(DMA1_Channel1, &DMA_InitStructure);

  DMA_EnableInterrupt(DMA1_Channel1,DMA_INT_TC|DMA_INT_TERR);
  /* Enable DMA1 channel1 */
   DMA_Enable(DMA1_Channel1);
}

void TMR1_UP_IRQHandler(void)
{       
                         static unsigned DmaTimeOut,DmaFaultCount =0;
          if(TMR_ReadIntFlag(TMR1, TMR_FLAG_UPDATE) == SET)
    {
                        TMR_ClearIntFlag(TMR1, TMR_FLAG_UPDATE);
                          //启动ADC转换,定时器触发或软件触发,当前由TIM2_CC2触发,
        ADC_EnableSoftwareStartConv(ADC1);
        //等待ADC转换结束以及DMA数据传输完成,由于使用DMA传输,当前判定DMA传输完成
        //如果传输出错,选用一个周波前的点填充,连续出错一个周波报错。
        while( DMA_ReadStatusFlag(DMA1_FLAG_TC1) !=SET )
        {
            if(DMA_ReadStatusFlag(DMA1_FLAG_TERR1) ==SET)  //传输出错
            {
                DMA_ClearStatusFlag(DMA1_FLAG_TERR1);
                ++DmaFaultCount;
            }
            //超时
            ++DmaTimeOut;
        }         
       DMA_ClearStatusFlag(DMA1_FLAG_TC1);
       adc_ReadSampleData();         
    }
}

void adc_ReadSampleData(void)
{
    int i;                             
    for(i=0; i < 3; i++)
    {
        SampleData.AIData[i][ADC_SampleIndex] = ADC_ConvertedValue[i];
    }
                ADC_SampleIndex = ADC_SampleIndex + 1;
                if(ADC_SampleIndex >= ADC_SAMPLEBUFF_SIZE)
                {
                        ADC_SampleIndex =0;
                }
}

int main(void)
{
                SetSysClock();
                rcc_init();
                gpio_init();
                nvic_Init();
                dma_Init();                  /*配置DMA传输AD转换结果*/
                adc_Init();
                tim_CreateSampleTimer();
                             
    while(1)
    {

    }
}

使用特权

评论回复
沙发
zylxcu|  楼主 | 2023-4-1 11:33 | 只看该作者
为什么通道数据会乱呢

使用特权

评论回复
板凳
51xlf| | 2023-4-12 21:12 | 只看该作者
adc多通道采集可以不采用dma吗

使用特权

评论回复
地板
maudlu| | 2023-4-12 21:36 | 只看该作者
如何控制发送速率               

使用特权

评论回复
5
zerorobert| | 2023-4-13 15:41 | 只看该作者
ADC-DMA如何初始化配置

使用特权

评论回复
6
vivilyly| | 2023-4-13 20:26 | 只看该作者
ADC转换如何计算               

使用特权

评论回复
7
louliana| | 2023-4-13 20:46 | 只看该作者
多通道转换,是怎么样读取转换的结果的 ?

使用特权

评论回复
8
primojones| | 2023-4-13 21:13 | 只看该作者
ADC+DMA模式能把ADC速度更新做到的最快

使用特权

评论回复
9
backlugin| | 2023-4-13 22:06 | 只看该作者
如何配置库函数 apm32f103RBT6  adc的dma传输

使用特权

评论回复
10
ulystronglll| | 2023-4-13 22:34 | 只看该作者
ADC连续扫描模式必须要用DMA吗

使用特权

评论回复
11
gygp| | 2023-4-13 22:43 | 只看该作者
使用dma 为什么只显示一个通道的值

使用特权

评论回复
12
saservice| | 2023-5-5 21:03 | 只看该作者
一些可能导致多通道ADC DMA传输时数据错误的原因及其解决方案,请根据实际情况进行排查。

使用特权

评论回复
13
51xlf| | 2023-5-5 21:14 | 只看该作者
DMA配置错误:在使用DMA时,需要正确配置DMA通道、传输方向、缓冲区地址等参数。

使用特权

评论回复
14
lzmm| | 2023-5-5 21:20 | 只看该作者
确保DMA传输长度与采样周期匹配。如果DMA传输长度太短,则可能无法完全传输一次采样,从而导致数据错误。

使用特权

评论回复
15
pixhw| | 2023-5-5 21:26 | 只看该作者
首先这种情况, 第一感觉的是地址弄错了.

使用特权

评论回复
16
maqianqu| | 2023-5-5 21:48 | 只看该作者
adc多通道采集 使用dma 为什么只显示一个通道的值

使用特权

评论回复
17
cemaj| | 2023-5-5 22:41 | 只看该作者
在使用多个DMA通道进行数据传输时,需要正确设置每个DMA通道的优先级,以确保数据传输的正确性。

使用特权

评论回复
18
wengh2016| | 2023-5-5 22:55 | 只看该作者
adc数据采集的不对,也就是说adc的配置错误。dma在取数据时发生错误,也就是dma的配置错误。

使用特权

评论回复
19
qiufengsd| | 2023-5-5 23:20 | 只看该作者
在STM32中ADC有些通道是重合的

使用特权

评论回复
20
sanfuzi| | 2023-5-5 23:37 | 只看该作者
可以添加电源滤波器和/或信号滤波器来减少ADC通道之间的交叉干扰,从而减少数据错误的发生。

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

5

主题

22

帖子

0

粉丝