Skip to main content
daviddavid942
Associate II
March 9, 2010
Question

ADC Analog Watchdog

  • March 9, 2010
  • 4 replies
  • 1093 views
Posted on March 09, 2010 at 10:37

ADC Analog Watchdog

    This topic has been closed for replies.

    4 replies

    daviddavid942
    Associate II
    May 17, 2011
    Posted on May 17, 2011 at 13:42

    Hi edison,

    I already use DMA for ADC, and I observed read values. The're not 0 when the AWD triggers (and even if they were, I'd expect AWD not triggering, because the reference manual says below low threshold).

    I'll check with oscilloscope asap, but I can't imagine what kind of spike could cause this, if the low threshold is 0...

    Thanks
    Tomas DRESLER
    Associate II
    May 17, 2011
    Posted on May 17, 2011 at 13:42

    Strange, I never experienced such behavior, and use it for motor control task => you'd simply hear it, if it's misplaced. Can you check with scope, that you have no spikes on the ADC input, like dirt in the pot?

    Use DMA to store data into a circular buffer and stop it when you get the AWD flag set, you should see the data record.
    er23
    Visitor II
    May 17, 2011
    Posted on May 17, 2011 at 13:42

    Hello,

    I am facing similar issue.

    Analog watchdog flag in ADc1->SR never gets clear ,even it is written zero by software.Only ADC disable clears the flag.

    AWD behaviour is not as per defined in reference manual.

    daviddavid942
    Associate II
    May 17, 2011
    Posted on May 17, 2011 at 13:42

    Edison,

    I verified with oscilloscopre that there are not strange spikes.

    However, I was wrong when I said that the AWD triggers when approaching to 0, I was erroneously reading another channel value.

    The AWD is always set, even after an ADC_ClearFlag (ADC1, ADC_FLAG_AWD) call and even if the channel value is between 0 and high threshold.

    The flag is raised as soon the ADC is turned with ADC_SoftwareStartConvCmd(ADC1, ENABLE) call.

    Mybe there's something wrong with my initialization sequence ?

    The complete sequence, including DMA, is the following:

    DMA_InitTypeDef DMA_InitStructure;

    ADC_InitTypeDef  ADC_InitStructure;

    //DMA configuration

    DMA_DeInit(DMA1_Channel1);

    DMA_InitStructure.DMA_PeripheralBaseAddr = (uint32_t)&(ADC1->DR);

    DMA_InitStructure.DMA_MemoryBaseAddr = (uint32_t)(&Sensors.m_ADC_Sensors);

    DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralSRC;

    DMA_InitStructure.DMA_BufferSize = 5;

    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(D_DMA_ADC_CHANNEL, &DMA_InitStructure);

    //ADC configuration

    ADC_DeInit(D_ADC_SENSORS);

    RCC_ADCCLKConfig(RCC_PCLK2_Div4); //12MHz

    ADC_InitStructure.ADC_ContinuousConvMode = ENABLE;

    ADC_InitStructure.ADC_DataAlign    = ADC_DataAlign_Right;

    ADC_InitStructure.ADC_ExternalTrigConv  = ADC_ExternalTrigConv_None;

    ADC_InitStructure.ADC_Mode = ADC_Mode_Independent;

    ADC_InitStructure.ADC_NbrOfChannel = 5;

    ADC_InitStructure.ADC_ScanConvMode = ENABLE;

    ADC_Init(ADC1, &ADC_InitStructure);

    ADC_RegularChannelConfig(ADC1, ADC_Channel_0, 1, ADC_SampleTime_13Cycles5);

    ADC_RegularChannelConfig(ADC1, ADC_Channel_1, 2, ADC_SampleTime_13Cycles5);  

    ADC_RegularChannelConfig(ADC1, ADC_Channel_2, 3, ADC_SampleTime_13Cycles5);

    ADC_RegularChannelConfig(ADC1, ADC_Channel_3, 4, ADC_SampleTime_13Cycles5);

    ADC_RegularChannelConfig(ADC1, ADC_Channel_4, 5, ADC_SampleTime_13Cycles5);

    ADC_RegularChannelConfig(ADC1, ADC_Channel_5, 6, ADC_SampleTime_13Cycles5);

    //Enable D_ADC_SENSORS

    ADC_Cmd(ADC1, ENABLE);

    //Enable D_ADC_SENSORS reset calibration register

    ADC_ResetCalibration(ADC1);

    //Check the end of D_ADC_SENSORS reset calibration register

    while(ADC_GetResetCalibrationStatus(ADC1));

     

    //Start ADC1 calibaration

    ADC_StartCalibration(ADC1);

    //Check the end of ADC1 calibration

    while(ADC_GetCalibrationStatus(ADC1));

    #ifdef USE_AWD

        ADC_AnalogWatchdogThresholdsConfig(ADC1, high, 0);

        ADC_AnalogWatchdogSingleChannelConfig(ADC1, ADC_Channel_5);

        ADC_ClearFlag(ADC1, ADC_FLAG_AWD);

        ADC_AnalogWatchdogCmd(ADC1, ADC_AnalogWatchdog_SingleRegEnable);

    #endif

    //Enable ADC-DMA

    ADC_DMACmd(ADC1, ENABLE);

    //Enable DMA channel 1

    DMA_Cmd(DMA1_Channel1, ENABLE);

    //Start ADC1 Software Conversion 

    ADC_SoftwareStartConvCmd(ADC1, ENABLE);

    Edited: initialization sequence updated (DMA activation moved after ADC calibraton, ADC_DeInit added).

    The problem remains, the AWD flag is actvated as soon as the ADC_SoftwareStartConvCmd call is done, and will not go away, even if the channel value is BETWEEN low and high threshold.