Помощь - Поиск - Пользователи - Календарь
Полная версия этой страницы: Калибровка АЦП
Форум разработчиков электроники ELECTRONIX.ru > Микроконтроллеры (MCs) > ARM
777777
В процессе отладки программы вдруг стал зависать АЦП во время его инициализации. Оказалось, он не выходит из калибровки:

Код
    ADC1->CR2 |= ADC_CR2_RSTCAL;                        // reset calibration
    while(ADC1->CR2 & ADC_CR2_RSTCAL)                    // wait until reset finished
        {}

Выяснилось, что если перед ним поставить два или более NOP-ов, то он начинает работать. В даташите нашел следующий абзац:
Цитата
Before starting a calibration the ADC must have been in power-off state (ADON bit = ‘0’) for
at least two ADC clock cycles.

Как это понимать? Калибровка производится при включении питания, поэтому он находится в power-off state гораздо больше, чем два clock cycles.
Может наоборот, после включения ADON должно пройти не менее двух циклов? Тогда это объясняет помощь NOP-ов.
Shaeto
а собственно какую роль тогда играют nop ? цикл то тоже не святым духом исполняется, такие же команды проца. скорее имеется ввиду что после выключения/включения ADC обратно должно пройти как минимум 2 команды для того чтобы можно было установить бит старта калибровки.
в ds например на f103vet6 вообще такого примечания нет, только указано минимальное время необходимое на калибровку.
sevastianovd
покажите весь код, касаемый ADC. работал с ним на этом-же камне - без проблем.
777777
Цитата(sevastianovd @ Dec 2 2011, 13:03) *
покажите весь код, касаемый ADC. работал с ним на этом-же камне - без проблем.


Я тоже в других проектах его использовал и ничего не требовалось. Может потому, что здесь АЦП запускается от таймера? Вот вся инициализация:

CODE
void ADC1Setup()
{
// TIM4
RCC->APB1ENR |= RCC_APB1ENR_TIM4EN; // TIM4 Periph clock enable

TIM4->PSC = 1; // Prescaler = 27.778 ns
TIM4->ARR = 297-1; // Auto reload value 297*27.778 = 8.25 us,
// 6 отсчетов на импульс длительностью 49.5 us
TIM4->CCR4 = 50; // контрольный выход на PB9
TIM4->CCMR1 = 0;
TIM4->CCMR2 = TIM_CCMR2_OC4M(6); // channel 4
TIM4->CCER = TIM_ER_CC4E; // set capture/compare enable register

// ADC1
RCC->APB2ENR |= RCC_APB2ENR_ADC1EN; // enable clock for ADC1

ADC1->CR1 = ADC_CR1_SCAN | ADC_CR1_EOCIE;
ADC1->CR2 = ADC_CR2_EXTSEL(5) | // Timer 4 CC4 event
ADC_CR2_EXTTRIG | // EXTTRIG
ADC_CR2_ADON;
ADC1->SMPR1 =ADC_SMPR1_SMP12(0); // set sample time (1,5 cycles)

ADC1->SQR3 = ADC_SQR3_SQ1(12);
ADC1->SQR2 = 0;
ADC1->SQR1 = ADC_SQR1_L(0);

__nop();
__nop();
__nop();
__nop();
__nop();
ADC1->CR2 |= ADC_CR2_RSTCAL; // reset calibration
while(ADC1->CR2 & ADC_CR2_RSTCAL) // wait until reset finished
{}
ADC1->CR2 |= ADC_CR2_CAL; // start calibraton
while(ADC1->CR2 & ADC_CR2_CAL) // wait until calibration finished
{}

NVIC->ISER[0] = (1 << (ADC1_2_IRQChannel & 0x1F)); // enable interrupt ADC1_2
TIM4->CR1 |= TIM_CR1_CEN;
}
sevastianovd
попробуйте поднимать бит ADC_CR2_ADON отдельной командой после инициализации, т.е. непосредственно вместо nop(),
а то как-то нехорошо получается сразу запускаем, а потом инитим.
777777
Цитата(sevastianovd @ Dec 5 2011, 06:12) *
попробуйте поднимать бит ADC_CR2_ADON отдельной командой после инициализации, т.е. непосредственно вместо nop(),
а то как-то нехорошо получается сразу запускаем, а потом инитим.

Ты имеешь в виду так:

Код
    ADC1->CR2  = ADC_CR2_EXTSEL(5) |                    // Timer 4 CC4 event
                 ADC_CR2_EXTTRIG;                        // EXTTRIG
    ADC1->CR2  |= ADC_CR2_ADON;

Будешь смеяться, но это помогло. Теперь не зависает даже без нопов.

Кстати, когда он зависал, то не работал даже таймер 4. Как таймер мог влиять на калибровку АЦП?
sevastianovd
я имел ввиду так
CODE

ADC1->CR1 = ADC_CR1_SCAN | ADC_CR1_EOCIE;
ADC1->CR2 = ADC_CR2_EXTSEL(5) | // Timer 4 CC4 event
ADC_CR2_EXTTRIG ; // EXTTRIG


ADC1->SMPR1 =ADC_SMPR1_SMP12(0); // set sample time (1,5 cycles)

ADC1->SQR3 = ADC_SQR3_SQ1(12);
ADC1->SQR2 = 0;
ADC1->SQR1 = ADC_SQR1_L(0);

ADC1->CR2 =ADC_CR2_ADON;

думаю, что таймер здесь непричём. скорей последовательность запусака АЦП
777777
Цитата(sevastianovd @ Dec 6 2011, 12:17) *
я имел ввиду так

Забыл "ИЛИ":

Код
ADC1->CR2 |= ADC_CR2_ADON;

Цитата(sevastianovd @ Dec 6 2011, 12:17) *
думаю, что таймер здесь непричём. скорей последовательность запусака АЦП

Да, но таймер при зависшем АЦП не работал. Его выход выведен у меня наружу для контроля, так при зависании на этом выходе не было импульсов. Значит АЦП на него как-то влиял.
Для просмотра полной версии этой страницы, пожалуйста, пройдите по ссылке.
Invision Power Board © 2001-2025 Invision Power Services, Inc.