ВходНаше всё Теги codebook 无线电组件 Поиск Опросы Закон Пятница
29 марта
1138125
Sergey_N (13.10.2021 00:00, просмотров: 1567)
atxmega32a4u adc scan mode 

Привет! Пытаюсь отладить непрерывный режим у АЦП на xmega. Тестовая программа очень простая: по прерыванию берет номер канала в SCAN регистре и кладет в буфер по инкрементируемому указателю. В идеале, содержимое позиция в буфере должно отличаться на единицу от содержимого (или совпадать), т.е. ожидаю следующее

0 1 2 3 0 1 2 3
0 1 2 3 0 1 2 3
0 1 2 3 0 1 2 3
0 1 2 3 0 1 2 3

Однако получаю это

0 1 2 3 0 1 2 3
1 2 3 0 1 2 3 0
2 3 0 1 2 3 0 1
3 0 1 2 3 0 1 2
0 1 2 3 0 1 2 3
1 2 3 0 1 2 3 0
2 3 0 1 2 3 0 1
3 0 1 2 3 0 1 2
0 1 2 3 0 1 2 3
0 1 2 3 0 1 2 3
1 2 3 0 1 2 3 0

Такое впечатление, что пропускаются какие-то прерывания. Вот код (опустил кусок, посылающий раз в секунду содержимое буфера через uart)

static uint8_t     mux;
static adcsample_t adc_buffer[MAX_CH * 2];

ISR(ADCA_CH0_vect) {
  uint8_t low = ADCA.CH0.RESL;
  uint8_t high = ADCA.CH0.RESH;
  uint8_t ch = ADCA.CH0.SCAN >> 4;
  adc_buffer[mux] = ch;//result;
  mux = (mux + 1) % (MAX_CH * 2);
}

void adc_init(void) {
  // low level interrupt
  ADCA.CH0.INTCTRL= ADC_CH_INTLVL_LO_gc;
  // Scan 4 (3+1) channel startting from (MUX_POS + 0)
  ADCA.CH0.SCAN = MAX_CH-1;
  // SINGLEENDED
  ADCA.CH0.CTRL = ADC_CH_INPUTMODE_SINGLEENDED_gc;
  // AREF as Vref
  ADCA.REFCTRL = ADC_REFSEL_AREFA_gc;
  // First conv line
  ADCA.CH0.MUXCTRL = ADC_CH_MUXPOS_PIN1_gc;
  // FREERUN and unsigned mode
  ADCA.CTRLB = ADC_FREERUN_bm;
  // DIV512
  ADCA.PRESCALER = ADC_PRESCALER_DIV512_gc;
  // ENABLE and START on Channel 0
  ADCA.CTRLA = ADC_ENABLE_bm | ADC_CH0START_bm;
  /* Enable low prio int */
  PMIC.CTRL |= PMIC_LOLVLEX_bm;
}

В эрате ничего подозрительного не нашел. Есть ли люди, работающие с xmega или все ушли на кортексы?