打印

关于STM32 ADC用DMA采多通道时数据错位的问题New

[复制链接]
楼主: kingpower2018
手机看帖
扫描二维码
随时随地手机跟帖
81
xiaoshuang| | 2009-10-15 10:01 | 只看该作者 回帖奖励 |倒序浏览
后来我将ad采样设置成单次扫描方式,同时启动ad中断,在中断中判断是否错位,没有就继续,有就复位ad和dma。下面是我改后的程序:
uint16  ADC_ConvertedValue[256];//ad转换结果存入的数组
bool ADC_ready;                //ad转换完成一次。

/***************************************************
重新初始化AD的寄存器
***************************************************/
void ReInitAd(void)
{
ADC_InitTypeDef ADC_InitStructure;
DMA_InitTypeDef DMA_InitStructure;
NVIC_InitTypeDef NVIC_InitStructure;
  DMA_DeInit(DMA_Channel1);       
  ADC_DeInit(ADC1);
  DMA_InitStructure.DMA_PeripheralBaseAddr =0x4001244c;
  DMA_InitStructure.DMA_MemoryBaseAddr = (u32)ADC_ConvertedValue;
  DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralSRC;
  DMA_InitStructure.DMA_BufferSize = 256;
  DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;
  DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;
  DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_HalfWord;
  DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_HalfWord;
  DMA_InitStructure.DMA_Mode = DMA_Mode_Circular;
  DMA_InitStructure.DMA_Priority = DMA_Priority_High;
  DMA_InitStructure.DMA_M2M = DMA_M2M_Disable;
  DMA_Init(DMA_Channel1, &DMA_InitStructure);
  
  DMA_Cmd(DMA_Channel1, ENABLE);
  
  ADC_InitStructure.ADC_Mode = ADC_Mode_Independent;
  ADC_InitStructure.ADC_ScanConvMode = ENABLE;
  ADC_InitStructure.ADC_ContinuousConvMode = DISABLE;//ENABLE;
  ADC_InitStructure.ADC_ExternalTrigConv = ADC_ExternalTrigConv_None;
  ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right;
  ADC_InitStructure.ADC_NbrOfChannel = 16;
  ADC_Init(ADC1, &ADC_InitStructure);

  ADC_RegularChannelConfig(ADC1, ADC_Channel_0, 1, ADC_SampleTime_1Cycles5);
  ADC_RegularChannelConfig(ADC1, ADC_Channel_1, 2, ADC_SampleTime_1Cycles5);
  ADC_RegularChannelConfig(ADC1, ADC_Channel_2, 3, ADC_SampleTime_1Cycles5);
  ADC_RegularChannelConfig(ADC1, ADC_Channel_3, 4, ADC_SampleTime_1Cycles5);
  ADC_RegularChannelConfig(ADC1, ADC_Channel_4, 5, ADC_SampleTime_1Cycles5);
  ADC_RegularChannelConfig(ADC1, ADC_Channel_5, 6, ADC_SampleTime_1Cycles5);
  ADC_RegularChannelConfig(ADC1, ADC_Channel_6, 7, ADC_SampleTime_1Cycles5);
  ADC_RegularChannelConfig(ADC1, ADC_Channel_7, 8, ADC_SampleTime_1Cycles5);
  ADC_RegularChannelConfig(ADC1, ADC_Channel_8, 9, ADC_SampleTime_1Cycles5);
  ADC_RegularChannelConfig(ADC1, ADC_Channel_9, 10, ADC_SampleTime_1Cycles5);
  ADC_RegularChannelConfig(ADC1, ADC_Channel_10, 11, ADC_SampleTime_55Cycles5);
  ADC_RegularChannelConfig(ADC1, ADC_Channel_11, 12, ADC_SampleTime_55Cycles5);
  ADC_RegularChannelConfig(ADC1, ADC_Channel_12, 13, ADC_SampleTime_55Cycles5);
  ADC_RegularChannelConfig(ADC1, ADC_Channel_13, 14, ADC_SampleTime_55Cycles5);
  ADC_RegularChannelConfig(ADC1, ADC_Channel_14, 15, ADC_SampleTime_1Cycles5);
  ADC_RegularChannelConfig(ADC1, ADC_Channel_15, 16, ADC_SampleTime_1Cycles5);

  /* Enable ADC1 DMA */
  ADC_DMACmd(ADC1, ENABLE);
  
  ADC_ITConfig(ADC1, ADC_IT_EOC, ENABLE);
  
  ADC_Cmd(ADC1, ENABLE);
  
  ADC_ResetCalibration(ADC1);
  while(ADC_GetResetCalibrationStatus(ADC1));

  ADC_StartCalibration(ADC1);
  while(ADC_GetCalibrationStatus(ADC1));
     
  ADC_SoftwareStartConvCmd(ADC1, ENABLE);  
  
  
  NVIC_InitStructure.NVIC_IRQChannel = ADC_IRQChannel;
  NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
  NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
  NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
  NVIC_Init(&NVIC_InitStructure);
  ADC_ready = FALSE;          
}


//////////// 下面是ad中断程序///////////////////
void ADC_IRQHandler(void)
{
ADC_ClearITPendingBit(ADC1, ADC_IT_AWD);
ADC_ready = TRUE;
if(((DMA_Channel1->CNDTR)&0XF) != 0)
{
         ReInitAd();
}
else
{                         
     ADC_SoftwareStartConvCmd(ADC1, ENABLE);  
}
}

/////////下面是在其他模块中定时调用的一段程序,时间间隔应该是大于2个ad中断时间//

   if(ADC_ready        ==FALSE)
   {
       ReInitAd();     
   }
   ADC_ready = FALSE;
不知是否有帮助?

使用特权

评论回复
82
fzxuecumt| | 2009-12-3 15:53 | 只看该作者
我的三个ad没问题,8个旧有问题。

使用特权

评论回复
83
rockli| | 2010-10-24 20:40 | 只看该作者
楼主需要自己冷静,自己解决。就算st承认芯片有bug。你怎么办?对客户说我的ic有bug。
还是要解决的。
怎样解决问题是你目前的重点,这个要靠自己。就算st的工程师解决不了了,你能把所有的产品召回重新设计吗?
感觉楼主还是年轻,我遇到过好多原厂解决不了,最后靠自己解决的事情了。原厂工程师也是工程师,也不是万能的。

使用特权

评论回复
84
jinjing999| | 2011-10-21 10:20 | 只看该作者
楼主,我也遇到跟楼主一样问题

使用特权

评论回复
85
jinjing999| | 2011-10-21 10:34 | 只看该作者
65# kingpower2018
遇到的问题一摸一样,我是打3kv脉冲干扰群

使用特权

评论回复
86
jinjing999| | 2011-10-21 10:56 | 只看该作者
86# xiaoshuang
他这方法值得试试

使用特权

评论回复
87
zxz_chy| | 2011-12-14 09:15 | 只看该作者
好贴,我也来凑凑热闹,我的贴都没人理我的,是不是我水平不够啊:'(

使用特权

评论回复
88
duyinqian1986| | 2012-7-5 21:50 | 只看该作者
我的做法不知可行不可行:
用一定时器,在定时中断中启动ADC。假如ADC转换的是4路,在定时中断服务中:
    ADC1->CR2 |= 0x00500000;                              // 启动ADC1
    DMA1_Channel1->CCR   &= 0xFFFFFFFE;             // 关闭DMA
    DMA1_Channel1->CNDTR = 4;                            // 重设为4路
    DMA1_Channel1->CMAR         = (int)&ADC_res;          // 重设地址
    DMA1_Channel1->CCR   |= 0x00000001;            // 启动DMA
    TIM3->SR &=~(1 <<0 );                                    // 清中断标志
每一次采样都重设DMA的传送地址和长度,看它错位不错位。

使用特权

评论回复
89
wforest68| | 2012-9-17 19:08 | 只看该作者
5# zhiweihzx


看来ST的产品的抗干扰能力真是一般,我的产品看来不能选ST了

使用特权

评论回复
90
wforest68| | 2012-9-17 19:09 | 只看该作者
16# 他爹


建议换NXP的

使用特权

评论回复
91
zhousun| | 2012-9-18 15:48 | 只看该作者
不知解决了没有,我看了上面的回复和讨论,可以试试下面做法:
1.确定一下是不是ADC的问题,这样可以将计算的数据数组数据固定不变,
然后让故障复现,如果故障消失,那么故障定位在DMA传输以前。
2. 将ADC转换数据模拟在数组,重复上面实验确定是否是DMA的问题。
3.如果以上都没有问题那么可以肯定是ADC了,然后采用软件或硬件措施

我始终认为只要在实验室故障能复现就好办,就怕故障随机,无法检验整改效果最麻烦。

使用特权

评论回复
92
zhousun| | 2012-9-18 15:49 | 只看该作者
不知解决了没有,我看了上面的回复和讨论,可以试试下面做法:
1.确定一下是不是ADC的问题,这样可以将计算的数据数组数据固定不变,
然后让故障复现,如果故障消失,那么故障定位在DMA传输以前。
2. 将ADC转换数据模拟在数组,重复上面实验确定是否是DMA的问题。
3.如果以上都没有问题那么可以肯定是ADC了,然后采用软件或硬件措施

我始终认为只要在实验室故障能复现就好办,就怕故障随机,无法检验整改效果最麻烦。

使用特权

评论回复
93
zhousun| | 2012-9-18 15:49 | 只看该作者
不知解决了没有,我看了上面的回复和讨论,可以试试下面做法: 1.确定一下是不是ADC的问题,这样可以将计算的数据数组数据固定不变,然后让故障复现,如果故障消失,那么故障定位在DMA传输以前。 2. 将ADC转换数据模拟在数组,重复上面实验确定是否是DMA的问题。 3.如果以上都没有问题那么可以肯定是ADC了,然后采用软件或硬件措施 我始终认为只要在实验室故障能复现就好办,就怕故障随机,无法检验整改效果最麻烦。

使用特权

评论回复
94
zhousun| | 2012-9-18 15:49 | 只看该作者

我来说说我的想法

不知解决了没有,我看了上面的回复和讨论,可以试试下面做法: 1.确定一下是不是ADC的问题,这样可以将计算的数据数组数据固定不变,然后让故障复现,如果故障消失,那么故障定位在DMA传输以前。 2. 将ADC转换数据模拟在数组,重复上面实验确定是否是DMA的问题。 3.如果以上都没有问题那么可以肯定是ADC了,然后采用软件或硬件措施 我始终认为只要在实验室故障能复现就好办,就怕故障随机,无法检验整改效果最麻烦。

使用特权

评论回复
95
zchong| | 2014-6-11 11:32 | 只看该作者

使用特权

评论回复
96
金融小数| | 2014-6-11 11:36 | 只看该作者
挖坟啊!:lol

使用特权

评论回复
97
cool_coder| | 2014-6-11 12:31 | 只看该作者
这么老的贴子都被挖出来了?呵呵……

使用特权

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

本版积分规则