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

 
 
 
Reply to this topicStart new topic
> Помогите настроить АЦП в ATMEGA16
Vladimir Semenov
сообщение Dec 9 2012, 16:31
Сообщение #1





Группа: Новичок
Сообщений: 3
Регистрация: 9-12-12
Пользователь №: 74 777



Доброго времени суток, уважаемые форумчане! Опыт работы с микроконтроллерами у меня весьма мал, начал погружаться в эту тему, т.к. по работе нужно. Дошел до изучения работы с АЦП в ATMEGA 16. Сейчас у меня стоит задача - нужно сделать так, чтобы АЦП с как можно большей частотой в реальном времени оцифровывал входной сигнал и сразу же передавал его на один из портов (а дальше там уже ЦАП). Получается этакий повторитель - выходной сигнал равен входному.
Программы пишу на Си в CodeVisionAVR. Вот текст программы:

CODE
// Программа для работы с встроенным АЦП микроконтроллера ATmega16.
// Микроконтроллер оцифровывает входное напряжение и подает его на выход,
// где подразумевается наличие ЦАП - таким образом реализуется повторение
// входного сигнала на выходе.

// Используемые библиотеки:
#include <mega16.h>

// Начало программы
void main(void)
{
// Настраиваем порты:
DDRA = 0b00000000; // Все выводы порта А настраиваем на входы (0 - вход, 1 - выход)
PORTA = 0b11111111; // Подключаем внутренние подтягивающие резисторы к выводам порта A.


DDRC=0b11111111; // Все выводы порта C настраиваем как выходы (0 - вход, 1 - выход)
PORTC=0b00000000; // Обнуляем порт С до начала выполнения программы (на всякий случай)

// Настраиваем встроенный АЦП:
ADCSRA = 0b11100100; // включить АЦП, запустить преобразование, непрерывный режим работы, частота считывания 750kHz (12MHz/16)
ADMUX = 0b01100000; /* источник опорного напряжения - источник питания МК - 5 В, выравнивание слева (используем
только 8 бит регистра ADCH), входной канал ADC0 */
SFIOR = 0b00000000;

//Основная программа
while(1)
{
PORTC=ADCH; //вывести в порт С значение, полученное в результате считывания

}
}

программа не работает (но компилируется нормально)

Вопросы такие: Правильно ли я настроил АЦП? Нужно ли перед настройкой АЦП настраивать порт А как вход ( т.к. ADC0 соответствует входу PA0)? Корректна ли такая настройка АЦП без настройки прерываний и т.д.?

За любую помощь буду очень благодарен! Не судите строго - я только начинающий...

Сообщение отредактировал IgorKossak - Dec 9 2012, 16:59
Причина редактирования: [codebox] для длинного кода, [code] - для короткого!!!
Go to the top of the page
 
+Quote Post
_Артём_
сообщение Dec 9 2012, 17:37
Сообщение #2


Гуру
******

Группа: Свой
Сообщений: 2 128
Регистрация: 21-05-06
Пользователь №: 17 322



Цитата(Vladimir Semenov @ Dec 9 2012, 18:31) *
PORTA = 0b11111111; // Подключаем внутренние подтягивающие резисторы к выводам порта A.

Уверены, что вам нужны подтягивающие резисторы?

Цитата(Vladimir Semenov @ Dec 9 2012, 18:31) *
// Настраиваем встроенный АЦП:
ADCSRA = 0b11100100; // включить АЦП, запустить преобразование, непрерывный режим работы, частота считывания 750kHz (12MHz/16)

750 - это не частота оцифровки, а частота которой тактируется АЦП. Пребразование занимает ещё сколько циклов (12 или 13 - смотрите в ДШ).
Частота получения навых отсчётов будет - 12МГц/16/12 (или 13).

Цитата(Vladimir Semenov @ Dec 9 2012, 18:31) *
//Основная программа
while(1)
{
PORTC=ADCH; //вывести в порт С значение, полученное в результате считывания

}
}

Почему бы не проверять флаг готовности нового результата, и если готово, то считывать?

Цитата(Vladimir Semenov @ Dec 9 2012, 18:31) *
программа не работает (но компилируется нормально)

В чём это выражается?

Цитата(Vladimir Semenov @ Dec 9 2012, 18:31) *
Вопросы такие: Правильно ли я настроил АЦП?
Нужно ли перед настройкой АЦП настраивать порт А как вход ( т.к. ADC0 соответствует входу PA0)? Корректна ли такая настройка АЦП без настройки прерываний и т.д.?

Настройка на вход, точно не повредит.
Можно без прерываний.


Go to the top of the page
 
+Quote Post
Vladimir Semenov
сообщение Dec 9 2012, 17:49
Сообщение #3





Группа: Новичок
Сообщений: 3
Регистрация: 9-12-12
Пользователь №: 74 777



Цитата(_Артём_ @ Dec 9 2012, 20:37) *
Уверены, что вам нужны подтягивающие резисторы?

-не уверен - по привычке подключил от греха подальше

750 - это не частота оцифровки, а частота которой тактируется АЦП. Пребразование занимает ещё сколько циклов (12 или 13 - смотрите в ДШ).
Частота получения навых отсчётов будет - 12МГц/16/12 (или 13).

-спасибо большое за уточнение - буду знать

Почему бы не проверять флаг готовности нового результата, и если готово, то считывать?

- а как это сделать? всм где находится этот флаг?

В чём это выражается?

- при моделировании в Proteus ничего не появляется на выходе, после прошивки настоящий МК тоже ничего не выдавал, завтра на работе опять пробовать буду...

Настройка на вход, точно не повредит.
Можно без прерываний.

- успокоили))))))

Go to the top of the page
 
+Quote Post
_Артём_
сообщение Dec 9 2012, 18:15
Сообщение #4


Гуру
******

Группа: Свой
Сообщений: 2 128
Регистрация: 21-05-06
Пользователь №: 17 322



Цитата
Уверены, что вам нужны подтягивающие резисторы?

-не уверен - по привычке подключил от греха подальше

Если отключите, то будет ещё дальше от греха.

Цитата
Почему бы не проверять флаг готовности нового результата, и если готово, то считывать?
- а как это сделать? всм где находится этот флаг?


Код
if (ADCSRA&(1<<ADIF)) {
    PORTC=ADCH;
    ADCSRA |= (1<<ADIF);
}

Или можно использовать прерывание ADC Complete, тогда очистка будет аппаратной.

Цитата
- при моделировании в Proteus ничего не появляется на выходе,

А Proteus умеет АЦП эмулировать?
Только "железу" можно верить.

Ещё момент:
Цитата
• Bit 5 – ADATE: ADC Auto Trigger Enable
When this bit is written to one, Auto Triggering of the ADC is enabled. The ADC will start
a conversion on a positive edge of the selected trigger signal.
The trigger source is
selected by setting the ADC Trigger Select bits, ADTS in SFIOR

У вас триггером является флаг ADIF, в программе он не сбрасывается и всё время равен 1. Никакого перепада не возникает.
Может причина в этом.
Go to the top of the page
 
+Quote Post
Vladimir Semenov
сообщение Dec 11 2012, 08:21
Сообщение #5





Группа: Новичок
Сообщений: 3
Регистрация: 9-12-12
Пользователь №: 74 777



Цитата(_Артём_ @ Dec 9 2012, 21:15) *
Если отключите, то будет ещё дальше от греха.



Код
if (ADCSRA&(1<<ADIF)) {
    PORTC=ADCH;
    ADCSRA |= (1<<ADIF);
}

Или можно использовать прерывание ADC Complete, тогда очистка будет аппаратной.


А Proteus умеет АЦП эмулировать?
Только "железу" можно верить.

Ещё момент:

У вас триггером является флаг ADIF, в программе он не сбрасывается и всё время равен 1. Никакого перепада не возникает.
Может причина в этом.


Спасибо огромное!!!)))) Все заработало!!!)))) Действительно, нужно было проверять флаг готовности нового результата АЦП, прежде чем считывать)))) Буду дальше разбираться и изучать)))))
Go to the top of the page
 
+Quote Post

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

 


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


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