Помощь - Поиск - Пользователи - Календарь
Полная версия этой страницы: а покажите АЦП на иаре, пожалуйста
Форум разработчиков электроники ELECTRONIX.ru > Сайт и форум > В помощь начинающему
d71
поиск только запутал сильнее crying.gif
покажите как оно инициализируется и тупо в переменную результат загнать
что-то не нашел я примера, весь поиск перекопал - там всё сильно заумно : (
мне бы для старта пару строк мега и тини, всёравно
---
раньше внешний по i2c пробовал, но там совсем всё по другому
zltigo
Цитата(d71 @ Jun 3 2007, 16:06) *
там всё сильно заумно : (

"Сильно заумные" "проблемы" подобные этой желательно рассматривать в разделе для начинающих.
Перенес.
oran-be
Все равно придется ручками кнопочки на калькуляторе понажимать.


ADCSRA = (1 << ADEN)|(6 << ADPS0); //ADPS сооветствует 125кГц преобразование
//при 8Мгц тактовой
ADMUX = (3 << REFS0)|([номер канала] << MUX0);
// Здесь уже все включено, можно еще, правда поотключать цифровые входы-выходы в случае с
//мегой хх8
ADCSRA = (1 << ADIF)|(1 <<ADSC); // Запуск преобразования
while(!(ADCSRA & (1 <<ADIF);

После этого результат в ADC - можно забирать.

[quote] Оптимальная загрузка процессора - это когда cosФ его тактового генератора лежит в пределах 0.7-0.8
defunct
Пример с работы АЦП с частотой дискретизации Fdescr.
Код
#define Fosc     16000000
#define Fdescr  4000

#define ADC_CONTROL (1 << ADEN)|(1 << ADIE)|(1 << ADPS2)|(1 << ADPS1)
#define MUX_CONTROL (1 << REFS1)|(1 << REFS0)

void adc_Init(void)
{
// init sampling timer
    TIMSK |= (1 << OCIE1A);
    OCR1A = Fosc / Fdescr; // for 4Khz sampling
    TCCR1B = (1 << WGM12) | 1; // запуск таймера
    
// turn off analog comparator
    ACSR = 0x80;
    
// init Adc in single conv mode
    ADCSRA = ADC_CONTROL;
    ADMUX = MUX_CONTROL;
}


/********************************************************
* adcBeginConversion()                                  *
* ---> channel - particular MUX channel                 *
* <--- returns nothing                                  *
********************************************************/
void adcBeginConversion(U8 channel)
{
    ADMUX = (MUX_CONTROL | channel);
    ADCSRA = ADC_CONTROL | (1 << ADSC);
}


/********************************************************
*       Sampling Timer Interrupt service routine        *
********************************************************/
#pragma vector=TIMER1_COMPA_vect
__interrupt void T1OCAISRHandler(void)
{
    adcBeginConversion( 0 );
}

/********************************************************
*            ADC Interrupt service routine              *
********************************************************/
#pragma vector=ADC_vect
__interrupt void AdcISRHandler(void)
{
    U16 Val = ADC;
    ....
}
singlskv
Цитата
а покажите АЦП на иаре, пожалуйста

да пожалуйста:

АЦП
-----
IAR
smile.gif

если еще какие шарады нужно придумать, обращайтесь

Цитата(defunct @ Jun 3 2007, 18:06) *
............................

1. А зачем нужны 2 прерывания (и таймер и ADC)?
2. Почему первое преобразование начинается в прерывании таймера, а не в момент
инициализации таймера ?
3. Почему при инициализации таймера не производится первое "длинное" преобразование ?
А если выбранный частота преобразования будет легко вписываться в обычный цикл
преобразования но не будет вписываться в "длинный" ?
defunct
Цитата(singlskv @ Jun 3 2007, 20:03) *
1. А зачем нужны 2 прерывания (и таймер и ADC)?

одно соответствует моменту запуска АЦП, второе считывает и обрабатывает результат.
Сделано так - чтобы покрыть общий случай, когда какие-то действия необходимо сделать до запуска преобразования, какие-то после.

(Например, после преобразования может потребоваться переключить канал и выполнить запуск еще одного преобразования).


Цитата
2. Почему первое преобразование начинается в прерывании таймера, а не в момент
инициализации таймера ?

Чтобы было меньше исключений. Т.к. меньше исключений - меньше кода - меньше потенциальных ошибок.
Нет разницы в том откуда будет выполнен запуск первого преобразования.

Цитата
3. Почему при инициализации таймера не производится первое "длинное" преобразование ?
Потому что это делать нежелательно - чтобы не было конфликтов с запуском АЦП из разных потоков. Даже если исключить возможность конфликтов, то просто незачем добавлять дупликат кода.

Цитата
А если выбранный частота преобразования будет легко вписываться в обычный цикл
преобразования но не будет вписываться в "длинный" ?

Опять единичное исключение. Это не важно, т.к. длинное преобразование выполняется только один раз. Все остальные будут короткими. Но если для вас рез-тат первого преобразования важен, тогда вы можете уменьшить предделитель АЦП - чтобы время преобразования вписывалось в цикл перезапуска.
d71
ВО, СПАСИБИЩЕ ВСЕМ : )
стартанул, результ читаю : ) дальше я сам
Andrеys
искал то же самое, сделал также - не работает.
У меня кварц на 8 Мгц, выбран нужный вход, частота преобразования как в примере выше (от oran-be), контроллер АТмега8.
все хорошо, пока не появляется в коде строка while( !(ADCSR & (1<<ADIF)) );
она означает конец преобразования, как я понял, так вот его похоже не происходит!
конроллер сразу после прошивки вешается, отображает всякую белиберду, не опрашивает клавиатуру, не регагирует ни на что 05.gif
Подскажите пожалуйста, что бы это могло быть???
Andrеys
причина была найдена!
мне кажется, кусок проги из текста выше нерабочий, и вот почему:

ADCSRA = (1 << ADEN)|(6 << ADPS0); //ADPS сооветствует 125кГц преобразование
//при 8Мгц тактовой
ADMUX = (3 << REFS0)|([номер канала] << MUX0);
// Здесь уже все включено, можно еще, правда поотключать цифровые входы-выходы в случае с
//мегой хх8
ADCSRA = (1 << ADIF)|(1 <<ADSC); // Запуск преобразования
while(!(ADCSRA & (1 <<ADIF);


обратите внимание на красную строку, с регистром ADCSRA делают операцию присваивания, а не поразрядное ИЛИ с присваиванием, таким образом в регистр пишется 2 единички, а остальные - нули, один из которых ADEN, преобразование в итоге запрещено.
правильно так ADCSRA |= (1 << ADIF)|(1 <<ADSC);
sKWO
Цитата(Andrеys @ Aug 16 2007, 12:42) *
причина была найдена!
мне кажется, кусок проги из текста выше нерабочий, и вот почему:

[i]ADCSRA = (1 << ADEN)|(6 << ADPS0); //ADPS сооветствует 125кГц преобразование
обратите внимание на красную строку, с регистром ADCSRA делают операцию присваивания, а не поразрядное ИЛИ с присваиванием, таким образом в регистр пишется 2 единички, а остальные - нули, один из которых ADEN, преобразование в итоге запрещено.
правильно так ADCSRA |= (1 << ADIF)|(1 <<ADSC);

разрешено, смотрите внимательно
#define ADC_CONTROL (1 << ADEN)|(1 << ADIE)|(1 << ADPS2)|(1 << ADPS1)
ADCSRA = ADC_CONTROL | (1 << ADSC);
таким образом в регистре ADCSRA добавится один битик под номером ADSC которій определён
в хедерном файле выбранного МК.

Смотрите значение ADC_CONTROL.
Andrеys
sKWO: это вы у участника defunct посмотрели, у него правильно smile.gif , а я про прогу еще выше написанную говорил, которая от oran-be, там у него присвоить одну единичку и кучу нулей, вместо наложить маску для изменения только одного бита. biggrin.gif палочки такой | перед равно, короче, не хватает.
Для просмотра полной версии этой страницы, пожалуйста, пройдите по ссылке.
Invision Power Board © 2001-2025 Invision Power Services, Inc.