|
Вопрос по WinAVR |
|
|
|
May 15 2007, 05:08
|
Участник

Группа: Новичок
Сообщений: 28
Регистрация: 15-05-07
Пользователь №: 27 727

|
Сразу оговорюсь - я только учусь!!! Взял книгу Ю.Шпака Программирование на языке C для AVR и PIC микроконтроллеров. В придачу дан диск, на котором WINAVR версии 20040404 и примеры программ. Я некоторые пробовал и проверял на ATTINY2313. Но этот WINAVR не поддерживает такой процессор. Пришлось программы делать для AT90S2313 и прошивать ими тини. Но когда я поставил на комп. поддерживающий тини WINAVR 20060421, у меня перестали компилироваться программы, работавшие со старой версией WINAVR. Не знаю, что и делать. Уж не возвращаться же к старой версии! Подвкажите, спецы! Спасибо!
|
|
|
|
|
May 15 2007, 05:29
|
Участник

Группа: Новичок
Сообщений: 28
Регистрация: 15-05-07
Пользователь №: 27 727

|
Ну вот простая программка мигания светодиодом по прерыванию от переполнения T/C1:
#include <avr/io.h> #include <avr/interrupt.h> #include <avr/signal.h>
#define Freq 4000000
INTERRUPT(SIG_OVERFLOW1) { TCNT1 = 0x10000 - (Freq / 1024); PORTB ^= 0x01; }
int main (void) { DDRB = 0x01; TCCR1A = 0; TCCR1B = 5; TCNT1 = 0x10000 - (Freq / 1024); TIFR = 0; TIMSK = 0x80; GIMSK = 0; sei(); while(1) ; }
Сейчас ругается так:
Compiling: LEDBlink.c avr-gcc -c -mmcu=at90s8515 -I. -g -Os -funsigned-char -funsigned-bitfields -fpack-struct -fshort-enums -Wall -Wstrict-prototypes -Wa,-adhlns=LEDBlink.lst -std=gnu99 -Wp,-M,-MP,-MT,LEDBlink.o,-MF,.dep/LEDBlink.o.d LEDBlink.c -o LEDBlink.o LEDBlink.c:8: warning: return type defaults to `int' LEDBlink.c:8: warning: function declaration isn't a prototype LEDBlink.c: In function `INTERRUPT': LEDBlink.c:8: warning: type of "__vector_6" defaults to "int" LEDBlink.c:11: warning: control reaches end of non-void function
То есть, что-то не то в подпрограмме прерываний. Ачто??? Не могу понять!
|
|
|
|
|
May 15 2007, 05:51
|

Познающий...
     
Группа: Свой
Сообщений: 2 963
Регистрация: 1-09-05
Из: г. Иркутск
Пользователь №: 8 125

|
Слегка изменил, компиляция проходит нормально. В Вашем случае тоже все ок, просто это не ошибки, а предупреждения. Но про работоспособность кода сказать ничего не могу.... Сейчас нет платы с AVR. Код #include <avr/io.h> #include <avr/interrupt.h>
#define Freq 4000000
ISR(TIMER0_OVF_vect) { TCNT1 = 0x10000 - (Freq / 1024); PORTB ^= 0x01; }
int main (void) { DDRB = 0x01; TCCR1A = 0; TCCR1B = 5; TCNT1 = 0x10000 - (Freq / 1024); TIFR = 0; TIMSK = 0x80; GIMSK = 0; sei(); while(1); } Также прикладываю makefile (свой). На всякий случай. И еще: не стоит писать макрос Freq в программе. Он выносится в makefile под именем F_CPU. Хотя это не так важно. Лог сборки: Код -------- begin -------- Cleaning project: rm -f main.hex rm -f main.srec rm -f main.eep rm -f main.cof rm -f main.elf rm -f main.map rm -f main.sym rm -f main.lss rm -rf obj rm -f main.s rm -f main.d rm -rf .dep -------- end -------- -------- begin -------- avr-gcc (GCC) 3.4.6 Copyright (C) 2006 Free Software Foundation, Inc. This is free software; see the source for copying conditions. There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. Compiling C: main.c avr-gcc -c -mmcu=atmega32 -I. -gdwarf-2 -DF_CPU=16000000UL -Os -funsigned-char -funsigned-bitfields -fpack-struct -fshort-enums -Wall -Wstrict-prototypes -Wundef -Wa,-adhlns=obj/main.lst -std=gnu99 -MD -MP -MF .dep/main.o.d main.c -o obj/main.o Linking: main.elf avr-gcc -mmcu=atmega32 -I. -gdwarf-2 -DF_CPU=16000000UL -Os -funsigned-char -funsigned-bitfields -fpack-struct -fshort-enums -Wall -Wstrict-prototypes -Wundef -Wa,-adhlns=obj/main.o -std=gnu99 -MD -MP -MF .dep/main.elf.d obj/main.o --output main.elf -Wl,-Map=main.map,--cref --section-start=.text=0x0000, Creating load file for Flash: main.hex avr-objcopy -O ihex -R .eeprom main.elf main.hex srec_cat main.hex -Intel -Output main.srec -Motorola srec_cat: main.hex: 15: warning: no start address record Creating load file for EEPROM: main.eep avr-objcopy -j .eeprom --set-section-flags=.eeprom="alloc,load" \ --change-section-lma .eeprom=0 -O ihex main.elf main.eep Creating Extended Listing: main.lss avr-objdump -h -S main.elf > main.lss Creating Symbol Table: main.sym avr-nm -n main.elf > main.sym Size after: main.elf : section size addr .text 224 0 .data 0 8388704 .bss 0 8388704 .noinit 0 8388704 .eeprom 0 8454144 .stab 876 0 .stabstr 132 0 .debug_aranges 20 0 .debug_pubnames 43 0 .debug_info 138 0 .debug_abbrev 86 0 .debug_line 198 0 .debug_str 128 0 Total 1845 -------- end -------- Process terminated with status 0 (2 minutes, 29 seconds) 0 errors, 1 warnings
--------------------
Выбор.
|
|
|
|
|
May 15 2007, 07:14
|
Участник

Группа: Новичок
Сообщений: 28
Регистрация: 15-05-07
Пользователь №: 27 727

|
Спасибо. Сажусь "ковыряться" дальше.
Еще попутный вопрос по WINAVR. Почему иногда программа выдает в новом проекте при попытке компиляции следующее:
-------- begin -------- avr-gcc (GCC) 3.4.6 Copyright © 2006 Free Software Foundation, Inc. This is free software; see the source for copying conditions. There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
make.exe: *** No rule to make target `obj/main.o', needed by `main.elf'. Stop.
> Process Exit Code: 2 > Time Taken: 00:00
Скажу откровенно, решаю это "танцами с бубном", а вот конкретно, что не так? В каталоге проекта изначально лежат два файла - файл.c и makefile
|
|
|
|
|
May 15 2007, 15:57
|

Местный
  
Группа: Участник
Сообщений: 403
Регистрация: 14-05-07
Из: Россия, г.Пенза
Пользователь №: 27 719

|
Цитата(Jagupop @ May 15 2007, 15:14)  Спасибо. Сажусь "ковыряться" дальше.
Еще попутный вопрос по WINAVR. Почему иногда программа выдает в новом проекте при попытке компиляции следующее:
-------- begin -------- avr-gcc (GCC) 3.4.6 Copyright © 2006 Free Software Foundation, Inc. This is free software; see the source for copying conditions. There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
make.exe: *** No rule to make target `obj/main.o', needed by `main.elf'. Stop.
> Process Exit Code: 2 > Time Taken: 00:00
Скажу откровенно, решаю это "танцами с бубном", а вот конкретно, что не так? В каталоге проекта изначально лежат два файла - файл.c и makefile Как это не смешно, но я тоже ловился на эту удочку  Ты просто забываешь поставить расширение файла (myfile. c.) или cpp.
--------------------
" Многие вещи нам непонятны не потому, что наши понятия слабы; но потому, что сии вещи не входят в круг наших понятий." (с) К.Прутков.
|
|
|
|
|
May 16 2007, 03:38
|

Профессионал
    
Группа: Свой
Сообщений: 1 202
Регистрация: 26-08-05
Из: Донецк, ДНР
Пользователь №: 7 980

|
Привет всем.
Использую WinAVR 20070122. Проект использует все 3 таймера (с помощью avrLib) с прерываниями по переполнению, и USART с прерываниями (avrLib). работает великолепно, как часы. Еще там висит LCD 20x4, тоже управляемый avrlib. Подключил внешние прерывания - INT0 от IR датчика, INT1 - просто кнопка в землю, так для отладки. Обработчики:
// INT0 handler // edge from IR receiver detected. This is assumed to be the middle of a bit. //ISR ( INT0_vect ) SIGNAL ( SIG_INTERRUPT0 ) { count0 ++; .............
return 0; } // int0
// INT1 handler by low ISR ( INT1_vect ) { count1 ++;
if ( ledFlag == 0 ) { LED3_ON; ledFlag = 1; } // if else { LED3_OFF; ledFlag = 0; } // else return 0; } // int1
Заголовки специально написал по-разному. При компиляции этого богатства лезут предупреждения:
main.c:97: warning: return type defaults to `int' main.c:97: warning: function declaration isn't a prototype main.c: In function `SIGNAL': main.c:97: warning: type of "__vector_1" defaults to "int" main.c: At top level: main.c:128: warning: return type defaults to `int' main.c:128: warning: function declaration isn't a prototype main.c: In function `ISR': main.c:128: warning: type of "__vector_2" defaults to "int"
Т.е. ругаеся на оба вектора.
Игнорирую, прошиваю, запускаю. При нажатии кнопки на ДУ - сброс проца, как по reset. При нажатии кнопки на INT1 - такой же сброс.
Взял WinAVR 20060421 - точь-в-точь то же самое.
На CvAVR подобный вещи работают идеально на этой же самой микросхеме. Вывод - или я чего-то не добираю в WinAVR, или он глючит.
Найти примеов под WinAVR с внешними прерываниями мне не удалось.
Кто-нибудь знает, как это побороть? Перенести проект в CVAVR нереально - там не работают другие вещи, работающие в WinAVR. Куда не кинь всюду клин ...
--------------------
Чтобы возить такого пассажира, необходим лимузин другого класса. (с) Мария Эдуарда
|
|
|
|
|
May 16 2007, 05:51
|

Профессионал
    
Группа: Свой
Сообщений: 1 202
Регистрация: 26-08-05
Из: Донецк, ДНР
Пользователь №: 7 980

|
Цитата(aesok @ May 16 2007, 10:46)  В С файле есть строка #include <avr/interrupt.h>?
Анатолий. Ха, прозевал .. Нема такой. Спасибо. Вставил, warning-и пропали, 2006 WinAVR откомпилил молча. А работает или нет, проверю позже и отпишу.
--------------------
Чтобы возить такого пассажира, необходим лимузин другого класса. (с) Мария Эдуарда
|
|
|
|
|
Sep 20 2010, 20:21
|
Участник

Группа: Участник
Сообщений: 22
Регистрация: 20-09-10
Из: Киев
Пользователь №: 59 612

|
Доброго времени суток! Имеется такой простенький код: CODE #include <avr/io.h> #include <math.h>
double b=15.485; double tmpVar;
int main (void) { tmpVar = floor(b); //берем целую часть от 15.485, т.е. 15 while (1) { char i=1; } return (0); } Компилируется нормально. Олаживаю в avr studio. При выполнении команды tmpVar = floor(b) переменной tmpVar должно быть присвоено значение 15, но вместо этого выполнение передается в цикл, и в окне Watch в качестве значения переменной tmpVar появляется "Not in Scope", а на следующем шаге обратно из цикла и при этом в окне watch появляется значение переменной tmpVar равное 15. И далее выполнение программы продолжается правильно. Похожая программа написанная в codeVision AVR в avr studio работает корректно. Такой код работает правильно: CODE #include <avr/io.h> #include <math.h>
double tmpVar;
int main (void) { tmpVar = floor(15.485); while (1) { char i=1; } return (0); } Подскажите, пожалуйста, в чем может быть ошибка.
Сообщение отредактировал the_last_dreamer - Sep 20 2010, 20:23
|
|
|
|
|
Sep 21 2010, 11:27
|

Нечётный пользователь.
     
Группа: Свой
Сообщений: 2 033
Регистрация: 26-05-05
Из: Бровари, Україна
Пользователь №: 5 417

|
Цитата(the_last_dreamer @ Sep 20 2010, 23:21)  Такой код работает правильно: Правильно работают оба кода. В чём смысл представленной программы при наружном наблюдении за её поведением? Крутиться в бесконечном цикле. При этом внутренние детали поведения, никак не проявляющиеся снаружи, компилятор имеет право выоптимизировать начисто. Во втором случае он всего лишь поленился это сделать. Объявите tmpVar как volatile, сказав тем компилятору, что он не имеет права предполагать что-то по поводу видимости этой переменной из внешнего по отношению к программе мира, и наслаждайтесь. Или присвойте значение этой переменной какому-то порту микроконтроллера - нужно дать понять компилятору, что результат floor() кому-то нужен. Хотя и в этом случае он имеет право пробросить результат floor() прямо в порт, исключив из программы переменную tmpVar как не имеющую значения со стороны внешнего наблюдателя.
--------------------
Ну, я пошёл… Если что – звоните…
|
|
|
|
|
Sep 21 2010, 20:40
|
Участник

Группа: Участник
Сообщений: 22
Регистрация: 20-09-10
Из: Киев
Пользователь №: 59 612

|
>ну дык посмотрите ассемблерные листинги. К сожалению, ассемблер не знаю, хотя разобраться в нем и надо бы. >а если выполнить присвоение перед выполнением функции? поменять опции оптимизатора? компилировал при уровне оптимизации 0. Не помогло >Объявите tmpVar как volatile, сказав тем компилятору, что он не имеет права предполагать что-то по поводу видимости этой переменной из внешнего по отношению к программе мира, и наслаждайтесь. Большое спасибо за совет. Работает
Сообщение отредактировал the_last_dreamer - Sep 21 2010, 20:41
|
|
|
|
|
Sep 22 2010, 20:30
|
Участник

Группа: Участник
Сообщений: 22
Регистрация: 20-09-10
Из: Киев
Пользователь №: 59 612

|
Извините за беспокойство, но она все-таки не работает  Приведу более толковый текст программы: CODE #include <avr/io.h> #include <avr/interrupt.h> #include <math.h>
/****************************************************************** Здесь еще есть обработчики прерываний при переполнении таймеров, дополнительные процедуры и т.д. и т.п. Их текст не привожу, чтобы не усложнять чтение программы. ******************************************************************/
volatile unsigned int OCR1AMaxValue=9900; volatile unsigned char ADCresult=255;
ISR(ADC_vect) { //Запись в переменную ADCresult значения АЦ преобразования ADCresult=ADCH; //Запись в регистр OCR1A целого выражения OCR1A=floor(ADCresult/255*OCR1AMaxValue); //Ошибка в этой строке, как мне кажется //Начать новое преобразование ADCSRA|=(1<<ADSC); }
int main (void) { SREG=1<<7; //Установка вывода OC1A при совпадении значений регистров OCR1A и TCNT1 TCCR1A|=(1<<COM1A1)|(1<<COM1A0); //Включение АЦП. Разрешение прерываний от АЦП. //Предделитель частоты - 32 ADCSRA|=(1<<ADEN)|(1<<ADIE)|(1<<ADPS2)|(1<<ADPS0); //Выбор опорного напряжения. Выбор аналогового входа ADMUX|=(1<<REFS0)|(1<<MUX0); //Левостороннее выравнивание ADMUX|=(1<<ADLAR); //Начать первое преобразование ADCSRA|=(1<<ADSC); while (1) { //Без этой строки похоже тоже не обойтись. Компилятор выбрасывает пустой цикл из программы char i=1; } return (0); } МК выполняет аналогово-цифровое преобразование. В регистр OCR1A необходимо записать целое число значение которого вычисляется по формуле: floor(OCR1AMaxValue*ADCResult/255). При отладке в Avr Studio происходит следующее (может все слишком подробно описано, но я уже начинаю думать, что я что-то не так делаю в отладчике): 1. В функции main установка битов в регистрах АЦП проходит правильно. 2. После того как программа входит в бесконечный цикл ввожу в регистр ADCH произвольное значение. Например, 64. 3. Устанавливаю breakpoint при входе в обработчик прерываний от АЦП. 4. Нажимаю F5. 5. Программа входит в тело процедуры ISR(ADC_vect). 6. Нажимаю F11. 7. Программа присваивает переменной ADCresult значение 64. 8. Нажимаю F11, когда курсор находится в строке OCR1A=floor(ADCresult/255*OCR1AMaxValue). 9. И в этот момент курсор перескакивает в бесконечный цикл, на строку char i=1. В окне watch значения переменной ADCresult=Not In Scope. 10. Нажимаю F11. Курсор возвращается в обработчик прерывания в строк ADCSRA|=(1<<ADSC). В окне watch ADCresult=64. Но в OCR1A все нули, хотя должно быть 64/255*9900=2484. 11. Далее выполнение программы идет нормально - ожидаем новое прерывание от АЦП. При его возникновении история повторяется. Компилировал при OPT = 0. Если я правильно понимаю, то компилятор вообще ничего не должен оптимизировать? Может быть я не понял что-то в предыдущих ответах... WinAVR у меня 20090313. Может быть в нем причина? Может ли данная ситуация быть просто глюком AVRStudio, а в реальном устройстве работать правильно? Подскажите, пожалуйста, в чем ошибка.
Сообщение отредактировал the_last_dreamer - Sep 22 2010, 20:33
|
|
|
|
|
Sep 22 2010, 22:04
|

Гуру
     
Группа: Модераторы
Сообщений: 8 455
Регистрация: 15-05-06
Из: Рига, Латвия
Пользователь №: 17 095

|
Цитата(the_last_dreamer @ Sep 22 2010, 23:30)  Но в OCR1A все нули, хотя должно быть 64/255*9900=2484. Нет, должно быть 0. Ибо деление в целых числах N/255 даст 0 для любого N меньше 255. Ваша ошибка в том, что вы не учитываете эффектов округления и не знаете правил неявного приведения типов. Совершенно не нужно в прерывании использовать функции, работающие с плавающей точкой. Вообще плавающая точка здесь совершенно не нужна. напишите OCR1A = (unsigned long)ADCresult * OCR1AMaxValue / 255; Цитата(the_last_dreamer @ Sep 22 2010, 23:30)  WinAVR у меня 20090313. Может быть в нем причина? Может ли данная ситуация быть просто глюком AVRStudio Агащазблин. Есть хорошая поговорка про зеркало...
--------------------
На любой вопрос даю любой ответ"Write code that is guaranteed to work, not code that doesn’t seem to break" ( C++ FAQ)
|
|
|
|
|
Sep 23 2010, 19:31
|
Участник

Группа: Участник
Сообщений: 22
Регистрация: 20-09-10
Из: Киев
Пользователь №: 59 612

|
Спасибо, Сергей Борщ! В регистр теперь записывается то число что нужно.
|
|
|
|
|
Jan 22 2011, 15:27
|

Местный
  
Группа: Свой
Сообщений: 401
Регистрация: 7-05-10
Из: Оренбург
Пользователь №: 57 135

|
Добрый день. По понятным, я думаю, причинам пришлось перейти с CVAVR на WINAWR. Скачал последнюю версию 20100110 и с первой же попытке компиляции простой программки сел в "галошу". Во первых в этой версии нет ни одного примера, пришлось использовать старые источники информации. С первой же попытки было сообщение о том что не верно указан адрес библиотеки <avr/delay.h>, а также об ошибочном макроопределении _delay_loop_2(). Насколько я понял, это макроопределение уже не используется. Уважаемые коллеги, пделитесь пожалуйста примерами по этой системе, и подскажите в каких разделах прилагаемой документации можно найти примеры применения самых ходовых макроопределений. Спасибо.
--------------------
Лень, оттвори дверь, сгоришь - а хоть и сгорю, но не оттворю.
|
|
|
|
|
Jan 23 2011, 07:27
|

Местный
  
Группа: Свой
Сообщений: 401
Регистрация: 7-05-10
Из: Оренбург
Пользователь №: 57 135

|
Цитата(ReAl @ Jan 23 2011, 00:31)  WinAWR-20100110/doc/avr-libc/avr-libc-user-manual.pdf Примеры тоже есть. WinAWR-20100110/doc/avr-libc/examples/stdiodemo - тут используется <util/delay.h> Очень вам благодарен, спасибо!
--------------------
Лень, оттвори дверь, сгоришь - а хоть и сгорю, но не оттворю.
|
|
|
|
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0
|
|
|