777777 0 1 декабря, 2011 Опубликовано 1 декабря, 2011 · Жалоба В процессе отладки программы вдруг стал зависать АЦП во время его инициализации. Оказалось, он не выходит из калибровки: 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 0 1 декабря, 2011 Опубликовано 1 декабря, 2011 · Жалоба а собственно какую роль тогда играют nop ? цикл то тоже не святым духом исполняется, такие же команды проца. скорее имеется ввиду что после выключения/включения ADC обратно должно пройти как минимум 2 команды для того чтобы можно было установить бит старта калибровки. в ds например на f103vet6 вообще такого примечания нет, только указано минимальное время необходимое на калибровку. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
sevastianovd 0 2 декабря, 2011 Опубликовано 2 декабря, 2011 · Жалоба покажите весь код, касаемый ADC. работал с ним на этом-же камне - без проблем. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
777777 0 2 декабря, 2011 Опубликовано 2 декабря, 2011 (изменено) · Жалоба покажите весь код, касаемый ADC. работал с ним на этом-же камне - без проблем. Я тоже в других проектах его использовал и ничего не требовалось. Может потому, что здесь АЦП запускается от таймера? Вот вся инициализация: 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; } Изменено 2 декабря, 2011 пользователем IgorKossak [codebox] Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
sevastianovd 0 5 декабря, 2011 Опубликовано 5 декабря, 2011 · Жалоба попробуйте поднимать бит ADC_CR2_ADON отдельной командой после инициализации, т.е. непосредственно вместо nop(), а то как-то нехорошо получается сразу запускаем, а потом инитим. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
777777 0 6 декабря, 2011 Опубликовано 6 декабря, 2011 · Жалоба попробуйте поднимать бит 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 0 6 декабря, 2011 Опубликовано 6 декабря, 2011 · Жалоба я имел ввиду так 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 0 7 декабря, 2011 Опубликовано 7 декабря, 2011 · Жалоба я имел ввиду так Забыл "ИЛИ": ADC1->CR2 |= ADC_CR2_ADON; думаю, что таймер здесь непричём. скорей последовательность запусака АЦП Да, но таймер при зависшем АЦП не работал. Его выход выведен у меня наружу для контроля, так при зависании на этом выходе не было импульсов. Значит АЦП на него как-то влиял. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться