打印

STM32 ADC DMA缓冲区读取出错

[复制链接]
1750|1
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
sanzhe|  楼主 | 2012-11-26 16:47 | 只看该作者 |只看大图 回帖奖励 |倒序浏览 |阅读模式
STM32 ADC DMA读取AD采样码有时会读到错误的值,但是DMA_Memory里面的值是对的,就一个赋值语句而已,是不是赋值的时候DMA正在对内存写操作?没有使用中断。
#define CONVERTTIMES      14        /*采样次数*/
#define CHANNELQUANITY    4         /*采样通道数*/
#define ADCSampleTime     ADC_SampleTime_41Cycles5    /*采样速率*/
static u16 ADCConvertedValue[CONVERTTIMES][CHANNELQUANITY];
//DMA初始化
void DMA1_Init(void)
{
  DMA_InitTypeDef DMA_InitStructure;
  
  RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1, ENABLE);
  
  /* DMA1 channel1 configuration ----------------------------------------------*/
  DMA_DeInit(DMA1_Channel1);
  DMA_InitStructure.DMA_PeripheralBaseAddr = ADC1_DR_Address;
  DMA_InitStructure.DMA_MemoryBaseAddr = (u32)ADCConvertedValue[0];
  DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralSRC;
  DMA_InitStructure.DMA_BufferSize = CONVERTTIMES * CHANNELQUANITY;
  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(DMA1_Channel1, &DMA_InitStructure);
  
  /* Enable DMA1 channel1 */
  DMA_Cmd(DMA1_Channel1, ENABLE);
}
//ADC初始化
void ADC1_Init(void)
{
  GPIO_InitTypeDef GPIO_InitStructure;
  ADC_InitTypeDef ADC_InitStructure;
  
  RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);
  RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);
  RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC, ENABLE);

  /*    配置ADC时钟 72MHz/6=12MHz   */
  RCC_ADCCLKConfig(RCC_PCLK2_Div6);
  RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1, ENABLE);
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AIN;
  /*    配置16个模拟量输入通道    */
  GPIO_InitStructure.GPIO_Pin = Pin_ADC_1;
  GPIO_Init(GPIO_ADC_1, &GPIO_InitStructure);
  GPIO_InitStructure.GPIO_Pin = Pin_ADC_2;
  GPIO_Init(GPIO_ADC_2, &GPIO_InitStructure);
  GPIO_InitStructure.GPIO_Pin = Pin_ADC_3;
  GPIO_Init(GPIO_ADC_3, &GPIO_InitStructure);
  GPIO_InitStructure.GPIO_Pin = Pin_ADC_4;
  GPIO_Init(GPIO_ADC_4, &GPIO_InitStructure);
  /*    配置ADC1工作在DMA模式下   */
  ADC_InitStructure.ADC_Mode = ADC_Mode_RegSimult;
  ADC_InitStructure.ADC_ScanConvMode = ENABLE;
  ADC_InitStructure.ADC_ContinuousConvMode = ENABLE;
  ADC_InitStructure.ADC_ExternalTrigConv = ADC_ExternalTrigConv_None;
  ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right;
  ADC_InitStructure.ADC_NbrOfChannel = CHANNELQUANITY;
  ADC_Init(ADC1, &ADC_InitStructure);

  /* ADC1 regular channel configuration */
  ADC_RegularChannelConfig(ADC1, ADC_Ch_ADC_1, 1, ADCSampleTime);
  ADC_RegularChannelConfig(ADC1, ADC_Ch_ADC_2, 2, ADCSampleTime);
  ADC_RegularChannelConfig(ADC1, ADC_Ch_ADC_3, 3, ADCSampleTime);
  ADC_RegularChannelConfig(ADC1, ADC_Ch_ADC_4, 4, ADCSampleTime);
  /* Enable ADC1 DMA */
  ADC_DMACmd(ADC1, ENABLE);
  /* Enable ADC1 */
  ADC_Cmd(ADC1, ENABLE);
  /* Enable ADC1 reset calibaration register */   
  ADC_ResetCalibration(ADC1);
  ADC_StartCalibration(ADC1);
  //while(ADC_GetCalibrationStatus(ADC1) == SET);
  ADC_SoftwareStartConvCmd(ADC1, ENABLE);
}
//Read AD
u16 ReadAD(u8 ch)
{
  u8 i;
  u32 sum = 0;
  for(i=0; i<CONVERTTIMES; i++)
  {
    tmp = ADCConvertedValue[i][ch];
    if(abs(tmp - 1760)>7)
    {
      aderrodata[0] = tmp;
      for (tmp =1;tmp<2000;tmp++)
      {
        aderrodata[tmp] = ADCConvertedValue[i][ch];
      }
      tmp = aderrodata[0];
    }
    sum += tmp;
  }
  tmp = sum/ CONVERTTIMES;
  return (tmp);
}

//问题现象:4个通道的AD采样码都是1760,跳动很小,当跳动大于7的时候加断点,监控发现ADCConvertedValue内的值仍为1760,但是赋值后读出来就变为1768或1772等其他的值,此时再连续读2000次此通道的ADCConvertedValue,发现读到500次左右的时候又能读到正确的值1762
请问版主,大概是什么问题?
沙发
sanzhe|  楼主 | 2012-11-26 16:49 | 只看该作者
aderrodata数组监控值

QQ截图20121126164243.png (6.75 KB )

QQ截图20121126164243.png

使用特权

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

本版积分规则

1

主题

2

帖子

0

粉丝