Помощь - Поиск - Пользователи - Календарь
Полная версия этой страницы: Какой бесплатный компилятор Си для AVR лучше? Поделитесь!
Форум разработчиков электроники ELECTRONIX.ru > Микроконтроллеры (MCs) > AVR
Samodelkin
Начинаю писать на Си для АВР. Посоветуйте компилятор Си для написания и отладки проектов. Попробовал WinAVR. Вроде удобная штука. Интегрируется в AVR Studio, там очень удобно отлаживать. В одной проге и пишишь, и отлаживаешь. Только вот столкнулся с проблемой, при отработке прерывания компилятор при выходе из него ставит RET вместо RETI. В результате ничего не работает, после выхода из прерывания программа начинает работу с 0-го адреса!!!???
Может быть есть что-то более удобное, бесплатное или взломанное???!!!!
Заранее благодарен!
aesok
В AVR-GCC нет проблемы про которую вы пишите. Если Вы хотите понять в где ошибка, высылайте Ваш код. Только давайте не в этом форуме, а в 'AVR'.

Анатолий.
prottoss
Цитата(Samodelkin @ Jan 2 2007, 17:37) *
Начинаю писать на Си для АВР. Посоветуйте компилятор Си для написания и отладки проектов.
ИМХО ИАР рулит!!! Масса настроек, еслиф нада... Еслиф не нада, можно о них и не думать на первые разы. С АВРСтудио тоже дружит, ИАРовский Сишный код она видит. Ну и в плане проблем с эээ...разрешением проблем... тоже все нормально, специальные успокоители есть
_Bill
Цитата(Samodelkin @ Jan 2 2007, 13:37) *
Начинаю писать на Си для АВР. Посоветуйте компилятор Си для написания и отладки проектов. Попробовал WinAVR. Вроде удобная штука. Интегрируется в AVR Studio, там очень удобно отлаживать. В одной проге и пишишь, и отлаживаешь. Только вот столкнулся с проблемой, при отработке прерывания компилятор при выходе из него ставит RET вместо RETI. В результате ничего не работает, после выхода из прерывания программа начинает работу с 0-го адреса!!!???
Может быть есть что-то более удобное, бесплатное или взломанное???!!!!
Заранее благодарен!

А как Вы процедуру прерывания описываете?
defunct
Цитата(Samodelkin @ Jan 2 2007, 13:37) *
Только вот столкнулся с проблемой, при отработке прерывания компилятор при выходе из него ставит RET вместо RETI. В результате ничего не работает, после выхода из прерывания программа начинает работу с 0-го адреса!!!???

#include <avr/interrupt.h>
..
функцию обработчик прерывания описать как:
SIGNAL (Вектор_прерывания)

Если будет продолжать сбоить - код в студию.

Цитата
Может быть есть что-то более удобное, бесплатное или взломанное???!!!!

Более бесплатного точно нет.
Более удобное (в плане работы с flash/eeprom) - IAR.
Samodelkin
Всем, кто откликнулся, большое спасибо!
Вы меня немного успокоили. Щас еще поколдую над прогой, если не получится, то вернусь сюда, будем разбираться дальше!!!
kamedi_clab
советую http://www.codevision.be/ (он бесплатный как IAR)

Цитата(defunct @ Jan 3 2007, 01:16) *
Цитата(Samodelkin @ Jan 2 2007, 13:37) *

Только вот столкнулся с проблемой, при отработке прерывания компилятор при выходе из него ставит RET вместо RETI. В результате ничего не работает, после выхода из прерывания программа начинает работу с 0-го адреса!!!???

#include <avr/interrupt.h>
..
функцию обработчик прерывания описать как:
SIGNAL (Вектор_прерывания)



а в новом WinAVR разве не иначе объявление ?
Samodelkin
Цитата(_Bill @ Jan 2 2007, 22:41) *
Цитата(Samodelkin @ Jan 2 2007, 13:37) *

Начинаю писать на Си для АВР. Посоветуйте компилятор Си для написания и отладки проектов. Попробовал WinAVR. Вроде удобная штука. Интегрируется в AVR Studio, там очень удобно отлаживать. В одной проге и пишишь, и отлаживаешь. Только вот столкнулся с проблемой, при отработке прерывания компилятор при выходе из него ставит RET вместо RETI. В результате ничего не работает, после выхода из прерывания программа начинает работу с 0-го адреса!!!???
Может быть есть что-то более удобное, бесплатное или взломанное???!!!!
Заранее благодарен!

А как Вы процедуру прерывания описываете?



Вот код:
если что-то наплужил, сильно не ругайте, я еще только учусь.
Компилятор WinAVR-20060421-install.
По идее после переполнения ТС1 должно отработать прерывание, но вместо этого прога начинает работу с самого начала!!!??? В коде при выходе их прерывания вместо RETI стоит RET!!!???
Что делать?



#include <avr/io.h>
#include <avr/interrupt.h>
//#include <avr/signal.h>

#define Freq 11059200


INTERRUPT(SIG_OVERFLOW1)
{
TCNT1 = 0x22;
PORTB ^= 0x01;
}



int main (void)
{
DDRB = 0x01;
TCCR1A = 0;
TCCR1B = 1;//5;
TCNT1 = 0xFFF0;//10000 - (Freq / 1024);
TIFR = 0;
TIMSK = 0x80;
GIMSK = 0;
sei();
while(1) ;
}

Цитата(defunct @ Jan 3 2007, 01:16) *
Цитата(Samodelkin @ Jan 2 2007, 13:37) *

Только вот столкнулся с проблемой, при отработке прерывания компилятор при выходе из него ставит RET вместо RETI. В результате ничего не работает, после выхода из прерывания программа начинает работу с 0-го адреса!!!???

#include <avr/interrupt.h>
..
функцию обработчик прерывания описать как:
SIGNAL (Вектор_прерывания)

Если будет продолжать сбоить - код в студию.

Цитата
Может быть есть что-то более удобное, бесплатное или взломанное???!!!!

Более бесплатного точно нет.
Более удобное (в плане работы с flash/eeprom) - IAR.



Вот код:
если что-то наплужил, сильно не ругайте, я еще только учусь.
Компилятор WinAVR-20060421-install.
По идее после переполнения ТС1 должно отработать прерывание, но вместо этого прога начинает работу с самого начала!!!??? В коде при выходе их прерывания вместо RETI стоит RET!!!???
Что делать?



#include <avr/io.h>
#include <avr/interrupt.h>
//#include <avr/signal.h>

#define Freq 11059200


INTERRUPT(SIG_OVERFLOW1)
{
TCNT1 = 0x22;
PORTB ^= 0x01;
}



int main (void)
{
DDRB = 0x01;
TCCR1A = 0;
TCCR1B = 1;//5;
TCNT1 = 0xFFF0;//10000 - (Freq / 1024);
TIFR = 0;
TIMSK = 0x80;
GIMSK = 0;
sei();
while(1) ;
}
beer_warrior
!!!!SIGNAL(SIG_OVERFLOW1)!!!!
Найдите в доке разницу между SIGNAL и INTERRUPT и почитайте.
Samodelkin
Цитата(beer_warrior @ Jan 4 2007, 01:02) *
!!!!SIGNAL(SIG_OVERFLOW1)!!!!
Найдите в доке разницу между SIGNAL и INTERRUPT и почитайте.


Я Вас понял, но дело в том что INTERRUPT ведет себя точно так-же!!!!!!!
aesok
Для какого контроллера компилируете? Для некоторых новых контролеров не определены имена прерываний начинающейся с 'SIG_*'. В новых проектах не используйте SIGNAL(), INTERRUPT() и SIG_*, этот интерфейс устарел.

Используйте новые макросы ISR() и имена прерываний заканчивающийся на _vect,
ISR(*_vect)
{
}

INTERRUPT() решили удалить как раз из-за того что некоторые не читают документацию.....

И еще, вместо:
#define Freq 11059200
напишите:
#define Freq 11059200UL
и тогда формула в:
TCNT1 = 0xFFF0;//10000 - (Freq / 1024);
заработает.


Анатолий.



А какя в WinAVR-20060421 версия avr-libc? Написана в avr-libc-user_manual.

Анатолий.
defunct
Цитата(Samodelkin @ Jan 4 2007, 01:06) *
Я Вас понял, но дело в том что INTERRUPT ведет себя точно так-же!!!!!!!

Значит проблема может быть и не в прерываниях.
Возможны три причины по которым МК у Вас сбрасывается:
1. запрограммирован сооветствующим Fuse-битом WDT, решение проблемы - оключить WDT или добавить в основной цикл программы asm("WDR").
2. глючит BOD, решение проблемы - отключить BOD при знакомстве с МК.
3. помеха на Reset'е, решение - добавить конденсатор между землей и Reset'ом 0.1..1uF.
prottoss
Цитата(defunct @ Jan 4 2007, 09:24) *
Цитата(Samodelkin @ Jan 4 2007, 01:06) *

Я Вас понял, но дело в том что INTERRUPT ведет себя точно так-же!!!!!!!

Значит проблема не в прерываниях.
Возможны три причины по которым МК у Вас сбрасывается:
1. запрограммирован сооветствующим Fuse-битом WDT, решение проблемы - оключить WDT или добавить в основной цикл программы asm("WDR").
2. глючит BOD, решение проблемы - отключить BOD при знакомстве с МК.
3. помеха на Reset'е, решение - добавить конденсатор между землей и Reset'ом 0.1..1uF.


Хм...Вроде бы автор топика глаголил, что "...Только вот столкнулся с проблемой, при отработке прерывания компилятор при выходе из него ставит RET вместо RETI..." ???

2 Samodelkin - это на самом деле имеет место быть? Вы смотрели ассемблерный листинг Вашего творения?
defunct
Цитата(prottoss @ Jan 4 2007, 05:50) *
Хм...Вроде бы автор топика глаголил, что "...Только вот столкнулся с проблемой, при отработке прерывания компилятор при выходе из него ставит RET вместо RETI..." ???

Но мы же с Вами знаем, что по поведению RET и RETI отличаются только влиянием на флаг I. Это отличие никак не могло привести к перезапуску девайса.

Тут либо вектором ошиблись, либо непредсказуемый сброс МК (по причинам, описанным в предыдущем моем посте).

Сомневаюсь я, что тут что-то не так генерится.


Цитата(Samodelkin @ Jan 4 2007, 01:02) *
...
TIMSK = 0x80; <--- вот здесь что разрешается-то? соответвует ли это SIG_OVERFLOW1?
aesok
В avr-libc 1.4.4, эта версия включена в WinAVR-20060421, маккос INTERRUPT удален из файла <avr/interrupt.h> и перемещен в <compat/deprecated.h>. Поэтому в коде:

#include <avr/io.h>
#include <avr/interrupt.h>
//#include <avr/signal.h>

....

INTERRUPT(SIG_OVERFLOW1)
{
TCNT1 = 0x22;
PORTB ^= 0x01;
}

INTERRUPT(SIG_OVERFLOW1) Интерпретируеться компилятором ни как описание функции обработчика прерывания, а как описание обычной функции с именем INTERRUPT.

Анатолий.
Punk
Цитата(kamedi_clab @ Jan 4 2007, 00:21) *
советую http://www.codevision.be/ (он бесплатный как IAR)


CodeVisionAVR это конечно просто и замечательно, но вот с огромной кучей библиотек ему не тягаться с WinAVR ну с IAR если его сравнивать то ИМХО:вижн просто учебник для студентов,......очень кайфовый учебник
kamedi_clab
и для радиолюбителей. а по списку компаний его использующих и по голосованию на этом сайте и для проффи тоже.

Цитата(aesok @ Jan 4 2007, 15:36) *
INTERRUPT(SIG_OVERFLOW1) Интерпретируеться компилятором ни как описание функции обработчика прерывания, а как описание обычной функции с именем INTERRUPT.

Анатолий.


Анатолий, напишите пожалуйста окончательно пример - как в последнем WinAVR объявлять прерывание. например по переполнению Timer0.

Спасибо !
aesok
Цитата(kamedi_clab @ Jan 4 2007, 18:23) *
и для радиолюбителей. а по списку компаний его использующих и по голосованию на этом сайте и для проффи тоже.

Цитата(aesok @ Jan 4 2007, 15:36) *

INTERRUPT(SIG_OVERFLOW1) Интерпретируеться компилятором ни как описание функции обработчика прерывания, а как описание обычной функции с именем INTERRUPT.

Анатолий.


Анатолий, напишите пожалуйста окончательно пример - как в последнем WinAVR объявлять прерывание. например по переполнению Timer0.

Спасибо !


Короткий ответ:
ISR(TIMER0_OVF_vect)
{
код
}

Длинный ответ:
1. В '.с' файл где пишете обработчик прерывания должен быть включен заголовочный файл <avr/interrupt.h>:
#include <avr/interrupt.h>

2. Описываете обработчик прерывания:
ISR(*_vect)
{
код
}

3. Для того чтобы правильно написать имя вектора прерывания '*_vect', открываете в даташите таблицу с описанием векторов прерывания (Table XX. Reset and Interrupt Vectors), находите нужное вам прерывание. Слова в имени прерывания должны быть разделены одним знаком подчеркивания и в конец добавлено _vect. Примеры:
TIMER1 OVF -> TIMER1_OVF_vect;
USART, RXC -> USART_RXC_vect.

Но проще открыть заголовочный файл на ваш контроллер и скопировать оттуда (например 'include/avr/iom8.h'), для некоторых контроллеров заголовочные файлы идут на семейство, например для AT90USB1286 ищете не в 'iousb1286.h' а в 'iousbxx6_7.h'.

4. Компилируете проект и внимательно смотрите на варинги компилятора, если выскочило что-то типа:
"XXXX appears to be a misspelled signal handler" - значит вы ошиблись с именем прерывания повторить пункт 3.

5. Если вы хотите быть уверенным на 100%, открываете файл листинга, находите 0-вой адрес:

Код
00000000 <__vectors>:
   0:    12 c0           rjmp    .+36    ; 0x26 <__ctors_end>
   2:    2a c0           rjmp    .+84    ; 0x58 <__vector_1>
   4:    29 c0           rjmp    .+82    ; 0x98 <__vector_2>
   6:    27 c0           rjmp    .+78    ; 0x56 <__bad_interrupt>
   8:    26 c0           rjmp    .+76    ; 0x56 <__bad_interrupt>
   a:    25 c0           rjmp    .+74    ; 0x56 <__bad_interrupt>
   c:    24 c0           rjmp    .+72    ; 0x56 <__bad_interrupt>
   e:    23 c0           rjmp    .+70    ; 0x56 <__bad_interrupt>
  10:    22 c0           rjmp    .+68    ; 0x56 <__bad_interrupt>
  12:    21 c0           rjmp    .+66    ; 0x56 <__bad_interrupt>
  14:    20 c0           rjmp    .+64    ; 0x56 <__bad_interrupt>
.....


Для тех векторов для которые есть обработчики осуществляется переход на метки __vector_XX, для которых нет на __bad_interrupt.


Анатолий.
Samodelkin
Цитата(aesok @ Jan 4 2007, 01:37) *
Для какого контроллера компилируете? Для некоторых новых контролеров не определены имена прерываний начинающейся с 'SIG_*'. В новых проектах не используйте SIGNAL(), INTERRUPT() и SIG_*, этот интерфейс устарел.

Используйте новые макросы ISR() и имена прерываний заканчивающийся на _vect,
ISR(*_vect)
{
}

INTERRUPT() решили удалить как раз из-за того что некоторые не читают документацию.....

И еще, вместо:
#define Freq 11059200
напишите:
#define Freq 11059200UL
и тогда формула в:
TCNT1 = 0xFFF0;//10000 - (Freq / 1024);
заработает.


Анатолий.



А какя в WinAVR-20060421 версия avr-libc? Написана в avr-libc-user_manual.

Анатолий.



Спасибо за "ISR()"
После исправления этого, ассемблерный код стал нормальным, но поведение симулятора не изменилось. Как оказалось сам был виноват, в проекте и в опциях симулятора стояли разные типы контроллеров.
А зачем в строке "#define Freq 11059200UL" вконце добавлять UL???
Заранее спасибо, С уважением Samodelkin!
aesok
Цитата(Samodelkin @ Jan 4 2007, 22:56) *
А зачем в строке "#define Freq 11059200UL" вконце добавлять UL???
Заранее спасибо, С уважением Samodelkin!



В языке С константы по умолчанию имеют тип int, так как int в avr-gcc 16-битный то они могут принимать значение от -32 768 до 32 767. Ели вам нужно значение константы больше используйте суфиксы UL - для токо чтобы сообщит коппилятору что константа имеет тип unsigned long (32-бита в avr-gcc 0 до 4 294 967 295), L - long (-2 147 483 648 до 2 147 483 647), ULL - unsidned long long (64 бита) , ... итд.
Для более полной информации прочтите в вашей книге по 'C' раздел про константы.

Анатолий.
_Bill
Цитата(prottoss @ Jan 4 2007, 05:50) *
Цитата(defunct @ Jan 4 2007, 09:24) *
Цитата(Samodelkin @ Jan 4 2007, 01:06) *

Я Вас понял, но дело в том что INTERRUPT ведет себя точно так-же!!!!!!!

Значит проблема не в прерываниях.
Возможны три причины по которым МК у Вас сбрасывается:
1. запрограммирован сооветствующим Fuse-битом WDT, решение проблемы - оключить WDT или добавить в основной цикл программы asm("WDR").
2. глючит BOD, решение проблемы - отключить BOD при знакомстве с МК.
3. помеха на Reset'е, решение - добавить конденсатор между землей и Reset'ом 0.1..1uF.


Хм...Вроде бы автор топика глаголил, что "...Только вот столкнулся с проблемой, при отработке прерывания компилятор при выходе из него ставит RET вместо RETI..." ???

2 Samodelkin - это на самом деле имеет место быть? Вы смотрели ассемблерный листинг Вашего творения?

Насколько мне известно, в WinAVR функции обработки прерываний описываются при помощи квалификатора SIGNAL. Или нет?
aesok
Цитата(_Bill @ Jan 4 2007, 23:28) *
Насколько мне известно, в WinAVR функции обработки прерываний описываются при помощи квалификатора SIGNAL. Или нет?


До avr-libc весии 1.4.4 обработчики прерываний в которых были запрещены прерывания описывались с помощью SIGNAL, а в которых были разрешены прерывания описывались с помощью INTERRUPT.
К сожалению новички очень часто не прочитав документацию и/или не поняв в чем разница использовали INTERRUPT ..... и получали граблями по лбу. Поэтому в avr-libc 1.4.4 SIGNAL был заменен на ISR (SIGNAL конечно же остался для совместимости, только не рекомендован для использования), а INTERRUPT удален, точнее перемещен в <compat/deprecated.h>.

Если вам нужна функциональность INTERRUPT, значит .... вы уже профессиональный разработчик и знаете как описать такой обработчик прерываний.

Анатолий.
kamedi_clab
Анатолий, огромное спасибо за толерантность !
_Bill
Цитата(aesok @ Jan 4 2007, 23:49) *
Цитата(_Bill @ Jan 4 2007, 23:28) *


Насколько мне известно, в WinAVR функции обработки прерываний описываются при помощи квалификатора SIGNAL. Или нет?


До avr-libc весии 1.4.4 обработчики прерываний в которых были запрещены прерывания описывались с помощью SIGNAL, а в которых были разрешены прерывания описывались с помощью INTERRUPT.
К сожалению новички очень часто не прочитав документацию и/или не поняв в чем разница использовали INTERRUPT ..... и получали граблями по лбу. Поэтому в avr-libc 1.4.4 SIGNAL был заменен на ISR (SIGNAL конечно же остался для совместимости, только не рекомендован для использования), а INTERRUPT удален, точнее перемещен в <compat/deprecated.h>.

Если вам нужна функциональность INTERRUPT, значит .... вы уже профессиональный разработчик и знаете как описать такой обработчик прерываний.

Анатолий.

Спасибо за разъяснение. Сам я этим компилятором не пользовался, поэтому этих тонкостей не знал. Теперь буду знать. Или нет?
Для просмотра полной версии этой страницы, пожалуйста, пройдите по ссылке.
Invision Power Board © 2001-2025 Invision Power Services, Inc.