Страница 1 из 1

АЦП у Меги16

Добавлено: Сб ноя 15, 2008 16:14:45
Денис203
Здравствуйте...
помогите , пожалуйста с работой АЦП у меги16
..сам принцип работы....
мы должны подключать дополнительно таймер, для того чтобы по прерыванию таймера оцифровывать.... или надо без таймера...?
он сам будет с частотой оцифровывать?
т.е сам принцип работы..... и еще прошу помочь разобраться с регистром ADMUX....с остальными битами, кроме выбора входов АЦП....

Добавлено: Сб ноя 15, 2008 18:59:21
Денис203
и еще вопрос.... как в Меге 16 точно называется прерывание ADC...
пишу в Авр Студио... смотрю в даташите,, там просто ADC,,, пишу в программе,, он выделяет его синим,, типо это такой оператор....
в блокноте def.inc к этой меге, написано ADCC,, и так пишу,, но он на него не переходит....

Добавлено: Сб ноя 15, 2008 21:40:23
biDE
мы должны подключать дополнительно таймер, для того чтобы по прерыванию таймера оцифровывать.... или надо без таймера...?
он сам будет с частотой оцифровывать?

можно и с таймером и без, все зависит от конкретной задачи и подробно описанов даташите.
и еще прошу помочь разобраться с регистром ADMUX

а в чем собственно вопрос? в ADMUXе выбирается источник опорного напряжения, нужный аналоговый вход (прямой или дифференциальный) и вид результата, опять же даташит.
как в Меге 16 точно называется прерывание ADC

А как его сами назовете, так и будет, никто не запрещает назвать его как угодно. Я например, называю ADC_COMP

Добавлено: Вс ноя 16, 2008 09:00:30
Денис203
вот текст программы,,, вернее ее начальной и элементарной части.....
все вроде расставлено по местам.... все по адпесам, напомню, что пишу для меги16..... а при уст флага прерывания ADC,,,он не переходит на вектор ADC,, а начинает программу заного.....

Добавлено: Вс ноя 16, 2008 10:37:59
Денис203
Так,, вот что происходит.... на одном компьютере все хорошо,, делает без пробьлем hex файл, а на другом вот как раз на том, на котором все писал, не хочет,, пишет что с адресами что-то не то....

Добавлено: Вс ноя 16, 2008 13:46:42
biDE
Денис203 писал(а):все вроде расставлено по местам.... все по адпесам

Не все, в таблице прерываний у меги16 каждый вектор имеет длину два слова, а не одно, поэтому вместо инструкции rjmp в даташите используются jmp.

Добавлено: Вс ноя 16, 2008 16:54:35
TechMike
Денис203 писал(а):Так,, вот что происходит.... на одном компьютере все хорошо,, делает без пробьлем hex файл, а на другом вот как раз на том, на котором все писал, не хочет,, пишет что с адресами что-то не то....


Что конкретно за ошибку пишет?
Ниже исходник для mega16+winavr+avr studio. Буквально недавно разбирался с АЦП, и у меня все получилось(внимательно надо прочитать даташит).
Обязательно ногу AREF посадить на +5в(если опорник внешний), у меня из-за этого выдавало всякую фигню, на выходе преобразования.
Ну и поставить делитель по входу АЦП, чтобы нога не была в воздухе.

Код: Выделить всё

volatile unsigned char  ADCresult=0; //флаг возникновения прерывания от АЦП
unsigned char ADCinPin=0; // по какому входу PORTA выполяняется измерение
unsigned int  ADCcountConv=2; //кол-во измерений данных на одном входе, сохраняется только последнее измерения, остальные холостые
unsigned char ADCcountConv_tmp=1; //храним кол-во сделаных преобразований
unsigned int  ADCPin[8]={0,0,0,0,0,0,0,0}; // массив для хранения измереных данных с АЦП
unsigned char ADCmaxCount=4; // кол-во проходов измерений АЦП до принятия решения(сколько раз мерять на всех входах, а потом уже решать что делать)
unsigned char ADCmaxCount_tmp=1; // кол-во проходов измерений АЦП до принятия решения(сколько раз мерять на всех входах, а потом уже решать что делать)
unsigned char ADCok; // флаг окончания преобразований, после которых можно принимать решение по результатам измерений
unsigned int  ADCPin1; // для хранения измереных данных с АЦП

unsigned char i=0; // временная переменная
SIGNAL(SIG_ADC){
//ловим окончание преобразования АЦП
 ADCresult=1;
}

int main(void)
  {
// настраиваем порты(ножки)
//настраиваем АЦП
DDRA=0x00;//весь PORTA делаем входом
PORTA=0x00;//no Pull-up
ADMUX=0x0;
ADMUX|=(0<<MUX2)|(0<<MUX1)|(0<<MUX0)|(0<<REFS0)|(0<<REFS1); //select ADC0 and AREF, Internal Vref turned off


SFIOR|=(1<<ACME);//enable multiplexer   

ACSR|=   (0<<ACD)|   //Comparator ON
(1<<ACIE)|   //Comparator Interrupt enable
(0<<ACIC)|   //input capture disabled
(0<<ACIS1)| //set interrupt on output toggle
(0<<ACIS0);

//ADCSRA=0x0;
ADCSRA|=(1<<ADEN);//make sure ADC is ON
ADCSRA|=(1<<ADIE);//ADC Interrupt Flag ON
ADCSRA|=(1<<ADSC>=ADCcountConv)
while(1)
 { //начало бесконечного цикла

if (ADCresult==1)
{
 if (ADCcountConv_tmp>=ADCcountConv)
 { //пропускаем холостые циклы преобразования
  ADCPin1=ADC; //читаем полученое преобразование
  ADCcountConv_tmp=1; //обнуляем цикл для холостых пребразований
  ADCok=1; //выставляем флаг успешного получения данных с АЦП
  ADCresult=0; //обнуляем флаг входа в процедуру
  }else{
   ADCcountConv_tmp++; //увеличиваем счетчик холостых преобразований
   ADCSRA|=(1<<ADSC);//start each conversion
   ADCresult=0; //обнуляем флаг входа в процедуру
  }
}
//принимаем решение по результатам измерений в АЦП, результаты храняться в массиве ADCPin[]
if (ADCok==1){
 USART_Send_srt("ADC Result:");
 }
ADCok=0;
ADCSRA|=(1<<ADSC);//start each conversion
}

};// конец бесконечного цикла
}// конец main


Если не разберешся, то могу прислать весь проект, но там много чего лишнего для тебя.

Добавлено: Вс ноя 16, 2008 17:16:55
Денис203
Это все понятно,,,!! с питанием все в порядке,, с ногой ввода все тоже хорошо,, но вот даже в АВР студио не хочет входить в прерывания....
Извините , но я нек понял про JMP и про RJMP .... в чем разница... и что мне нужно сделать?

Добавлено: Вс ноя 16, 2008 18:19:23
TechMike
Денис203 писал(а):Это все понятно,,,!! с питанием все в порядке,, с ногой ввода все тоже хорошо,, но вот даже в АВР студио не хочет входить в прерывания....
Извините , но я нек понял про JMP и про RJMP .... в чем разница... и что мне нужно сделать?


Если не вызываются вообще какие прерывания, то смотри регистр SREG, если только АЦП, то нужно включить сам АЦП:
ADCSRA|=(1<<ADEN);//make sure ADC is ON
включить выполнение прерывание от АЦП по завершению преобразования:
ADCSRA|=(1<<ADIE);//ADC Interrupt Flag ON
ну и запустить само преобразование:
ADCSRA|=(1<<ADSC);//start ADC each conversion

Про глобальные прерывания посмотри в даташите, я точно не помню регистр.

Я всегда перед залитием в железо, прекрасно моделировал в самой AVR Studio, там все прерывается замечательно.

Добавлено: Вс ноя 16, 2008 18:36:18
biDE
Извините , но я нек понял про JMP и про RJMP .... в чем разница... и что мне нужно сделать?

1. заменить rjmp RESET...rjmp SPM_RDY на jmp RESET...jmp SPM_RDY
2. не забыть включить глобальные прерывания командой sei

Добавлено: Пн ноя 17, 2008 16:46:19
Денис203
вот вроде все получачается в проеусе,, но прошить мегу не могу,,, прошиваю в Uniprof
может там чтото гдето нужно поставитть... Подскажите плиз......
вот окончательный текст программы

Добавлено: Пн ноя 17, 2008 17:44:06
Денис203
утоЧНЮ!!! не работает ПОРТ Б,,, старшие биты отрабатывают, а вот младшие не хотят,, почему??