ADC1 on STM32F105 incorrect readings

ChibiOS public support forum for topics related to the STMicroelectronics STM32 family of micro-controllers.

Moderator: RoccoMarco

Post Reply
podhrmic
Posts: 21
Joined: Wed Nov 06, 2013 1:40 am

ADC1 on STM32F105 incorrect readings

Post by podhrmic »

Hi,

I am using ChibiOS/RT v. 2.6.2 on Lisa M 2.0 board with Paparazzi autopilo (STM32F105 chip, pinout and some info about the board and the autopilot here http://paparazzi.enac.fr/wiki/Lisa/M_v2.0).

There are 4 ADC channels available plus the CPU temperature sensor. I use ADC1 (only ADC available for this chip) in circular buffer mode. I noticed, that no matter what is the order of the channels, voltage change in one channel affects measured voltage in the next channel in the sequence.

For example, my sequence is ADC13, ADC11, ADC10, ADC14. If I connect ADC13 to Vref, I can see voltage increase also on ADC11. If I connect ADC10 to Vref, then voltage on ADC14 jumps up. I am pretty sure that I am reading buffer from the callback correctly.

Different timing settings or buffer size has no effect on this behavior.

A workaround seems to be to include "dummy" channels in the sequence (i.e. ADC13 - DUMMY - ADC11 - DUMMY - ADC10 - DUMMY - ADC14). Then the next measurement in the sequence shows correct value. Disadvantage is that you have to use twice as much memory and time to do the conversion.

My code:

Code: Select all

#define ADC_NUM_CHANNELS        9
#define ADC_BUF_DEPTH 32

#define ADC_V_REF_MV 3300
#define ADC_12_BIT_RESOLUTION 4096

static adcsample_t adc_samples[ADC_NUM_CHANNELS * ADC_BUF_DEPTH] = {0};

struct adc_buf {
  uint32_t sum;                      /* Sum of samples in buffer (avg = sum / av_nb_sample) */
  uint16_t values[MAX_AV_NB_SAMPLE]; /* Buffer for sample values from ADC                   */
  uint8_t  head;                     /* Position index of write head in buffer              */
  uint8_t  av_nb_sample;             /* Number of samples to use in buffer (used for avg)   */
};

static struct adc_buf * adc1_buffers[ADC_NUM_CHANNELS] = {NULL};

void adc1callback(ADCDriver *adcp, adcsample_t *buffer, size_t n) {
  if (adcp->state != ADC_STOP) {
      for(uint8_t channel = 0; channel < ADC_NUM_CHANNELS; channel+=2) {
          if (adc1_buffers[channel/2] != NULL) {
          adc1_buffers[channel/2]->sum = 0;
          adc1_buffers[channel/2]->av_nb_sample = n;
          for (uint8_t sample = 0; sample < n; sample++) {
                adc1_buffers[channel/2]->sum += buffer[channel + sample*ADC_NUM_CHANNELS];
            }
          adc1_buffers[channel/2]->sum = (adc1_buffers[channel/2]->sum)*ADC_V_REF_MV/ADC_12_BIT_RESOLUTION;
          }
      }
  }
}


static void adcerrorcallback(ADCDriver *adcp, adcerror_t err) {
  chSysLockFromIsr();
  adcp_err = adcp;
  adc_error_flag = err;
  chSysUnlockFromIsr();
}

/*
 * Conversion config for ADC
 * @note: Continuous conversion
 * Including Temp sensor, Ts = 7 + 12.5 = 19.5us
 * ADCCLK = 14 MHz
 * Rest of ADcs Ts = 41.5c + 12.5c = 54.0us
 */
static const ADCConversionGroup adcgrpcfg = {
    TRUE,
    ADC_NUM_CHANNELS,
    adc1callback,
    adcerrorcallback,
    0, ADC_CR2_TSVREFE,
    ADC_SMPR1_SMP_AN10(ADC_SAMPLE_41P5) | ADC_SMPR1_SMP_AN11(ADC_SAMPLE_41P5) |
    ADC_SMPR1_SMP_AN13(ADC_SAMPLE_41P5) | ADC_SMPR1_SMP_AN14(ADC_SAMPLE_41P5) | ADC_SMPR1_SMP_SENSOR(ADC_SAMPLE_7P5),
    0,
    ADC_SQR1_NUM_CH(ADC_NUM_CHANNELS),
    ADC_SQR2_SQ9_N(ADC_CHANNEL_SENSOR) |ADC_SQR2_SQ7_N(ADC_CHANNEL_IN14),
    ADC_SQR3_SQ5_N(ADC_CHANNEL_IN11) |  ADC_SQR3_SQ3_N(ADC_CHANNEL_IN10)  | ADC_SQR3_SQ1_N(ADC_CHANNEL_IN13)
};


then in my thread I run:

Code: Select all

  adcStart(&ADCD1, NULL);
  adcStartConversion(&ADCD1, &adcgrpcfg, adc_samples, ADC_BUF_DEPTH);


Do you have any idea what might be wrong? Might it be HW issue?

Regards
Michal
User avatar
Giovanni
Site Admin
Posts: 14892
Joined: Wed May 27, 2009 8:48 am
Has thanked: 1202 times
Been thanked: 996 times

Re: ADC1 on STM32F105 incorrect readings

Post by Giovanni »

Hi,

I suspect an HW issue, do you drive the analog channels with a sufficiently low impedance? there is a relationship to be respected between impedance and sample time, there should be a table in the RM.

Giovanni
Post Reply