реклама на сайте
подробности

 
 
> Переключение между каналами АЦП, ATmega32
B_Sergey_N
сообщение Sep 28 2008, 18:41
Сообщение #1


Участник
*

Группа: Новичок
Сообщений: 17
Регистрация: 28-07-08
Из: г. Санкт-Петербург
Пользователь №: 39 246



Всем привет.
Как можно переключаться между каналами АЦП? К примеру, мне необходимо:
сделать преобразование, прочитать один канал (Vbg), затем опять сделать преобразование и прочитать канал ADC0.

Выкладываю код, переключения между каналами не происходит.

Код
#include <util/delay.h>
#include <avr/io.h>
#include <avr/interrupt.h>

#define F_CPU 16000000

int i, flag, t;

void main(void)
{

DDRA |= (1 << 1)|(1 << 2)|(1 << 6)|(1 << 7);         // Инициализация светодиодов

ADCSRA |= (1 << ADPS2) | (1 << ADPS1) | (1 << ADPS0); // Установка частоты преобразования 125KHz

ADCSRA |= (1 << ADEN);              // Вкл. АЦП

ADCSRA |= (1 << ADIE);              // Разрешение прерывания от компаратора
sei();


    for(;;)
    {
        
    flag = 1;
    ADMUX |= (1 << 1)|(1 << 2)|(1 << 3)|(1 << 4);     // Выбор входного канала АЦП - Vbg
                ADCSRA |= (1 << ADSC);        // Запуск преобразования
        

                                flag = 0;
        ADMUX |= 0;             // Выбор входного канала АЦП - ADC0
        ADCSRA |= (1 << ADSC);        // Запуск преобразования
    }

}

//********************************************************************************//

ISR(ADC_vect)
{
        
         if (flag == 1)
            {
             i = ADCL;        // Чтение младших 8 битов первыми
             i += (int)ADCH << 8;    // Чтение старших 2 битов, умножение их на 256 и сложение с мл. б.
            
            if (i < 255)
            {
            // Питание контроллера падает
            _delay_ms(200);

            PORTA |= (1 << 6);
        
            _delay_ms(200);
        
            PORTA &= ~(1 << 6);
            }
            }

    
    if (flag == 0)
    {
        
    t = ADCL;        // Чтение младших 8 битов первыми
    t += (int)ADCH << 8;    // Чтение старших 2 битов, умножение их на 256 и сложение с мл. б.
        
        if (t < 830)
        {
        _delay_ms(200);

        PORTA |= (1 << 1);
        
        _delay_ms(200);
        
        PORTA &= ~(1 << 1);
        }
            
            else
            {
                
                _delay_ms(200);

                PORTA |= (1 << 2);
        
                _delay_ms(200);
        
                PORTA &= ~(1 << 2);
            }

    }


}


Не знаю, необходим ли reti из прерывания?
Go to the top of the page
 
+Quote Post
 
Start new topic
Ответов
SysRq
сообщение Sep 28 2008, 22:36
Сообщение #2


Чайник, 1 литр
****

Группа: Свой
Сообщений: 655
Регистрация: 17-05-06
Из: Moscow
Пользователь №: 17 168



0) F_CPU следует определить в makefile, или до включения delay.h;
1) Здесь прерывание следует использовать лишь в том случае, если между запуском АЦ-преобразования и собстно его завершением вы занимаетесь какой-то другой полезной работой;
2) Прерывание будет срабатывать не по вашей задумке, т.к., как уже подметил smac, или необходимо ждать завершения текущего преобразования перед сменой флага и канала (просто ждать нельзя, см пункт 2 -- теряется целесообразность вообще прерывания), либо исключить ситуацию что флаг меняется до срабатывания прерывания (например, АЦ-преобразование по второму каналу пусть запускается из прерывания, после оконцания работы с 1-м каналом). Регистры АЦП-блока буферизуются (если идет АЦ-преобразование, то запись в регистры не повлияет на текущее преобразование), и таким образом у вас преобразование выполнится для одного канала, а результаты воспримутся как для другого...

Примерчик простой реализация преобразования без прерываний:
CODE

/* ATMega103 (128 with M103C programmed */

#define BIT(x) (1 << (x))

WORD DoADC(BYTE _ADMUX)
{
WORD value;

ADMUX = _ADMUX;

_delay_ms(250); // Wait till signals are stabilized

ADCSR |= BIT(ADSC); // Start conversion
while(ADCSR & BIT(ADSC)); // Wait till conversion done

*((BYTE *) &value) = ADCL; // Read lower byte
*(((BYTE *) &value) + 1) = ADCH; // Read higher byte

return value;
}

void GetVoltages(void)
{
ADCSR = BIT(ADEN) | BIT(ADSC) | BIT(ADPS2) | BIT(ADPS1) | BIT(ADPS0); // Enable ADC, start dummy conversion to init ADC
while(ADCSR & BIT(ADSC)); // Wait till dummy conversion done

voltage1 = DoADC(0x00); // AREF, single ended input - PORTF0
voltage2 = DoADC(BIT(MUX0)); // AREF, single ended input - PORTF1
voltage3 = DoADC(BIT(MUX1)); // AREF, single ended input - PORTF2
voltage4 = DoADC(BIT(MUX1) | BIT(MUX0)); // AREF, single ended input - PORTF3

ADCSR = 0; // disable ADC
}
Go to the top of the page
 
+Quote Post

Сообщений в этой теме
- B_Sergey_N   Переключение между каналами АЦП   Sep 28 2008, 18:41
- - Николай Иванович Приходько   Не забывайте делать задержку после включения ADC б...   Sep 28 2008, 19:02
|- - singlskv   Цитата(Николай Иванович Приходько @ Sep 28 20...   Oct 4 2008, 20:38
|- - Николай Иванович Приходько   Цитата(singlskv @ Oct 5 2008, 00:38) Стра...   Oct 7 2008, 09:03
|- - VladimirYU   Цитата(Николай Иванович Приходько @ Oct 7 200...   Oct 7 2008, 12:33
|- - singlskv   Цитата(Николай Иванович Приходько @ Oct 7 200...   Oct 7 2008, 18:22
- - smac   Цитата(B_Sergey_N @ Sep 28 2008, 22:41) ....   Sep 28 2008, 21:23
- - domowoj   Я не силен в СИ, но после каждого ночала преобразо...   Sep 29 2008, 02:09
- - VladimirYU   Цитата(B_Sergey_N @ Sep 28 2008, 22:41) В...   Sep 29 2008, 09:47
- - hainiken   по ДШ вроде 125 мкС мин. паузу рекомендуют, а напр...   Oct 4 2008, 20:15
- - domowoj   УВХ начинает работать вместе с АЦП, на то оно и УВ...   Oct 5 2008, 14:22
|- - singlskv   Цитата(domowoj @ Oct 5 2008, 18:22) УВХ н...   Oct 5 2008, 15:47
- - domowoj   На конденцаторе хранения УВХ напряж.запоминается в...   Oct 5 2008, 16:21
|- - singlskv   Цитата(domowoj @ Oct 5 2008, 20:21) На ко...   Oct 5 2008, 16:43
- - B_Sergey_N   Большое спасибо всем за ответы!!! Особ...   Oct 5 2008, 17:31
- - rudy_b   Что-то я не понимаю, вы про какой проц говорите? Е...   Oct 5 2008, 18:23
|- - singlskv   Цитата(rudy_b @ Oct 5 2008, 22:23) Что-то...   Oct 5 2008, 18:34
- - domowoj   Вывод! Делай все как надо - и не будет никаких...   Oct 6 2008, 00:34
- - domowoj   Вот на русском, почти даташиит(хотя и не без ошибо...   Oct 7 2008, 14:29
- - Николай Иванович Приходько   Цитата(domowoj @ Oct 7 2008, 18:29) Перво...   Oct 7 2008, 18:35
- - singlskv   Цитата(Николай Иванович Приходько @ Oct 7 200...   Oct 7 2008, 18:46
|- - Николай Иванович Приходько   Цитата(singlskv @ Oct 7 2008, 22:46) для ...   Oct 7 2008, 19:01
|- - singlskv   Цитата(Николай Иванович Приходько @ Oct 7 200...   Oct 7 2008, 19:10
- - domowoj   Цитата(Николай Иванович Приходько @ Oct 8 200...   Oct 8 2008, 03:18


Reply to this topicStart new topic
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0

 


RSS Текстовая версия Сейчас: 19th June 2025 - 18:32
Рейтинг@Mail.ru


Страница сгенерированна за 0.01384 секунд с 7
ELECTRONIX ©2004-2016