STM32 ADC DMA缓冲区读取出错

2019-03-23 19:25发布

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[ch];
    if(abs(tmp - 1760)>7)
    {
      aderrodata[0] = tmp;
      for (tmp =1;tmp<2000;tmp++)
      {
        aderrodata[tmp] = ADCConvertedValue[ch];
      }
      tmp = aderrodata[0];
    }
    sum += tmp;
  }
  tmp = sum/ CONVERTTIMES;
  return (tmp);
}

//问题现象:4个通道的AD采样码都是1762,跳动很小,当跳动大于7的时候加断点,监控发现ADCConvertedValue内的值仍为1762,但是赋值后读出来就变为1768或1772等其他的值,此时再连续读2000次此通道的ADCConvertedValue,发现读到500次左右的时候又能读到正确的值1762
请问版主,大概是什么问题? 此帖出自小平头技术问答
0条回答

一周热门 更多>