Суть работы - опрос поочередно четырех каналов АЦП, сравнение 0-1 и 2-3 и принятие решений. Изначально АЦП у меня работал по флагу, но на макетке мусор доходил до 6 разряда!!! (выравнивание влево, первые два разряда не учитываю) потому пришлось разбираться и переводить на ADC Noise Reduction. Вот тут и появился вопрос. Вот часть прошивки:
- Код: Выделить всё • Развернуть
void on_adc_up (void)
{
ADMUX = 0x61;
unsigned char i=0;
for (i=0; i<5; i++)
{
ADCSRA |= (1<<ADEN) | (1<<ADPS1) | (1<<ADPS0) | (1<<ADIE);
MCUCR&=~(1<<SM2) | ~(1<<SM1);
MCUCR|= (1<<SM0) | (1<<SE);
ADCSR|=1<<ADSC;
asm("sleep");
asm("nop"); // ???
sum_adh += adh;
_delay_ms(25);
}
Up_Solar_ = sum_adh/5;
sum_adh=0;
}
Обработчик прерывания:
- Код: Выделить всё • Развернуть
ISR(ADC_vect)
{
cli();
MCUCR &=~(1<<SE);
ADCSRA &= ~_BV(ADIE);
adh=ADCH;
sei();
}
Так вот, без вставки asm("nop") ничего не работало, интуитивно догадался, что где-то теряю, но не понял где.
P.S. При наладке я выводил число сразу на порт, так вот, если выводил в обработчике прерываний - все ОК, если в самой функции - пусто. Объясните пожалуйста почему.
Следующий вопрос - изменение канала АЦП. В программе написаны функции последовательно для каналов 0-3, если в своем канале меняю перед спячкой MUX - ничего не происходит. Мучался всю ночь. Помогло только тогда когда в фунции я переключал на следующий канал. Так и должно быть? Тоесть я сейчас запускаю АЦП нулевого канала, а MUX надо выставить для первого?
Тертий вопрос: в начале мейна у меня идет инициализация устройства по функции Init_(). Без вставок asm("nop") фукция не отрабатывалась и программа висла, не доходя до основного цикла.
Просьба, если не сложно, обьяснить "на пальцах". Интуитивно понимаю, но хочу вникнуть. Заранее спасибо.
P.S. Dj время отладки этой программы убедился в том, что знание асма не помешало-бы.