Форум по Роботика
Технически форум => Програмиране => Темата е започната от: Borislav в Юни 26, 2007, 09:56:57 am
-
Ето, че настана време да започваме да се учим на програмиране! Сега ще ви обясня основните настройки на програмата, с която ще програмираме. За целта ще използваме WinAVR - една от най-популярните програми за програмиране на роботи!
Първо е необходимо да създадем папка, където ще се намират файловете на Вашия проект. Названието на папката е по Ваш избор, а мястото и е добре да е там, където сте инсталирали пакета на WinAVR.
И така...да започваме! Отваряме редактора на програмиста Programmers Notepad [WinAVR]. Можете да си оставите иконка на Десктопа. В менюто на редактора трябва да изберете File -> New -> C/C++ и въвеждаме програма на езика Си.
/************************************************
ПРИМЕР ЗА МИГАНЕ НА СВЕТОДИОДИ
*************************************************/
#include <avr/io.h>
#include <avr/delay.h>
#define F_CPU 8000000UL // 8 MHz
int main(void) // начало на основната програма
{
DDRD = 0xff; // Всички изводи на порта D трябва да се конфигурурат като изводи
while (1) { // Безкраен цикъл
PORTD = 0xff; // установяваме "1" на всички линии на порта D
_delay_ms(250); // Чакаме 0.25 сек.
PORTD = 0x00; // установяваме "0" на всички линии на порта D
_delay_ms(250); // Чакаме 0.25 сек.
} // закриваща скобка на безкрайния цикъл
} // Закриваща скобка на основната програма
Съхраняваме листингът на програмата във файл, с име "my_test.c" Името на файла е по ваш избор, без интервали, и с разширение ".c". След това затваряме Programmers Notepad.
-
Урок 2:
Създаване на файл - Makefile
В WinAVR, изходният текст на програмата се компилира с помощта на утилита make.exe, която се намира в папка WinAVR\utils\bin. Make.exe контролира генерацията на използваните файлове от изходния код на програмата. За управление на този утилит се използват именно makefile-овете. Тя съобщава на компилатора какви програми да пуска, кой изходен код да генерира и т.н...
След инсталирането на WinAVR в папката WinAVR/sample може да се намери шаблон с името Makefile, която трябва да се копира в папката с проекта и вече оттам да се редактира.
Внимание! Makefile и компилираният файл (в случая my_test.c) трябва да се намират в ЕДНА папка!
Отваряме Makefile в редактора Programmers Notepad и ще редактираме няколко важни за компилатора инструкции.
Първо, задължително трябва да се посочи за какъв тип микроконтролер да бъде изходният код. Търсим следните редове:
# MCU name
MCU = atmega128
Първият ред е коментар, а във втория, вместо atmega128 пишем този микроконтролер, който ни интересува. (Например: atmega8, attiny2313, attiny26 и т.н.)
Частотата на използвания кварцов кристал (в Херци) се определя в редовете:
# Processor frequency.
F_CPU = 8000000
Името на проекта, а съответно и името на изходния файл, с функцията main и изходните файлове с разширение hex и cof, се определя в следните редове:
# Target file name (without extension).
TARGET = testpp
Тук, вместо testpp пишем нужното име на проекта (в нашия случай е my_test).
Търсим редовете:
# List C source files here. (C dependencies are automatically generated.)
SRC =
И след знака "равно" пишем $(TARGET).c, за да се получи това:
# List C source files here. (C dependencies are automatically generated.)
SRC = $(TARGET).c
Търсим редовете:
# List C++ source files here. (C dependencies are automatically generated.)
CPPSRC = main.cpp
След знака "равно" изтриваме. Трябва да се получи това:
# List C++ source files here. (C dependencies are automatically generated.)
CPPSRC =
След това, малко по-надолу намираме раздела:
#---------------- Programming Options (avrdude) ----------------
Търсим реда:
AVRDUDE_PROGRAMMER = stk500
и го заместваме с:
AVRDUDE_PROGRAMMER = stk200
След това, ще използваме за целта си упростен вариант за програматор. За тези, които още не са разбрали, STK200 е програматор от типа "Пет проводника". Ще има описание в съответната тема! :)
Търсим реда:
AVRDUDE_PORT = com1 # programmer connected to serial device
и заместваме с:
AVRDUDE_PORT = lpt1
Програматорът stk200 използва паралелния порт на компютъра - LPT (принтерският).
Освен това, в състава на WinAVR влиза и утилита MFile, която помага правилно да се редактира и състави Makefile-ът! Можете да я стартирате от Старт -> Програми (Programs) -> WinAVR -> MFile [WinAVR].
Това беше вторият урок! Очаквайте третият и последен, в който ще компилираме програмата, и след това вече започваме да правим схеми с експериментиране на програмите! :)
-
Урок 3:
Компилация на програмата
Заредете в редактора Programmers Notepad изходния текст на програмата my_test.c, в менюто изберете Tools -> [WinAVR] Make All. Командата Make All изпълнява компилирането на изходния код на програмата и в случай на отсъствие на грешки генерира файл, който може да се качва на микроконтролера от серията AVR!
Долу, в прозореца "Output" трябва да се появи следното съобщение за успешна компилация:
(http://robotics-bg.com/a/proz1.JPG)
А в папката на Вашия проект трябва да имате следните файлове:
(http://robotics-bg.com/a/proz2.JPG)
Най-важният от тези файлове за нас ще бъде my_test.hex. В него се пази шестнадесетиричният код за качване в паметта на програмите (Flash ROM) на микроконтролера.
:1000000012C02BC02AC029C028C027C026C025C0C6
:1000100024C023C022C021C020C01FC01EC01DC0DC
:100020001CC01BC01AC011241FBECFE5D4E0DEBF28
:10003000CDBF10E0A0E6B0E0E0E8F0E002C005903F
:100040000D92A036B107D9F710E0A0E6B0E001C0EC
:100050001D92A036B107E1F701C0D2CFCFE5D4E0C1
:10006000DEBFCDBF8FEF81BB282FE0E0F0E022BBE9
:10007000CF010197F1F712BACF010197F1F7F7CF4E
:00000001FF
Във файла my_test.eep се пази шестнадесетиричният код за качване на данни в енергонезависима памет (EEPROM).
Трябва да се доуточни, че след всяка редакция на кода, програмата трябва да бъде прекомпелирана, т.е. в редактора Programmers Notepad трябва да е изпълнено Tools -> [WinAVR] Make All.
Ако проектът се състои от няколко файлове, и вие сте редактирали само един от тях, тогава при повторната прекомпилация ще се компилира само редактираният файл! За пълна прекомпилация трябва да изпълните в началото следната функция: Tools -> [WinAVR] Make Clean, и след това командата [WinAVR] Make All. Командата Make Clean премахва всички файлове, генерирани от предната команда Make All.
Това бяха уроците с WinAVR! Вече мога да ви дам линк за изтегляне на програмата!
Можете да я изтеглите от ТУК (http://winavr.sourceforge.net/download.html)
Успех на всички!!! :)
-
Да допълня малко темата. Първо какво предствалява WinAVR, това е пакет програми базиран на AVR-GCC кoмпилатора и позволява неговото използване по Windows. Пакета е безплатен и дава възможност свободно да се създават и компилират C програми за AVR. Борислав е описал добре работата с WinAVR, като отделна програма. Съеществува и възможност тя да се използва като plug-in съвместно с друга програма AVRStudio. Въпросното AVRStudio e интегрирана среда за разработка на фирмата ATMEL, включва в себе си project manager, асемблер, симулатор, подръжка на различни видове дебъгери и програматори. Хубавото е че тя позволява към нея да се добави WinAVR и да се получи напълно интегрирана среда за разработка, включваща в себе си и C компилатор. AVRStudio е безплатно програма и може да се изтегли от сайта на фирмата ATMEL на този адрес:
http://www.atmel.com/dyn/products/tools_card.asp?tool_id=2725
За съжаление въведоха една досадна регистраци при изтегляне на средата, която смятам че за любителски цели е ненужна, така че за момента може да се изтегли директно от тук:
http://www.atmel.com/dyn/resources/prod_documents/aStudio4b528.exe
Големината е около 70MB. В следващите теми ще опитам да обясня накратко как се създава проект и се компилира.
_________________
-
Благодаря на Borislav и yasko за полезната информация и за да улесня българите с бавен международен интернет ще дам този линк: http://datamatrix.bgshare.com/robotica/aStudio4b528.exe
-
Ясене, много важно разяснение! Благодаря за помощта! :) Много интересна информация. Ще си изтегля програмката, за да видя за какво става въпрос. Мерси още веднъж!
-
Както бях обещал ще се опитам да разкажа как да направим един елементарен проект с AVRStudio и WinAVR. За целта трябва да имаме инсталирани въпросните 2 програми на комютъра. Линкове за изтегляне на AVRStudio има по-нагоре в темата, а последната версия на WinAVR може да бъде изтеглен от тук (http://sourceforge.net/project/showfiles.php?group_id=68108).
След като програмите са инсталирани, стартираме AVRStdio и от менюто "Project" избираме "New Project", след което изскача един диалогов прозорец. Оттам трябва да изберем първо типа на проекта има 2 избора:
"ATMEL AVR Assembler" или "AVR GCC",
тъй като ще правим пример на C избираме "AVR GCC". След това трябва да дадем име на проекта и да изберем дали да бъде създаден начален файл и директория. От позиция "Location" в диалогови прозорец може да изберем къде да се създаде проекта. Нека за име на проекта да изберем "led1" и да изберем да ни бъде създаден начален файл и директория. Натискаме "Finish" и проекта led1 есъздаден :) Програмата автоматично ни отворя началния файл с име "led1.c" в който може да почнем да пишем нашия код. Преди това обаче трябват да се направят някои други настройки по проекта.
От меню "Project" избираме "Configuration Options" и се отваря диалогов прозорец за основни настройки по проекта. Повечето от нещата имат стойности по подразбиране, но някои от тях задължително трябва да настроим:
1. Избираме "Device" или типа ма микроконтролера с който ще работим, сегашния пример ще го направим с ATmega8, така че избираме този процесор от падащото меню.
2. Задаваме в полето "Frequency", работната честота, най често това е честота на външния кварц (за това по късно), слагаме 8 000 000 Hz (8MHz)
3.От полето "Optimisations" избираме нивото на оптимизация на компилатора - за начало избираме ниво "Os" или оптимизация за големина на изпълнимия файл.
С това основните настройки са завършени и може да запчнем работата по писането на програмата.
В следващата тема ще опиша кратка програма, която да накара един светодиод да мига. (затова избрах име на проекта led1 :))
-
AVRStudio ми изглежда много добра програма! Настройките са лесни за изпълнение, а и интерфейса много ми допада! :) С огромно нетърпение очаквам урока за първата програма с въпросната AVRStudio.. Ясене, моля те, разкажи и дали има някакви тънкости при свързването на Микроконтролера с компютъра.. Браво!
-
Ей момчета - страхотни сте! Как сте го обяснили, та направо ми идва да почна да пиша и аз статии, че ме домързяло от известно време...
-
Време е да продължа с програмата за размигване на светодиода :)
Борислав е качил една примерна програма: my_test (http://robotics-bg.com/a/polezno/project/my_test.c)
Позволих си да корегирам и тествам някои неща и сега програмата доби следния вид:
#include <avr/io.h>
#include <util/delay.h>
#define F_CPU 8000000UL // 8 MHz
//функция генерираща закъснение в диапазона 1 -65535 ms
void delay_ms(unsigned int ms)
{
while (ms>0){
_delay_ms(1);
ms--;
}
}
int main(void) // начало на основната програма
{
DDRD = 0xFF; // Всички изводи на порта D трябва да се конфигурурат като изходи
while (1) { // Безкраен цикъл
PORTD = 0xFF; // установяваме "1" на всички линии на порта D
delay_ms(250); // Чакаме 0.25 сек.
PORTD = 0x00; // установяваме "0" на всички линии на порта D
delay_ms(250); // Чакаме 0.25 сек.
} // закриваща скобка на безкрайния цикъл
} // Закриваща скобка на основната
Утре ще продължа с коментарите и разясненията по програмата.
-
Малко се забавих с обяснението на прграмата, но продължавам.
И така да видим какво имаме в нашата програма. Първо чрез директивата include, включваме 2 файла с дефиниции "io.h" и "delay.h". Първия ни е небходим за да може да работим с портовете на процесора, а втория ни позволява да ползваме готови функции за генериране на закъснения.
След това следва дефиниция за тактовата честота микропроцесора, указваща на компилатора каква е реалната скорост на работа на микроконтролера. По нагоре, когато правихме настройките на нашия проект имаше подбна опция за тактовата честота. Реално и двата начина указват едно и също нещо, а кой точно ще ползваме е въпрос на предпочитание, все пак дефиницията в самия сорс файл е по универсално решение.
След това имаме дефинирана една функция delay_ms, но за нея по късно. Минаваме към нашата главна функция "main". Първото нещо, което правим е да инициализираме I/O порта на микроконторелера. Вхоно/ изходните портове (или за по кратко само портове) са връзката на микроконтролера с реалния свят, чрез тях той може да предава и приема информация. Реално всеки процесор разполага с няколко на брой порта, всеки от които е изграден от различен брой входно изходни лиинии, които са изведни на опрделени пинове на MCU Портовете се със двупосочни функции, могат да бъдат както входове така и изходи. В наши случай искаме да управляваме един свеотодиод закачен към порт D на микроконтролера. PORTD на ATMEGA8 разполага с 8 на брой линии, наименовани от PD0 до PD7 или накратко казано порта е 8 битовa големина. Нека да закачим светодиода към най малдшата линия PD0. За да може да упрвляваме светодиода трбява да конфигурираме въпрсония пин да работи като изход, това прави инструкцията: DDRD=0xFF (Реално тя конфигурира всички линии на PORTD, като изходи). И така следа като направихме тази инициализация влизаме в нашия основен цикъл. Обикновено при програмирането на MCU, това един безкраен цикъл в който се изпълняват всички неща от прогрмата. В нашия случай това е "while(1)" и сега да видим какво става в него: имаме "PORTD=0xFF", по този начин установяваме всички пинове на PORTD във високо ниво (5V) и светодиода който сложихме на PD0 ще получи напрежение и ще светне.
След това извикваме функцията delay_ms(250), която кара процесора да изчака и да безделничи 250ms :) Защо се наложи да напиша допълнителна функция "delay_ms()", а не ползвам вградената функция "_delay_ms()" , която е дал Борислав? Обясненението се крие по начина по който се генерира закъснението, обикновено това става като се прави цикъл в който се повтарят определени инструкции на процесора и тъй като времето за изпълнение е фиксирано и като знаем тактовата честота, може да генерираме закъснението което ни е необходимо. Вградената функция _delay_ms() при честота на процесора 8MHz, може да генерира максимум около 32ms изчакване, така че за да увелича времето до 250ms, аз си направих "delay_ms()", За да направя закъснение 250ms, аз извиквам функцията "delay_ms" с параметър 250 тя от своя старана вика 250 пъти вградената функция "_delay_ms()" с параметър 1, т.е изчакване 1 ms.
Оттук нататък нещата са ясни, чакаме 250ms през което диода свети, след това имаме: "PORTD = 0x00;", установяваме PORTD в нула и по този начин спираме нарежението на светодиода и той угасва, чакаме отново 250ms, през това време светодиода не свети и после с връщаме в началото на цикъла и отново го запалаваме и така нещата се повтрят.
Леле колко много изписах, надявам се да е полезно ще почина малко. че ме заболя пръстите от писане :)
-
Сега да обобщим накратко, имаме програма която кара един светодиод 2 пъти в секундата, т.е с честота 2 Hz, за генериране на закъснението ползваме помощна функция базирана на вградените функции за закъснения. Разбира се има и много по елегантни методи за генериране на големи закъснения чрез използване на вградените часовници в MCU, но за това по-късно. Недостатъка на горния метод е че докато чакаме да изтече времето, процесора не може да прави нищо друго, но в конкретния случай това не е проблем. По принцип този тип закъснение е по удачен при малки времена на закъсненията.
Вече може да продължим с компилацията, за целата посочения пример трябва да се прехвърли в нашия файл led1.c, който създадохме с нашия проект в AVRStdio. След това натискаме "F7" -"Build" и процеса на компилация започва. В долната половина има прозорец "Build", където се появява информация как протича процеса. Ако всичко е OK програмата ни дава информация какво количество от FLASH и RAM паметта използва нашата програма и ни уведомява че процеса ма билдване (незнам как да го преведа правилно "Build" на български) е приключил успешно. В директорията на нашия проект има подиректория "default", там ще намерим файл с име "led1.hex". Това е всъщност изпълнимия код, който трябва да запишем чрез програматора в микроконтролера. Но преди това ще продължа темата на Борислав относно тестовия хардуер за нашата програма и ще обяня някои неща относно хардуера:
http://www.robotics-bg.com/forum/viewtopic.php?p=171#171
-
Може ли с visual basic 2005 studio и тем подобните програми към пакета да се направи същата програма и да върви на определения робот?
-
Няма как да стане ако на робата си имаш примерно 8 битов MCU. Visual basic 2005 studio създава програми предназначени да работят на PC, ако на робота сложиш PC, тогава всичко е OK, но обикновено се ползват по скромни контролери, за тях между другото има и BASIC компилатори, но като цяло C се ползва най-много.
-
Нещо не разбрах,при "[WIinAVR]Make all"ли се качва програмата във контролера или после след компилацията по някакъв начин? :roll:
-
Нещо не разбрах,при "[WIinAVR]Make all"ли се качва програмата във контролера или после след компилацията по някакъв начин? :roll:
След компилиране, качваш *.hex-файла с програматора в микроконтролера! Това посредством PonyProg2000! :) Това е, поразрови се в личните си съобщения, бях ти го обяснявал преди време!
-
Тестова установка:
http://upload.robotics-bg.com/files/P1020818.JPG
Захранване -12/5 волта
http://upload.robotics-bg.com/files/P1020820.JPG
мигнатия свето диод
http://upload.robotics-bg.com/files/P1020822.JPG
е като качих интелския файл в атмегата -мига та се къса.
Добре ама не можах да го компилирм както е описано в поста.
PS
Платката е направена така че да може да се закачат сензори -светлинни и бутонен тип към МК,ще я монтирам на шаси от пласмаса.или метал ,връзката между силовата част и "мозъка" ще е на куплунг.
-
Как компилираш: през AVR Studio или чрез make файл? През AVR Studio съм тествал и нещата вървят.
-
и с двете не става.слагам файла в нотепада както е описано и ми излизат грешки -около 100...
С АВР студиото изобщо не иска да компилира файла
Много се извинявам ама грешката си е моя.понеже в настройките съм дал да ми програмира директно файла/CODE V AVR/и съм сложил чисто нов но дефектен чип/те даже са два!!! ама рискове на он-лайн пазаруването от китай!!/
Сега всичко е наред.Дажв взех че си оправих и пони програматора...
-
във училище уча С++ но още не мога да различа С и С++.
на какъв взик се програмират микроконтролерите (С или С++).
копирах един от кодовете за мигащ светлодиод и го компилирах но ми дава грешка още при библиотеките.в началото ,при създаването на файла го давам "source file"
знам че въпросите ми могат да звучат тапо но съм нов в тази област и ми трябва помощ.
Благодаря!
-
ako във двете опции за изчакването зададем числата съответно 1 милисекунда и 4 милисекунди ще получим ли на практика такова премигване, че диода да намали светлината си драстично,без да премигва видимо и ако направим това може ли да се каже че сме направили ШИМ?
-
Малко линкове за последните версии на:
AVR Studio 4.16 (build 628) (126 MB, updated 2/09)
http://www.atmel.com/dyn/resources/prod_documents/AvrStudio416Setup.exe
и WinAVR December 6, 2008:
http://sourceforge.net/project/showfiles.php?group_id=68108&package_id=66543&release_id=645436
-
Не се бях изразил точно в темата която постнах. Tрябва ми синтаксисът за "if" (работа с датчици). Например:
if( (какво трябва да се напише тук за да се провери 1 или 0 на някой пин) ) {}
-
Погледни този пост:
http://www.robotics-bg.com/forum/viewtopic.php?p=6240#6240
Всеки I/O порт на AVR има няколко регистъра през, които се управлява. Четенето става през PINX, където X е името на порта.
Примерно ако искаш да провериш дали пин PD3 на Порт D е във високо ниво:
if(PIND&(1<<PD3)){
}
-
Направих го както ми каза, но не се получи. Ето програмата:
#include <avr/io.h>
#include <avr/delay.h>
#define F_CPU 4000000UL
int main(void)
{
DDRD=0xff;
DDRC=0x00;
while (1) {
if (PINC&(1<<PC5))
{
PORTD|=_BV(PD1);
}
}
}
След като пусна захранването на схемата светодиодът свързан към D1 светва без да има сигнал (+5V) на пин C5 :? . Когато подавам сигнал към C5 нищо не се променя.
Къде може да е грешката?
-
В кода който си постнал, няма кой да загаси светодиода. Пробвай този код:
#include <avr/io.h>
#include <avr/delay.h>
#define F_CPU 4000000UL
int main(void)
{
DDRD=0xff;
DDRC=0x00;
while (1) {
if (PINC&_BV(PC5)){
PORTD|=_BV(PD1); //пали светодиода ако PC5=1
}
else{
PORTD&=~_BV(PD1); //гаси светодиода ако PC5=0
}
}
}
За тези които се чудят какво е _BV, това е вграден макрос. Дефиниране е по следния начин:
#define _BV(bit) (1 << (bit)) и следователно _BV(PC5) е еквиеалентно на (1<<PC5)
И накрая ако PC5 е оставан висящ във въздуха, няма гаранция какво ще бъде неговото входно състояние.
-
Пробвах и по този начин - пак същото :( . Но този път забелязах нещо: когато включа захранването диода светва, но когато подам сигнал на C5 - диода светва по-силно :?: и след като спра сигнала пак светва по-слабо. Значи реагира на сигнала ама неможе да изгасне напълно. Също така ми се струва че трепти когато няма сигнал.
Някакви идеи? :roll:
-
Благодарение на yasko успях да оправя схемата :clap: . Проблемът не е в програмата, а в това че когато C5 не е свързан никъде, се индуктират шумове и входа е в високо ниво. За да се премахнат, трябва да се сложи резистор към маса. Тогава входа е в ниско ниво и когато подам сигнал - светодиода светва :) .
-
може те ли да ми кажете как да направя цикъл за редуване на 4 вита от PORTD на ATMEGA8 така че да се получипреместващ регисър
-
Заредих програмата от началото с някой промени, защото моята Atmega8 е за 16MHz и си поиграх със времената за ''1'' и ''0'' на портовете, обаче на 10000ms мигането на светодиода не съответства на 1 секунда.Мига бързо, да не би да не съм настроил правилно честотата?И на 8 и на 16 еднакво мига
#include <avr/io.h>
#include <avr/delay.h>
#define F_CPU 16000000UL
int main(void)
{
DDRD = 0xff;
while (1) {
PORTD = 0xff;
_delay_ms(1000);
PORTD = 0x00;
_delay_ms(1000);
}
}
-
Прочети внимателно темата. В линка по-долу съм обяснявал защо не може да се ползвава _delay_ms() за големи закъснения.
http://www.robotics-bg.com/discussion/index.php?topic=33.msg1675#msg1675
-
Като променя
_delay_ms(250)
на delay_ms(250)
не иска да компилира, изписва ми:
C:\Users\pc\Desktop\default/../led4.c:14: undefined reference to `delay_ms'
-
Не четеш внимателно. Функцията delay_ms не е вградена и трябва да я добавиш към кода, за да може да я ползваш.
//функция генерираща закъснение в диапазона 1 -65535 ms
void delay_ms(unsigned int ms)
{
while (ms>0){
_delay_ms(1);
ms--;
}
}
-
Да, така е, не съм бил особено внимателен, а уж няколко пъти прехвърлих страниците на темата..
Благодаря!!! Обаче в по-старите теми на форума, както и тази тема, линковете които са дадени не работят, препращат ме в главната страница на форума