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

 
 
> АЦП и прерывания ATmega48, помогите начинающему...
NikitoS-86
сообщение Sep 22 2008, 10:29
Сообщение #1


Участник
*

Группа: Новичок
Сообщений: 28
Регистрация: 22-09-08
Пользователь №: 40 380



Добрый день. Я занялся изучением AVR, использую AVRStudio в связке с WinAVR.
И у меня появились затруднения определённого плана. Я имею представление о том, что есть прерывание, что есть стек, указатель команд и вообще имею хорошее знание касательно теории... Но дошло дело до практики... И попытался я написать простейший код... Итак ситуация: в качестве входа АЦП использоваться ADC7, надо будет на 3 выхода (PB0..2) выдавать адрес на мультиплексер, который будет переключать свои входы, на входв АДС7 будет как раз приходить сигнал с демультеплексора, АЦП должен оцифровать и записать эти данные в массив...
Вот примерный код:

Цитата
#include <avr/io.h>
#include <avr/signal.h>
#include <avr/interrupt.h>

void port_B_settings (void);
void ADC_settings (void);
void port_C_settings (void);


int help_reg=0;

ISR (ADC_vect)
{
help_reg = 1;
}

void main (void)
{
int Ubat[4];
int Tbat[4];
int Icur;

port_B_settings();
ADC_settings();


for (int i=0;i<3;i++)
{
ADCSRA = 0xC8;
sei();

while (!help_reg)
{}

Ubat[i] = help_reg;
}
}

void port_B_settings (void)
{
DDRB = 0x07; //PB0..1 - outputs
}

void ADC_settings (void)
{
ADMUX = 0x07; //ADC7
ADCSRA = 0x88; //ADEN=1 | ADIE = 1
}



В нём правда ещё не выдаётся адрес никуда и т.д. Не суть... А суть в том, что у меня по-левому работает прерывание.
Я хочу, чтобы после начала прерывания шло ожидание прерывания, после чего его обработка и после чего запись..., а у меня выходит всякая ересь и в симуляторе вконце концов вообще после первого "прохода" получается бесконечный цикл....=/
Что я делаю неправильно?
Вопрос касательно языка С - можно ли обрабатывать прерывание не по этому макросу, а что называется ручками... Просто я не знаю как мне в такой обработчик прерывания отправить например указатель на мой массив, чтобы прям в обработчике осуществлять запись в массив, а не вводить для этого пресловутый help_reg=/

И ещё вопрос: я перед запуском АЦП настраиваю только его вход в ADMUX, а надо ли настраивать ещё первые байты, которые отвечают за настройку напряжения если не ошибаюсь... Вообще если можно, то посвятите немного о том, как настраивать и запускать АЦП, поскольку из даташита к сожалению не всё понял на английском, например мне не понятно немного что такое некий "непрерывный режим работы" АЦП, который настраивается через запись бита ADATA в регистре ADCSRA...

Ах да, последнее: речь идёт о ATmega48

Заранее огромное спасибо ответившим, просто уже 2 дня мучаюсь с этим АЦП=/

Сообщение отредактировал NikitoS-86 - Sep 22 2008, 10:31
Go to the top of the page
 
+Quote Post
 
Start new topic
Ответов
NikitoS-86
сообщение Sep 23 2008, 12:25
Сообщение #2


Участник
*

Группа: Новичок
Сообщений: 28
Регистрация: 22-09-08
Пользователь №: 40 380



Итак, во-первых, ОГРОМНОЕ спасибо всем откликнувшимся в данной теме=). Отдельное спасибо товарищам SasaVitebsk, Aleksandr Baranov и Цыкетчик за подробные ответы и сведения касающиеся практики!!! Я наконец разобрался!=)))

Как промежуточный конечный результат я сваял следующий код:

Цитата
#include <avr/io.h>
#include <avr/sfr_defs.h>
#include <avr/delay.h>

#define MYADMUX_U_T (1<<REFS1) | (1<<REFS0) | (0<<MUX3) | (1<<MUX2) | (1<<MUX1) | (1<<MUX0);
#define MYADMUX_I (1<<REFS1) | (1<<REFS0) | (0<<MUX3) | (1<<MUX2) | (1<<MUX1) | (0<<MUX0);

void port_B_settings (void);
void port_C_settings (void);
void measure_Ubat (int *, int *);
void measure_Tbat (int *, int *);
void measure_Icur (int *);

void main (void)
{
int Ubat[4];
int Tbat[4];
int Icur;

const int channel_number[8] =
{0b000, 0b001, 0b010, 0b011, 0b100, 0b101, 0b110, 0b111};

port_B_settings();

ADCSRA = 0x80;
_delay_ms(10);

measure_Ubat (&Ubat, &channel_number);

measure_Tbat (&Tbat, &channel_number);

measure_Icur (&Icur);
return;
}

void port_B_settings (void)
{
DDRB = 0x07;

return;
}

void measure_Ubat (int *Ubat, int *channel_number)
{
for (int i=0;i<4;i++)
{
ADMUX = MYADMUX_U_T;

PORTB = ((channel_number[i]>>2)<<PB2) | ((channel_number[i]>>1)<<PB1) | ((channel_number[i])<<PB0);
_delay_ms(10);

ADCSRA=ADCSRA | (1<<ADSC);

for (;;)
{
if (bit_is_set(ADCSRA,4))
break;
}

*(Ubat+i) = ADCH;
*(Ubat+i) = (*(Ubat+i)<<8) + ADCL;

ADCSRA = ADCSRA | (1<<ADIF);
}

return;
}

void measure_Tbat (int *Tbat, int *channel_number)
{
for (int i=0;i<4;i++)
{
ADMUX = MYADMUX_U_T;

PORTB = ((channel_number[i+4]>>2)<<PB2) | ((channel_number[i+4]>>1)<<PB1) | ((channel_number[i+4])<<PB0);
_delay_ms(10);

ADCSRA=ADCSRA | (1<<ADSC);

for (;;)
{
if (bit_is_set(ADCSRA,4))
break;
}

*(Tbat+i) = ADCH;
*(Tbat+i) = (*(Tbat+i)<<8) + ADCL;

ADCSRA = ADCSRA | (1<<ADIF);
}

return;
}

void measure_Icur (int *Icur)
{
ADMUX = MYADMUX_I

ADCSRA=ADCSRA | (1<<ADSC);

for (;;)
{
if (bit_is_set(ADCSRA,4))
break;
}

*Icur = ADCH;
*Icur = (*Icur<<8) + ADCL;

ADCSRA = ADCSRA | (1<<ADIF);

return;
}


Который вроде даже работает=)
У меня только вот что "вылезло":
1) В последнем ответе SasaVitebsk на мой пост есть фраза:
Цитата
В этом случае в п/п вам надо проверить флаг готовности АЦП и ждать его выставления и прочитать значение. Опять таки (см. выше) первое, после переключ. канала отбросить как не верное.

этот момент мне не очень понятен... Или таким образом реализуется "устаканивание" сигнала после смены канала? своего рода задержка между подачей сигнала на оцифровку и оцифровкой дабы получить более точное значение? Если так, то можно ли это реализовать функцией delay()?

2) На счёт встроенного дизасемблера и функции watch - спасибо, что подсказали... Удобно... НО почему она мне не позволяет наблюдать за метаморфозами моих переменных во время нахождения в вызываемых функциях? А я могу видеть состояние массивов только после возвращения из этих функций... Кроме того, переменную Icur она вообще наотрез отказывается отображать, всё время пишет либо "Location not valid" либо "Not in scope"... Таким образом я даже не вижу что с ней происходит... Может я как-то неправильно осуществляю вызов функций? Вроде бы всё что называется как по книжке... или может быть я где-то ошибся? Кстати при компиляции она мне пишет различного рода вонингсы как раз на моменты вызова функции... Они звучат следующим образом:
"../first.c:29: warning: passing argument 1 of 'measure_Ubat' from incompatible pointer type"
что я примерно перевожу как:
"впервый аргумент функции 'measure_Ubat' несовместим с сылочным типом..."
Я в чём-то заблуждаюсь при вызове функций?

Спасибо!

Чёрт, эта зараза не понимает рускую кодировку каментов из студии, пришлось все каменты удалить, ибо каракули отобразились при вставке...

Сообщение отредактировал NikitoS-86 - Sep 23 2008, 12:27
Go to the top of the page
 
+Quote Post

Сообщений в этой теме
- NikitoS-86   АЦП и прерывания ATmega48, помогите начинающему...   Sep 22 2008, 10:29
- - gormih   Для инииализации АЦП небходимо обязательно инициал...   Sep 22 2008, 11:41
- - NikitoS-86   1) Так я помоему как раз в функции ADC_settings ()...   Sep 22 2008, 11:45
- - SasaVitebsk   Давайте по-порядку. 1) Для начала очень даже непло...   Sep 22 2008, 12:18
- - NikitoS-86   1) К сожалению выбрать другую микруху - уже нельзя...   Sep 22 2008, 12:43
|- - SasaVitebsk   Цитата(NikitoS-86 @ Sep 22 2008, 15...   Sep 22 2008, 15:48
||- - Цыкетчик   Надо не забыть ещё сделать задержку примерно на 1м...   Sep 23 2008, 10:50
|- - Сергей Борщ   Цитата(NikitoS-86 @ Sep 22 2008, 15...   Sep 23 2008, 18:23
- - Aleksandr Baranov   Для манипуляции битами регистров в библиотеке avr-...   Sep 22 2008, 12:58
|- - NikitoS-86   Цитата(Aleksandr Baranov @ Sep 22 2008, 16...   Sep 22 2008, 13:13
|- - Aleksandr Baranov   Цитата(NikitoS-86 @ Sep 22 2008, 09...   Sep 22 2008, 13:43
- - MrYuran   Цитатаmeasure_Ubat (&Ubat , &channel_numbe...   Sep 23 2008, 12:35
- - NikitoS-86   Да, так и есть по идее, и сначала я пользовал имен...   Sep 23 2008, 13:25
|- - MrYuran   Цитата(NikitoS-86 @ Sep 23 2008, 17...   Sep 23 2008, 13:46
- - SasaVitebsk   Высскажу несколько соображений общего характера. В...   Sep 23 2008, 16:09
- - NikitoS-86   Цитата(SasaVitebsk @ Sep 23 2008, 20:09) ...   Sep 23 2008, 19:25


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

 


RSS Текстовая версия Сейчас: 29th July 2025 - 21:54
Рейтинг@Mail.ru


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