Перейти к содержанию
    

Atmega48 запуск АЦП по внешнему сигналу

Есть такой код

#include <stdint.h>
#include <avr/io.h>
#include <avr/interrupt.h>
//#include "PortDefine.h"
#include "avrlibdefs.h"
#include "avrlibtypes.h"

//#define USE_INT0

union {
uint16_t ADC_Data;
uint8_t ADC_Bute[2];
} Data;

#ifdef USE_INT0
ISR (INT0_vect)
{
ADCSRA |= (1 << ADSC);
}
#endif // USE_INT0

ISR (ADC_vect)
{
PORTD |= 1;
Data.ADC_Data = (unsigned short)inb(ADCL) | (unsigned short)(inb(ADCH) << 8);
PORTD &=~ 1;
}

int main( void )
{
// ADC
ADMUX |= (1 << REFS0) | (1 << MUX0) | (1 << MUX2); // ADC5, AVCC
ADCSRA |= (1 << ADEN) | (1 << ADATE) | (1 << ADIE);
ADCSRB |= (1 << ADTS1);
DDRC = 0;
PORTC = 0;


#ifdef USE_INT0
EICRA |= (1 << ISC01) | (1 << ISC00);
EIMSK |= (1 << INT0);
#endif // USE_INT0


DDRD = 0x03;
PORTD = 4;

sei();

ADCSRA |= (1 << ADSC);
while (1)
{
	PORTD ^= 2;
}
return 0;
}

По идеи он должен запускать оцифровку по внешнему сигналу, но этого не происходит.

Если я открываю строку //#define USE_INT0 всё работает правильно, но при этом теряется время.

Строку инициализации EICRA убирал из под ифа, не помогает.

Может я чего в инициализации упускаю.

Изменено пользователем IgorKossak
[codebox] для длинного кода, [code] - для короткого!!!

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Я обычно запускаю АЦП от сигнала таймера, но и для внешнего прерывания должно быть аналогично.

1. Настраиваю АЦП, там мои макросы, но надеюсь будет понятно

    adc_enable        ();
    adc_mode_trigger  ();
    adc_set_source    (ADC_SOURCE_TC0_CMPA);
    adc_set_prescaler (ADC_PRESCALE_DIV64); // or 128 ??
    adc_set_reference (ADC_REFERENCE_AVCC); 
    adc_left_adjusted ();    // ADLAR = 1
    //    adc_right_adjusted();    // ADLAR = 0
    adc_int_enable    ();
    adc_set_channel   (0x00); // начальный канал

2. настраиваю таймер

    timer0_init        (TIMER0_MODE_CTC,    T0_TICK *TIME_1MS);    // for ADC

3. пишу обрабртчик таймера, если не нужен - то делаем его пустой

ISR(TIMER0_COMPA_vect)
{    timer0_tick    += T0_TICK;
}

4. пишу обработчик АЦП, например так

ISR(ADC_vect)
{     rms.val = ADCH;
    adc_flag = 1;
}

 

Соответственно с внешним прерыванием аналогично:

1. прерывание ExtINT0 должно быть настроено и включено, иначе откуда будет подаваться сигнал на АЦП?

2. для избежания косяков, необходимо написать обработчик ExtINT0, пусть даже и пустой

3. в этом обработчике НЕ НАДО напускать АЦП, иначе это будет ПЕРЕЗАПУСК, запуск АЦП делает логика МК, которая подключает старт АЦП от внешнего прерывания. А вот само прерывание должно обрабатывать аппаратная логика этого прерывания

4. что за, извиняюсь, гуанокод?

    ADMUX |= (1 << REFS0) | (1 << MUX0) | (1 << MUX2); // ADC5, AVCC
    ADCSRA |= (1 << ADEN) | (1 << ADATE) | (1 << ADIE);
    ADCSRB |= (1 << ADTS1);

Вы же однократно и один раз в начале програмы инициализируете АЦП, зачем там "|=" ? уберите их

ADMUX = (1 << REFS0) | (1 << MUX0) | (1 << MUX2); // ADC5, AVCC
    ADCSRA = (1 << ADEN) | (1 << ADATE) | (1 << ADIE);
    ADCSRB = (1 << ADTS1);

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Так как Вы описали инициализацию работает, но выигрыш во времени не впечатлил, Atmega48, 10МГц, с запуском АЦП в обработчике внешнего прерывания от начала входного импульса на INT0 до начала прерывания АЦП 66,8 мкс, а тоже время с автоматическим запуском составляет 46,4 мкс.

 

По поводу |= или =. В данном случае это эквивалентно, т.к. регистры по умолчанию равны 0. Но |= всё таки правильнее, это нужно, что бы не повреждать те биты которые нужны для других целей.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Но |= всё таки правильнее, это нужно, что бы не повреждать те биты которые нужны для других целей.
В данном случае вы инициализируете. И вам нужно не "не повредить" их, а вам нужно, чтобы в них были нули. Поэтому именно здесь правильнее "=". Кроме того, это даст более короткий код.

 

 

но выигрыш во времени не впечатлил
Какой выигрыш? АЦП запускается или сразу (аппаратно) или с задержкой (вручную в обработчике). Остальное время уходит на преобразование. Максимальная тактовая для АЦП (для получения 10 бит) - 1 МГц, вы можете затактировать АЦП частотой 10 МГц / 16 = 625 КГц, преобразование занимает 13.5 тактов, т.е. 21.6 мкС - это максимум, что можно выжать для вашего кварца и 10 бит. 40 мкС должно занимать первое преобразование после переключения канала. В вашем коде я не вижу смены канала, значит уже второе преобразование должно закончиться через 21.6 мкС. Но это только при условии, что вы настроите тактирование. В вашем коде я не вижу настройки предделителя АЦП, значит оно работает на 5 МГц и если при этом вы наблюдаете время преобразования 44 мкС, то я могу только предположить, что ваш процессор вместо 10 МГц работает от внутреннего RC-генератора деленного на 8, т.е. на 1 МГц. Хотя и тогда должно получиться около 27 мкС. В общем показывайте последний код, телепатировать не хочется.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Сергей, а где Вы нашли

Максимальная тактовая для АЦП (для получения 10 бит) - 1 МГц
?

Я знаю только

By default, the successive approximation circuitry requires an input clock frequency between 50 kHz and 200 kHz to get maximum resolution. If a lower resolution than 10 bits is needed, the input clock frequency to the ADC can be higher than 200 kHz to get a higher sample rate.

 

Да, согласен, Oleg_IT нужно выставить предделитель для АЦП для лучшей точности измерения. Совсем выпустил это из виду.

 

 

 

Упс, нашел, таблица 28-7. частота АЦП от 50 до 1000 кГц.

Изменено пользователем alexeyv

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Присоединяйтесь к обсуждению

Вы можете написать сейчас и зарегистрироваться позже. Если у вас есть аккаунт, авторизуйтесь, чтобы опубликовать от имени своего аккаунта.

Гость
Ответить в этой теме...

×   Вставлено с форматированием.   Вставить как обычный текст

  Разрешено использовать не более 75 эмодзи.

×   Ваша ссылка была автоматически встроена.   Отображать как обычную ссылку

×   Ваш предыдущий контент был восстановлен.   Очистить редактор

×   Вы не можете вставлять изображения напрямую. Загружайте или вставляйте изображения по ссылке.

×
×
  • Создать...