Помощь - Поиск - Пользователи - Календарь
Полная версия этой страницы: Не хочет работать прерывание компаратора в GCC+Eclipce.
Форум разработчиков электроники ELECTRONIX.ru > Микроконтроллеры (MCs) > Cредства разработки для МК > GNU/OpenSource средства разработки
Dikoy
Ну очень хочу зажечь светодиодик в прерывании. Не получается...
Сразу скажу - код был отлажен в IAR, в том же железе, инициализация компаратора и т.д. корректные. В IAR всё работает как часы, в клипсе - затыкается.

GCC+Eclipce. Инициализирую:
Код
    PORTD &= ~((1<<6)|(1<<7)); // лапы компаратора на вход
    DDRD  &= ~((1<<6)|(1<<7));

    ADCSRA &= ~(1<<ADEN); // выключаю АЦП
    ACSR  = (1<<ACBG)|(1<<ACIE)|(1<<ACIS1)|(1<<ACIS0);
    SFIOR |= (1<<ACME);
    ADMUX = 6;  // настройка компаратора на 6 вход АЦП
    _delay_ms(1);
    ACSR |= (1 << ACI); // сброс флага прерывания, чтоб не возникло сразу после включения
    _delay_ms(1);

    sei();

Собственно, кусок скопирован из IAR.
Далее если делать так, то всё работает:
Код
        if(ACSR & (1 << ACO) ) ON(LED);
                      else OFF(LED);


А вот если так, то фиг:

Код
ISR(ANA_COMP_vect) {

    ON(LED);

}


То есть софтовый опрос флага компаратора работает, значит железных проблем или проблем с инициализацией нет.
Не работает именно прерывание.
Куда порыть? В GCC я новичок...
_Артём_
Возможно у вас не устанавливается флаг прерывания ACI. Поэтому прерывание не происходит.

Цитата
Далее если делать так, то всё работает:
Код
if(ACSR & (1 << ACO) ) ON(LED);
                      else OFF(LED);


Этот пример ничего не показывает, попробуйте так:

Код
if(ACSR & (1 << ACI) ) ON(LED);
                      else OFF(LED);

Если загорится, то и прерывание должно заработать, если нет - неправильно настроены условия возникновения прерываний компаратора.
Dikoy
Как могут быть неправильно настроены условия возникновения прерываний компаратора, если в IAR с тем же кодом всё работает как часы?
Мнемоники бит корректны, GCC их находит по F3.
Возможно я вектор не так объявил? GCC, он же самостийный, не такой как все...
Или ещё что-то надо включить где-то?
Прерывания таймера работают, что интересно...

Попробовал мониторить ACI в мейнлупе. Светодиод загорелся и горит, не тухнет (флаг то не сбрасывается) как и должен.
В обработчике светодиод по прежнему не загорается...
_Артём_
Цитата(Dikoy @ Mar 13 2012, 15:27) *
Как могут быть неправильно настроены условия возникновения прерываний компаратора

Я только предположил....

Цитата(Dikoy @ Mar 13 2012, 15:27) *
Возможно я вектор не так объявил?


Возможно неправильно. Warning-ов не возникало?
Попробуйте так:
Код
ISR(ANALOG_COMP_vect)


Или в симуляторе установите флаг прерывания вручную и посмотрите в disassembler-е куда реально переходит программа.
Dikoy
По F3 ANA_COMP_vect уводит в хидер:
Код
/* Analog Comparator */
#define ANA_COMP_vect            _VECTOR(16)
#define SIG_COMPARATOR            _VECTOR(16)

То есть тут тоже, вроде, всё ОК...

Варнинг только один, но к компаратору даже близко не относящийся.
_Артём_
Цитата(Dikoy @ Mar 13 2012, 16:28) *
По F3 ANA_COMP_vect уводит в хидер:
Код
/* Analog Comparator */
#define ANA_COMP_vect            _VECTOR(16)
#define SIG_COMPARATOR            _VECTOR(16)

То есть тут тоже, вроде, всё ОК...

А какой процессор?


Цитата(Dikoy @ Mar 13 2012, 16:28) *
Варнинг только один, но к компаратору даже близко не относящийся.

Уверенны?


Dikoy
ATmega8.
Посмотрел в списке прерываний из ДШ, адрес 0x010 у компаратора. Как он получается в GCC так не понял, но хидер iom8.h из комплекта компилятора.

Про варнинг на 90% уверен:
_Артём_
Цитата(Dikoy @ Mar 13 2012, 16:58) *
ATmega8.
Посмотрел в списке прерываний из ДШ, адрес 0x010 у компаратора. Как он получается в GCC так не понял, но хидер iom8.h из комплекта компилятора.

С этим как раз понятно: 0x10=16.

Почему не работает не ясно - всё настроено вроде правильно и должно работать.
AHTOXA
А обработчик у вас не в cpp-файле?
ReAl
А всё равно.
Цитата(avr/interrupt.h)
#ifdef __cplusplus
# define ISR(vector, ...) \
extern "C" void vector (void) __attribute__ ((signal,__INTR_ATTRS)) __VA_ARGS__; \
void vector (void)
#else
# define ISR(vector, ...) \
void vector (void) __attribute__ ((signal,__INTR_ATTRS)) __VA_ARGS__; \
void vector (void)
#endif

Но, поскольку в примерах scmRTOS есть и вариант переключения контекста в прерывании от компаратора, в avr-gcc можно получить обработку прерывания от оного. Причём для разных контроллеров с разными настройками (по одному или по обеим перепадам). Каких-то проблем в написании кода не помню.

Пока я в первом сообщении темы в обработчике прерывания компаратора увидел только включение светодиода. Кода для выключения нет.
_Артём_
Цитата(AHTOXA @ Mar 13 2012, 17:54) *
А обработчик у вас не в cpp-файле?

А что это может быть источником проблем?
AHTOXA
Цитата(_Артём_ @ Mar 13 2012, 23:07) *
А что это может быть источником проблем?

Как нам только что объяснил уважаемый ReAl, в avr-gcc, оказывается, не может.
А, например, в случае arm-gcc и cortex - запросто. (Например, вот, вот, вот и ещё кучу разsm.gif )
Dikoy
Цитата(AHTOXA @ Mar 13 2012, 19:54) *
А обработчик у вас не в cpp-файле?

Там. Но там же и обработчик прерывания таймера, который, собака, работает.



Цитата(ReAl @ Mar 13 2012, 20:56) *
Пока я в первом сообщении темы в обработчике прерывания компаратора увидел только включение светодиода. Кода для выключения нет.

Нету. Ибо мне бы хотя бы чтоб он загорелся sm.gif А там уж потушу как нибудь.
Так он не загорается... Вообще... Весь контроллер уже проводком истыкал.
Что-то не то с обработчиком. Компаратор работает 100%.
Может он его оптимизирует... :spy:
Dikoy
Нее... Обработчик есть...

@0000027E: __vector_16
+0000027E: 921F PUSH R1 Push register on stack
+0000027F: 920F PUSH R0 Push register on stack
+00000280: B60F IN R0,0x3F In from I/O location
+00000281: 920F PUSH R0 Push register on stack
+00000282: 2411 CLR R1 Clear Register
+00000283: 9AA8 SBI 0x15,0 Set bit in I/O register
+00000284: 900F POP R0 Pop register from stack
+00000285: BE0F OUT 0x3F,R0 Out to I/O location
+00000286: 900F POP R0 Pop register from stack
+00000287: 901F POP R1 Pop register from stack
+00000288: 9518 RETI Interrupt return
_Pasha
Ну Вы хе-хе-хе lol.gif
Зогадко просто решается. В приведенном коде инициализации пинов напорото столько чуши, что.
Вы определитесь хотя бы, на каких ногах этот компаратор висит. Из кода это неясно абсолютно.
А люди мозг ломают...
_Артём_
Цитата(_Pasha @ Mar 14 2012, 04:37) *
Зогадко просто решается. В приведенном коде инициализации пинов напорото столько чуши, что.

В чём чушь? Ноги в Z переводятся.

Цитата(_Pasha @ Mar 14 2012, 04:37) *
Вы определитесь хотя бы, на каких ногах этот компаратор висит.

На PD6-PD7.

Цитата(_Pasha @ Mar 14 2012, 04:37) *
Зогадко просто решается.

А какая разгадка?

Цитата(AHTOXA @ Mar 13 2012, 20:11) *
Как нам только что объяснил уважаемый ReAl, в avr-gcc, оказывается, не может.

И что мешает в АРМ также сделать?


Цитата(AHTOXA @ Mar 13 2012, 20:11) *
А, например, в случае arm-gcc и cortex - запросто. (Например, вот, вот, вот и ещё кучу разsm.gif )

Почитал - вспомнил: сом недавно по этим граблям походил.
_Pasha
Цитата(_Артём_ @ Mar 14 2012, 13:46) *
В чём чушь? Ноги в Z переводятся.
На PD6-PD7.
А какая разгадка?

Вот она
Код
SFIOR |= (1<<ACME);
ADMUX = 6;  // настройка компаратора на 6 вход АЦП

Уберите ACME, ибо у Вас компаратор чисто электрически не работает
зы. Ой, не у Вас, а у ТС, конечно.
_Артём_
Цитата(_Pasha @ Mar 14 2012, 13:04) *
Вот она
Код
SFIOR |= (1<<ACME);
ADMUX = 6;  // настройка компаратора на 6 вход АЦП

Уберите ACME, ибо у Вас компаратор чисто электрически не работает

Как не работает?
ACME=1 - It is possible to select any of the ADC7..0(1) pins to replace the negative input to the Analog
Comparator.
Работает, но сигнал берётся с ADC6. Или нет?
_Pasha
Цитата(_Артём_ @ Mar 14 2012, 13:46) *
В чём чушь? Ноги в Z переводятся.
На PD6-PD7.


Цитата(_Артём_ @ Mar 14 2012, 14:13) *
Как не работает?
ACME=1 - It is possible to select any of the ADC7..0(1) pins to replace the negative input to the Analog
Comparator.
Работает, но сигнал берётся с ADC6. Или нет?

Вот и я не пойму, откуда берется сигнал sm.gif
Dikoy
Паша, прежде чем ржать глянули бы в ДШ.
Сигнал берётся с 6 канала АЦП, который не имеет функции пина, только АЦП, и инициализировать его как-то не нужно.
Входы же компаратора переводятся в Z для пущей лучшести, т.к. имеют свойство гадить его работе в таком режиме. Т.к. они у меня пока не задействованы, перевёл в Z от греха.
Ну и наконец, для бронебригад. Повторю в третий раз. Без прерывания компаратор РАБОТАЕТ. Биты и флаги встают как надо при изменении сигнала на входе. Этому посвящено 2/3 моего первого поста, с кусками кода и лирическими отступлениями. Не работает ТЕЛО ПРЕРЫВАНИЯ.

Всем.
Проблему решил. Оказалось, тело прерывания таймера настолько перегружено, что не успевает выполнится до следующего переполнения. А когда выполняется, выбирает флаг с бОльшим приотритетом - то есть снова таймер. А компаратор лишь удивлённо смотрит в след...
Первый раз такое вижу...
_Артём_
Цитата(Dikoy @ Mar 14 2012, 14:33) *
Оказалось, тело прерывания таймера настолько перегружено, что не успевает выполнится до следующего переполнения. А когда выполняется, выбирает флаг с бОльшим приотритетом - то есть снова таймер. А компаратор лишь удивлённо смотрит в след...
Первый раз такое вижу...

Ни хрена себе...точно пора с АВР завязывать...
Dikoy
Завязывать надо с С++ и писюковыми методами на МК...
_Артём_
Цитата(Dikoy @ Mar 14 2012, 15:04) *
Завязывать надо с С++ и писюковыми методами на МК...

Назад к ассемблеру Си?
Я думаю наоборот: С++ и PC-методам на МК всё большее применение находится.
Хотя каждому своё.
Dikoy
На х32.
На х8 - не стоит.
IgorKossak
Скрыл холивар.
Модератор.
Сергей Борщ
QUOTE (Dikoy @ Mar 14 2012, 15:04) *
Завязывать надо с С++ и писюковыми методами на МК...
Сергей, я существенно переделал эту часть программы, таймерное прерывание теперь выполняется очень быстро. Даже на С++. Но вот состыковать эту часть с остальной программой у меня просто нет времени. Я отпишу тебе в скайп и скину исходники.
Dikoy
Ок!
Лучше в почту.
Для просмотра полной версии этой страницы, пожалуйста, пройдите по ссылке.
Invision Power Board © 2001-2025 Invision Power Services, Inc.