AVR үшін кодты қалай жазуға болады, C тілінде Atmel AVR микроконтроллерлерін бағдарламалау. AVR бағдарламалау

LPT портының бағдарламалаушысының схемалық диаграммасы суретте көрсетілген. Автобус жүргізушісі ретінде 74AC 244 немесе 74HC244 (K1564AP5), 74LS244 (K555AP5) немесе 74ALS244 (K1533AP5) микросхемасын пайдаланыңыз.

LED VD1 микроконтроллердің жазу режимін көрсетеді,

LED VD2 - оқу,

LED VD3 - тізбекке қуат көзінің болуы.

Схема ISP коннекторынан қуат беру үшін қажетті кернеуді алады, яғни. бағдарламаланатын құрылғыдан. Бұл схема қайта жобаланған STK200/300 бағдарламалаушы тізбегі (жұмыс жеңілдігі үшін жарық диодтары қосылған), сондықтан ол STK200/300 схемасымен жұмыс істейтін ДК бағдарламалаушы бағдарламаларының барлығымен үйлесімді. Бұл бағдарламашымен жұмыс істеу үшін бағдарламаны пайдаланыңыз CVAVR

Бағдарламалаушыны басып шығарылған схемада жасауға және суреттерде көрсетілгендей LPT қосқышының корпусына орналастыруға болады:




Бағдарламашымен жұмыс істеу үшін LPT портының кеңейтімін пайдалану ыңғайлы, оны өзіңіз жасауға оңай (мысалы, принтерге арналған Centronix кабелінен), ең бастысы жерге өткізгіштерді аямау (18- 25 қосқыш аяқтары) немесе сатып алыңыз. Бағдарламалаушы мен бағдарламаланатын чип арасындағы кабель 20-30 см-ден аспауы керек.

Мен МК оқуды ассемблерден бастау керек деп бір-екі рет айтқанмын. Веб-сайттағы бүкіл курс осыған арналды (бірақ бұл өте дәйекті емес, бірақ мен оны барабар көрініске дейін біртіндеп таратып жатырмын). Иә, бұл қиын, нәтиже бірінші күні болмайды, бірақ сіз контроллеріңізде не болып жатқанын түсінуді үйренесіз. Сіз оның қалай жұмыс істейтінін білесіз және маймыл сияқты басқа адамдардың көздерін көшіріп алмайсыз және оның неге кенеттен жұмысын тоқтатқанын түсінуге тырысасыз. Сонымен қатар, C үшін ең сәтсіз сәтте айырмен шығатын қызыл мойынсұнғыш кодты жасау оңайырақ.

Өкінішке орай, бәрі бірден нәтиже алғысы келеді. Сондықтан мен басқа жолмен жүруді шештім - C бойынша оқулық жасаңыз, бірақ оның іш киімін көрсете отырып. Жақсы ендірілген бағдарламашы әрқашан өзінің аппараттық бөлігін болттан мықтап ұстайды, рұқсатсыз бір қадам жасауға мүмкіндік бермейді. Алдымен C коды болады, содан кейін компилятор не шығарды және оның барлығы қалай жұмыс істейді :)

Екінші жағынан, C-ның күшті тұсы - кодтың тасымалдануы. Егер, әрине, сіз бәрін дұрыс жазсаңыз. Жұмыс алгоритмдерін және олардың аппараттық іске асыруларын жобаның әртүрлі бөліктеріне бөлу. Содан кейін, алгоритмді басқа микроконтроллерге көшіру үшін аппараттық құралға барлық шақырулар жазылатын интерфейс деңгейін ғана қайта жазып, барлық жұмыс кодын сол күйінде қалдыру жеткілікті болады. Және, әрине, оқылу мүмкіндігі. C бастапқы кодын бір қарағанда түсіну оңайырақ (бірақ... мысалы, маған нені көрсететінім маңызды емес - ол C немесе ASM :)), бірақ бәрі дұрыс жазылған болса. Мен де осы тұстарға назар аударамын.

Менің отладка тақтасы тәжірибелік жабдық ретінде қызмет етеді, оған барлық мысалдардың басым бөлігі орнатылады.

AVR үшін бірінші C бағдарламасы

Компиляторды таңдау және ортаны орнату
AVR үшін көптеген әртүрлі C компиляторлары бар:
Ең алдымен осы IAR AVR C- AVR үшін ең жақсы компилятор ретінде белгілі дерлік танылады, өйткені Контроллердің өзі Atmel мен IAR мамандары арасындағы тығыз ынтымақтастықта жасалған. Бірақ бәрін төлеу керек. Және бұл компилятор тек қымбат коммерциялық бағдарламалық құрал ғана емес, сонымен қатар көптеген параметрлерге ие, оны жай ғана құрастыру үшін көп күш қажет. Мен онымен достық қарым-қатынаста болған жоқпын;

Екінші келеді WinAVR GCC- қуатты оңтайландырушы компилятор. Толығымен ашық дереккөз, кросс-платформа, жалпы, өмірдің барлық қуаныштары. Ол сондай-ақ AVR Studio бағдарламасына тамаша біріктіріліп, дәл сол жерде жөндеуге мүмкіндік береді, бұл өте ыңғайлы. Жалпы, мен оны таңдадым.

Сондай-ақ бар CodeVision AVR Cөте танымал компилятор болып табылады. Ол өзінің қарапайымдылығына байланысты танымал болды. Сіз онда бірнеше минут ішінде жұмыс бағдарламасын ала аласыз - іске қосу коды шебері барлық нәрселерді инициализациялауға арналған стандарттарды белгілеу арқылы мұны айтарлықтай жеңілдетеді. Шынымды айтсам, мен бұған күдіктенемін - бір рет осы компилятор жазған бағдарламаны бөлшектеуге тура келді, ол код емес, қандай да бір ретсіздік болып шықты. Қажетсіз қозғалыстар мен операциялардың қорқынышты саны, нәтижесінде кодтың айтарлықтай көлемі және баяу өнімділік. Дегенмен, түпнұсқа микробағдарламаны жазған адамның ДНҚ-сында қате болған шығар. Оның үстіне ол ақшаны қалайды. IAR сияқты емес, бірақ байқалады. Ал демонстрациялық режимде ол 2кб-тан аспайтын код жазуға мүмкіндік береді.
Әрине, сызат бар, бірақ егер сіз ұрлайтын болсаңыз, бұл IAR мағынасында миллион :)

Тағы да бар Image Craft AVR CЖәне MicroCмикроэлектроникадан. Мен екеуін де қолдануға тура келмеді, бірақ S.W.G.өте мақтау MicroPascal, дейді олар, өте ыңғайлы бағдарламалау ортасы мен кітапханалар. Менің ойымша, MicroC одан да жаман болмайды, бірақ ол да ақылы.

Мен айтқанымдай, мен таңдадым WinAVRүш себеп бойынша: ол тегін, ол AVR Studio бағдарламасына біріктірілген және барлық жағдайларға арналған дайын кодтың бір тоннасы ғана жазылған.

Сондықтан WinAVR орнатуын AVR Studio арқылы жүктеп алыңыз. Содан кейін алдымен студия орнатылады, содан кейін WinAVR үстіне оралып, студияға плагин түрінде бекітіледі. Мен WinAVR-ді C:\WinAVR сияқты қысқа жолға орнатуды ұсынамын, осылайша сіз жолдармен байланысты көптеген мәселелерден аулақ боласыз.

Жоба құру
Сонымен, студия орнатылды, C орнатылды, бірдеңені бағдарламалауға тырысатын уақыт келді. Қарапайымнан, ең қарапайымынан бастайық. Студияны іске қосыңыз, сол жерден AVR GCC компиляторы ретінде жаңа жобаны таңдаңыз және жобаның атын енгізіңіз.

Жұмыс өрісі бос *.c файлымен ашылады.

Енді студия бетбелгілеріндегі жолдардың дисплейін конфигурациялау зиян тигізбейді. Мұны істеу үшін келесіге өтіңіз:
Мәзір құралдары - Параметрлер - Жалпы - FileTabs және ашылмалы тізімнен «Тек файл атауы» тармағын таңдаңыз. Әйтпесе, жұмыс істеу мүмкін болмайды - қойындыда файлдың толық жолы болады және экранда екі немесе үш қойындыдан артық болмайды.

Жобаны орнату
Жалпы, барлық тәуелділіктер сипатталған make файлын жасау классикалық болып саналады. Және бұл дұрыс шығар. Бірақ толық интеграцияланған IDE-мен өскен мен үшін uVisionнемесе AVR Studioбұл тәсіл өте жат. Сондықтан мен мұны өз жолыммен жасаймын, барлығын студияның көмегімен жасаймын.

Түймені беріліспен басыңыз.


Бұл сіздің жобаңыздың параметрлері, дәлірек айтқанда, make файлын автоматты түрде жасау параметрлері. Бірінші бетте сіз МК жұмыс істейтін жиілікті енгізуіңіз керек. Бұл сақтандырғыш биттеріне байланысты, сондықтан біздің жиілігіміз 8000000Гц деп есептейміз.
Оңтайландыру сызығына да назар аударыңыз. Енді -Os бар - бұл өлшемді оңтайландыру. Оны қазірге қалдырыңыз, содан кейін осы параметрмен ойнауға болады. -O0 мүлде оңтайландыру емес.

Келесі қадам жолдарды конфигурациялау болып табылады. Ең алдымен, жоба каталогын сол жерге қосыңыз - онда сіз үшінші тарап кітапханаларын қосасыз. Тізімде “.\” жолы пайда болады.

Make файлы жасалды, оны жобаңыздағы әдепкі қалтада қарауға болады, жай қарап, онда не бар екенін көріңіз.


Әзірге бәрі осы. Барлық жерде OK түймесін басып, көзге өтіңіз.

Мәселенің тұжырымы
Бос қағаз парағы қандай да бір айлакер идеяны жүзеге асыруға тырысады, өйткені диодтың жыпылықтауы енді жұмыс істемейді. Бірден бұқаны мүйізден алып, компьютермен байланысты іске асырайық - бұл менің бірінші істейтін ісім.

Ол келесідей жұмыс істейді:
COM портына бір (коды 0x31) келгенде, біз диодты жағамыз, ал нөл келгенде (код 0х30) ол өшеді. Сонымен қатар, бәрі үзілістерде орындалады, ал фондық тапсырма басқа диодтың жыпылықтауы болады. Қарапайым және мағыналы.

Тізбекті құрастыру
USB-USART түрлендіргіш модулін микроконтроллердің USART түйреуіштеріне қосу керек. Мұны істеу үшін екі сымнан секіргішті алыңыз және оны түйреуіштерге көлденең орналастырыңыз. Яғни, контроллердің Rx-ін түрлендіргіштің Tx-ке, ал түрлендіргіштің Tx-ін контроллердің Rx-іне қосамыз.

Соңында бұл диаграмма:


Мен қалған түйреуіштерді қосуды, қуаттандыруды, қалпына келтіруді қарастырмаймын, бұл стандартты

Код жазу

Маған бірден ескертпе жасауға рұқсат етіңіз, мен Си тілінің сипаттамасын арнайы зерттемеймін. Бұл үшін K&R классикалық «С бағдарламалау тілінен» бастап және әртүрлі нұсқаулықтармен аяқталатын материалдардың өте көп мөлшері бар.

Мен өзімнің қоймамнан осындай бір әдісті таптым. Мұнда бәрі қысқа, түсінікті және нақты. Мен оны біртіндеп жинап, веб-сайтыма апарып жатырмын.

Барлық тараулар әлі тасымалданбағаны рас, бірақ менің ойымша, бұл ұзаққа созылмайды.

Мен оны жақсырақ сипаттай алуым екіталай, сондықтан оқу курсынан нәзіктіктерді егжей-тегжейлі түсіндірудің орнына мен осы нұсқаулықтың жеке беттеріне тікелей сілтемелерді беремін.

Кітапханаларды қосу.
Ең алдымен, анықтамалары бар қажетті кітапханалар мен тақырыптарды қосамыз. Өйткені, Си - әмбебап тіл және біз оған AVR-мен арнайы жұмыс істеп жатқанымызды түсіндіруіміз керек, сондықтан бастапқы кодта жолды жазыңыз:

1 #қосу

#қосу

Бұл файл қалтада орналасқан WinAVRжәне ол контроллердің барлық регистрлері мен порттарының сипаттамасын қамтиды. Оның үстіне, мұнда бәрі айлакер, оны компилятор арқылы жіберетін белгілі бір контроллерге байланыстырады. жасаупараметрдегі файл MCUжәне осы айнымалы мәнге негізделген тақырып файлы осы нақты контроллерге арналған барлық порттар мен регистрлердің мекенжайларының сипаттамасы бар жобаңызға қосылады. Апыр-ай! Онсыз бұл да мүмкін, бірақ содан кейін сіз SREG немесе UDR сияқты символдық регистр атауларын пайдалана алмайсыз және «0xC1» сияқты әрқайсысының мекенжайын есте сақтауыңыз керек, бұл бас ауруы болады.

Команданың өзі #қосу<имя файла> кез келген мәтіндік файлдың мазмұнын жобаңызға қосуға мүмкіндік береді, мысалы, функциялар сипаттамасы бар файл немесе басқа код бөлігі. Директиваның бұл файлды табуы үшін біз жобаға жолды белгіледік (WinAVR каталогы әдепкі бойынша сонда тіркелген).

Негізгі функция.
Си бағдарламасы толығымен функциялардан тұрады. Оларды кез келген ретпен және әртүрлі тәсілдермен ұяшыққа салуға және бір-бірінен шақыруға болады. Әрбір функцияның үш қажетті параметрі бар:

  • Қайтару мәні, мысалы: күнә(x) x синусының мәнін қайтарады. Қысқасы, математикадағы сияқты.
  • Жіберілген параметрлер бірдей X.
  • Функция денесі.

Барлық жіберілген және қайтарылған мәндер деректерге байланысты қандай да бір түрде болуы керек.

Кез келген Си бағдарламасында функция болуы керек негізгінегізгі бағдарламаға кіру нүктесі ретінде, әйтпесе ол мүлде C емес :). Миллиондаған файлдардан біреудің бастапқы кодында main болуы арқылы сіз бұл бағдарламаның бәрі басталатын негізгі бөлігі екенін түсінуге болады. Ендеше сұрайық:

1 2 3 4 5 int main(void) (қайтару 0; )

int main(void) (қайтару 0; )

Міне, бірінші қарапайым бағдарлама жазылды, оның ештеңе жасамайтыны маңызды емес, біз енді ғана бастадық.

Біз не істегенімізді анықтайық.
intБұл негізгі функция қайтаратын деректер түрі.

Әрине, микроконтроллерде негізгіНегізінде ештеңе қайтарылмайды және теорияда болуы керек негізгі жарамсыз (жарамсыз), бірақ GCC бастапқыда ДК үшін жасалған және бағдарлама аяқталғаннан кейін мәнді операциялық жүйеге қайтара алады. Сондықтан GCC қосулы негізгі жарамсыз (жарамсыз)Ескерту арқылы ант береді.

Бұл қате емес, ол жұмыс істейді, бірақ маған ескертулер ұнамайды.

жарамсызбұл біз бұл жағдайда функцияға беретін деректер түрі негізгісондықтан да сырттан ештеңені қабылдай алмайды жарамсыз- муляж. Түтік ештеңені жіберу немесе қайтару қажет болмаған кезде қолданылады.

Міне, олар { } бұйра жақшалар - бұл бағдарлама блогы, бұл жағдайда функцияның денесі негізгі, код сол жерде орналасады.

қайтару- бұл негізгі функция аяқталғаннан кейін қайтарылатын қайтарылатын мән, өйткені бізде int, яғни сан бар, онда біз санды қайтаруымыз керек. Бұл әлі де мағынасы жоқ болса да, өйткені... микроконтроллерде біз тек негізгіден ешқайда кете алмаймыз. Мен нөлді қайтарамын. Өйткені бұл маңызды емес. Бірақ компилятор әдетте ақылды және бұл жағдай үшін код жасамайды.
Дегенмен, егер бұрмаланған болса, содан кейін негізгіСіз МК-ға бара аласыз - мысалы, жүктеуші бөліміне түсіп, оны орындаңыз, бірақ бұл өтпелі мекенжайларды түзету үшін микробағдарламамен төмен деңгейде өңдеуді қажет етеді. Төменде сіз өзіңіз көресіз және мұны қалай жасау керектігін түсінесіз. Не үшін? Бұл басқа сұрақ, 99,999% жағдайда бұл қажет емес :)

Біз мұны істедік және әрі қарай жүрдік. Айнымалыны қосайық, ол бізге қажет емес және онсыз айнымалыларды енгізудің мәні жоқ, бірақ біз үйреніп жатырмыз. Егер айнымалылар функция денесінің ішіне қосылса, онда олар жергілікті болады және тек осы функцияда болады. Функциядан шыққан кезде бұл айнымалы мәндер жойылады және ЖЖҚ жады маңыздырақ қажеттіліктерге бөлінеді. .

1 2 3 4 5 6 int main(void) (таңбасыз char i; қайтару 0; )

int main(void) (таңбасыз i; қайтару 0; )

қол қойылмағанқолтаңбасыз дегенді білдіреді. Екілік кескінде ең маңызды бит таңбаға бөлінген, бұл +127/-128 саны бір байтқа (таңбаға) сәйкес келетінін білдіреді, бірақ егер белгі алынып тасталса, ол 0-ден бастап сәйкес келеді. 255. Әдетте белгі қажет емес. Сондықтан қол қойылмаған.
менжай ғана айнымалы атау. Артық керек емес.

Енді біз порттарды инициализациялауымыз керек және UART. Әрине, сіз кітапхананы алып, қосып, UartInit(9600) түрін шақыра аласыз; бірақ содан кейін сіз шынымен не болғанын білмейсіз.

Біз мұны істейміз:

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 int main(void ) ( unsigned char i; #define XTAL 8000000L #define boudrate 9600L #бауд бөлгішті анықтау (XTAL/(16*бауд жылдамдығы)-1)#define HI(x) ((x)>>8) #define LO(x) ((x)& 0xFF) UBRRL = LO(bauddivider) ; UBRRH = HI(бергіш) ; UCSRA = 0; UCSRB = 1<< RXEN| 1 << TXEN| 1 << RXCIE| 0 << TXCIE; UCSRC = 1 << URSEL| 1 << UCSZ0| 1 << UCSZ1; }

int main(void) ( unsigned char i; #define XTAL 8000000L #define boudrate 9600L #define bouddevider (XTAL/(16*baudrate)-1) #define HI(x) ((x)>>8) #define LO( x) ((x)& 0xFF) UBRRL = LO(бауд бөлгіш);<

Қорқынышты ма? Шын мәнінде, нақты кодтың соңғы бес жолы ғана бар. Бәрі, сол #анықтауБұл препроцессорлық макро тілі. Ассамблеядағыдай дерлік материал, бірақ синтаксис сәл өзгеше.

Олар қажетті коэффициенттерді есептеу бойынша күнделікті операцияларыңызды жеңілдетеді. Бірінші жолда біз оның орнына айтамыз XTALсіз қауіпсіз 8000000 ауыстыра аласыз, және Л- типті көрсету, ұзын деп айту процессордың тактілік жиілігі. Бірдей баудрат— деректерді UART арқылы беру жиілігі.

таратушыкүрделірек, оның орнына алдыңғы екі формуланың көмегімен есептелген өрнек ауыстырылады.
Жақсы және Л.О.Және Сәлемтөменгі және жоғары байттар осы нәтижеден алынады, өйткені Ол бір байтқа сыймауы мүмкін. IN Сәлем X (макрос енгізу параметрі) сегіз рет оңға жылжытылады, нәтижесінде ең маңызды байт қана қалады. Және ішінде Л.О.біз биттік ЖӘНЕ 00FF санымен орындаймыз, нәтижесінде тек төменгі байт қалады.

Демек, жасалғанның бәрі бірдей #анықтауСіз оны қауіпсіз лақтырып, калькуляторда қажетті сандарды есептеп, оларды UBBRL = … жолдарына дереу енгізе аласыз. және UBBRH = …..

мүмкін. Бірақ! Мұны істе МҮМКІН ЕМЕС!

Бұл кез келген жолмен жұмыс істейді, бірақ сізде осылай аталатын болады сиқырлы сандар- еш жерден және белгісіз себептермен алынған құндылықтар, және егер сіз бір-екі жылдан кейін мұндай жобаны ашсаңыз, бұл құндылықтардың не екенін түсіну қиын болады. Қазірдің өзінде, жылдамдықты өзгерткіңіз келсе немесе кварц жиілігін өзгерткіңіз келсе, барлығын қайта есептеу керек болады, бірақ сіз кодтағы бірнеше санды өзгерттіңіз және болды. Жалпы, егер сіз кодер ретінде бренд болғыңыз келмесе, кодты оқуға, түсінікті және өзгертуге оңай болатындай етіп жасаңыз.

Сонда бәрі қарапайым:
Осы «UBRRL және Co» барлығы UART таратқышының конфигурациялық регистрлері болып табылады, олардың көмегімен біз әлеммен байланысамыз. Енді біз оларға қажетті жылдамдық пен режимді орнатып, қажетті мәндерді тағайындадық.

Жазу түрі 1<Мынаны білдіреді: 1 алып, орнына қойыңыз RXENбайтта. RXENбұл регистрдің 4-ші биті UCSRB, Сондықтан 1< 00010000 екілік санын құрайды, TXEN- бұл 3-ші бит және 1< 00001000 береді. Жалғыз "|" бұл биттік НЕМЕСЕ, сондықтан 00010000 | 00001000 = 00011000. Сол сияқты қалған қажетті конфигурация биттері орнатылып, жалпы үймеге қосылады. Нәтижесінде жиналған нөмір UCSRB-да тіркеледі. Қосымша мәліметтер USART бөліміндегі МК деректер парағында сипатталған. Сондықтан техникалық мәліметтерге алданып қалмайық.

Дайын, не болғанын көру уақыты. Компиляцияны басыңыз және эмуляцияны бастаңыз (Ctrl+F7).

Түзету
Прогресс жолақтарының барлық түрлері өтті, студия өзгерді және негізгі функцияға кіре берістің жанында сары көрсеткі пайда болды. Дәл осы жерде процессор қазіргі уақытта жұмыс істейді және модельдеу кідіртіледі.

Өйткені, бастапқыда ол UBRRL = LO(bauddivider) желісінде болды; Ақыр соңында, бізде анықтайтын нәрсе - бұл код емес, жай ғана алдын-ала есептеулер, сондықтан тренажер сәл түтіккен. Бірақ енді ол түсінді, бірінші нұсқау орындалды және егер сіз ағашқа көтерілсеңіз Енгізу/шығару көрінісі, USART бөліміне өтіп, сол жерде UBBRL байтына қарасаңыз, мән бар екенін көресіз! 0x33.

Бір қадам алға. Басқа тізілімнің мазмұны қалай өзгеретінін қараңыз. Сондықтан олардың барлығын қарап шығыңыз, барлық көрсетілген биттердің мен айтқанымдай орнатылғанына және олар бүкіл байт үшін бір уақытта орнатылғанына назар аударыңыз. Бұл «Қайтару» дегеннен ары қарай жүрмейді - бағдарлама аяқталды.

Ашылу
Енді симуляцияны нөлге қайтарыңыз. Сол жерді басыңыз Қалпына келтіру (Shift+F5). Бөлшектелген тізімді ашыңыз, енді контроллерде не болып жатқанын көресіз. Көрініс -> Бөлшектеуіш. Және ЖАЯА емес!!! Ассемблер!!! СҰРАҚ!!! КЕРЕК. Осылайша, кейінірек бірдеңе дұрыс емес болғанда, сіз кодта ақымақ болмайсыз және форумдарда ақсап сұрақтар қоймаңыз, бірақ бірден ішекке кіріп, қай жерде тұрып қалғаныңызды көріңіз. Онда қорқынышты ештеңе жоқ.

Алдымен топтамалар болады:

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 +00000000: 940C002A JMP 0x0000002A Секіру +00000002: 940C0034 JMP 0x00000034 Секіру +00000004: 940C0034 JMP 0x0009000000 0x00000034 Секіру +00000008: 940C0034 JMP 0x00000034 Секіру +0000000A: 940C0034 JMP 0x00000034 Секіру +0000000C: 9400000C: 940000003JMP4000 0000000E: 940C0034 JMP 0x000034 Секіру +00000010: 940c0034 JMP 0x00000034 Секіру +000012: 940c0034 JMP 0x00000030400 0000034 Секіру +00000016: 940C003 4 JMP 0x00000034 Секіру +00000018: 940c0034 JMP 0x00000034 Секіру +0000001a: 940JMP00403 JMP0040 0000001c : 940C0034 JMP 0x00000034 Секіру +0000001E: 940C0034 JMP 0x00000034 Секіру +00000020: 940C0034 JMP 0x009002: Jump MP 0x00000 034 Секіру +00000024: 940C0034 JMP 0x00000034 Секіру +00000026: 940C0034 JMP 0x00000034 Секіру +00000028: 90000000: 9000000C

00000000: 940C002A JMP 0x00002A Секіру +00000002: 940C0034 JMP 0x00000034 Секіру +00000004: 940C0034 JMP 0x000030400P JMP +0000304000 000034 Секіру +000008: 940C0034 JMP 0x00000034 Секіру +0000000a: 940c0034 JMP 0x00000034 Секіру +0000000C: 940c0034 JMP000000034 Jump : 940C0034 JMP 0x00000034 Секіру +00000010: 940C0034 JMP 0x00000034 Секіру +00000012: 940C0034 JMP 0x00000034 Секіру +04000 034 Секіру +00000016: 940C0034 JMP 0x00000034 Секіру +00000018: 940C0034 JMP 0x00000034 Секіру +0000001A: 940C0034 JMP0000C Jump000x : 940C0034 JMP 0x00000034 Секіру +0000001E: 940C0034 JMP 0x00000034 Секіру +00000020: 940C0034 JMP 0x00000034 Секіру +000000 03 4 Секіру +00000024: 940C0034 JMP 0x00000034 Секіру +00000026: 940C0034 JMP 0x00000034 Секіру +00000028: 940C0034 JMP04 Jump

Бұл үзіліс векторының кестесі. Біз оған кейінірек ораламыз, бірақ әзірге оның бар екеніне қарап, есте сақтаңыз. Бірінші баған – команда орналасқан флэш ұяшығының мекенжайы, екіншісі – пәрмен коды, үшіншісі – пәрменнің мнемоникалық нұсқауы, сол құрастыру нұсқауы, үшінші – команданың операндтары. Автоматты түсініктеме.
Демек, қарасаңыз, үздіксіз ауысулар бар. Ал JMP пәрменінің коды төрт байт, оның құрамында кері жазылған көшу адресі бар - төменгі мекенжайдағы төмен байт және 940С өту пәрменінің коды.

0000002B: BE1F OUT 0x3F, R1 шығысы енгізу/шығару орнына

Бұл нөлді 0x3F мекенжайында жазу Егер сіз енгізу/шығару көру бағанына қарасаңыз, 0x3F мекенжайы SREG регистрінің мекенжайы - контроллердің жалауша регистрі екенін көресіз. Анау. бағдарламаны нөлдік жағдайда іске қосу үшін SREG қалпына келтіреміз.

1 2 3 4 +0000002C: E5CF LDI R28,0x5F Бірден жүктеңіз +0000002D: E0D4 LDI R29,0x04 Бірден жүктеңіз +0000002E: BFDE OUT 0x3E,R29 I/O орналасуына шығыс +0000000/O8UTO, I/O орнына шығыс: B02F - I/O

0000002C: E5CF LDI R28,0x5F Бірден жүктеңіз +0000002D: E0D4 LDI R29,0x04 Бірден жүктеңіз +0000002E: BFDE OUT 0x3E,R29 I/O орналасуына шығыс +0000000, BFDE шығысы +0000000/O8UTODO шығысы: I/O орнына

Бұл стек көрсеткішін жүктеп жатыр. Енгізу/шығару регистрлеріне тікелей жүктей алмайсыз, тек аралық регистр арқылы. Сондықтан, алдымен LDI аралық деңгейге, содан кейін OUT - I/O. Стек туралы кейінірек айтып беремін. Әзірге бұл жедел жадының соңында ілінетін және мекенжайлар мен аралық айнымалыларды сақтайтын динамикалық жады аймағы екенін біліңіз. Енді біз стектің қай жерден басталатынын көрсеттік.

00000032: 940C0041 JMP 0x00000041 Секіру

Бағдарламаның ең соңына дейін өтіңіз, сонда бізде үзілістерге және өздігінен цикл жасауға тыйым салынады:

1 2 +00000041: 94F8 CLI жаһандық үзілісін өшіру +00000042: CFFF RJMP PC-0x0000 салыстырмалы өту

00000041: 94F8 CLI жаһандық үзілісін өшіру +00000042: CFFF RJMP PC-0x0000 салыстырмалы өту

Бұл негізгі функциядан шығу сияқты күтпеген жағдайлар болған жағдайда. Контроллерді мұндай циклден аппараттық құралдарды қалпына келтіру арқылы немесе, ең алдымен, бақылаушыдан қалпына келтіру арқылы шығаруға болады. Немесе, жоғарыда айтқанымдай, он алтылық редакторда түзетіп, жүрегіміз қалаған жерге жүгіріңіз. Сондай-ақ, өтудің екі түрі бар екенін ескеріңіз: JMP және RJMP біріншісі мекенжайға тікелей өту; Ол төрт байтты алады және бүкіл жад аймағы арқылы тікелей өтуге болады. Өтудің екінші түрі RJMP – салыстырмалы. Оның командасы екі байт алады, бірақ ол ағымдағы позициядан (мекен-жайдан) 1024 қадам алға немесе артқа жылжиды. Ал оның параметрлері ағымдағы нүктеден ауытқуды көрсетеді. Ол жиі пайдаланылады, өйткені флеште жарты кеңістікті алады және ұзақ ауысулар сирек қажет.

1 +00000034: 940C0000 JMP 0x00000000 Секіру

00000034: 940C0000 JMP 0x00000000 Секіру

Және бұл кодтың ең басына секіру. Қайта жүктеу. Мұнда барлық векторлардың секіретінін тексеруге болады. Бұдан шығатын қорытынды, егер сіз қазір үзілістерді қоссаңыз (олар әдепкі бойынша өшірілген) және үзіліс орын алса, бірақ өңдеуші жоқ болса, бағдарламалық құралды қалпына келтіру болады - бағдарлама ең басына қайта оралады.

Негізгі функция. Барлығы ұқсас, оны сипаттаудың да қажеті жоқ. Тек регистрлерге енгізілген есептелген санды қараңыз. Компилятордың препроцессоры таң қалдырады!!! Сондықтан «сиқырлы» сандар жоқ!

1 2 3 4 5 6 7 8 9 10 11 12 <

00000036: E383 LDI R24,0x33 Бірден жүктеңіз +00000037: B989 OUT 0x09,R24 15 енгізу/шығару орнына шығыс: UBRRH = HI(байланыс бөлгіш); +00000038: BC10 OUT 0x20,R1 16 енгізу/шығару орнына шығыс: UCSRA = 0; +00000039: B81B OUT 0x0B,R1 17 енгізу/шығару орнына шығыс: UCSRB = 1<

Міне, қате:

1 2 3 +0000003E: E080 LDI R24.0x00 Бірден жүктеңіз +0000003F: E090 LDI R25.0x00 Бірден жүктеңіз +00000040: 9508 RET Ішкі бағдарламаны қайтару

0000003E: E080 LDI R24.0x00 Бірден жүктеңіз +0000003F: E090 LDI R25.0x00 Бірден жүктеңіз +00000040: 9508 RET Ішкі бағдарламаны қайтару

Мәселе мынада, компилятор неге мұндай шыңдарды қосады? Бұл Return 0-ден басқа ештеңе емес, біз функцияны int main(void) деп анықтадық, сондықтан біз себепсіз тағы төрт байтты босқа жібердік :) Ал егер сіз void main(void) жасасаңыз, онда тек RET қалады, бірақ ескерту болады. Біздің негізгі функциямыз ештеңені қайтармайды. Жалпы, өзіңіз қалағандай жасаңыз :)

Қиын ба? Шамасы жоқ. Бөлшектеуіш режимінде қадамдық орындау түймесін басып, процессордың жеке нұсқауларды қалай орындайтынын, регистрлерге не болатынын қараңыз. Пәрмендер арқылы қозғалыс және соңғы цикл қалай жүреді?

Бір-екі күннен кейін жалғасын табады...

Оффтоп:
Алексей78Мен Firefox-қа арналған плагин жасадым, ол менің сайтымды және форумымды шарлауды жеңілдетеді.
Талқылау және жүктеу,

Мен бірден AVR контроллері үшін бағдарламалау ортасын таңдау туралы кеңес беруге мәжбүр болдым. Тек маған тәпішке лақтырмаңыз. Мен сәл ғана :)

Микроконтроллерлер үшін көптеген бағдарламалау тілдері бар. Сондай-ақ бірнеше бағдарламалау орталары бар және оларды бір-бірімен салыстыру дұрыс емес. Ең жақсы бағдарламалау тілдері жоқ. Бұл сізге ең қолайлы тіл мен бағдарламалау ортасын таңдау керек дегенді білдіреді.

Егер сіз қазір немен айналысу керектігін таңдау алдында тұрсаңыз, мұнда сізге бірнеше ұсыныстар берілген.

Алдыңғы бағдарламалау тәжірибесі.Бұрынғы бағдарламалау тәжірибеңізді елемеңіз. Бұл BASIC болса да. Мектепте баяғыда болса да. Бағдарламалау велосипедпен жүру сияқты - сіз бастаған кезде сіз ұмытып кеткен барлық нәрсені тез есте сақтайсыз. BASIC-тен бастаңыз - оны меңгеріңіз - кейін сіздің мақсаттарыңызға сәйкес келетін нәрсені таңдау оңайырақ болады.

Қоршаған ортадан көмек.Сіздің достарыңыз Паскаль тілінде жаза ма? Мәселе сіз үшін шешілді - Паскаль тілінде жазыңыз! Олар сізге әрқашан кеңес береді, кітапханалар береді және оқуға дайын жобаларды береді. Жалпы, олар сізді өз қауымдастығына қуана қарсы алады. Егер сіз керісінше жасасаңыз, сіз керісінше нәтиже аласыз. Ассемблерді оқуды шешсеңіз, ТМД индустриясының достары сізді қуантады. Көмек күтпеңіз.

AVR бағдарламалау туралы жақсы кітапкөп көмегін тигізеді. Өкінішке орай, олардың саны өте аз. Егер сіз кітапты кездестірсеңіз және бәрі өте қолжетімді түрде түсіндірілді деп ойласаңыз, оны қолданып көріңіз. Мен электрондық кітаптардан оқуды ұсынбаймын, оларды басып шығарыңыз; Кітап файлының ортасы мен мәтіні арасында ауысу өте ыңғайсыз. Кітапты оқуға және оны ауыстыруға алаңдамай, оны бірден сынап көру әлдеқайда жағымды, сонымен қатар сіз шеттерге ескертулер жасап, туындаған идеяларды жаза аласыз.

Бағдарламалау ортасы қарапайым.Егер тіліңізде таңдауға болатын бірнеше бағдарламалау ортасы болса, тартынбаңыз, ең қарапайымын таңдаңыз. Ол азырақ функционалды болсын. Оған қорқынышты шифрланған кодты құрастыруға рұқсат етіңіз. Ең бастысы, жұмысқа енді кірісу. Қарапайым ортада ыңғайлы болғаннан кейін, сіз неғұрлым жетілдірілген және «дұрыс» ортаға оңай ауыса аласыз. Сіз көбірек уақыт жоғалтамын деп айтатындарды тыңдамаңыз - олар қателеседі. Бастауыш сынып оқушыларына «Соғыс және бейбітшілікті» оқу ұсынылмайды - суреттері бар қарапайым кітаптар.

Кітапханалар.Тіл үйрену үшін кітапханалардың болуы даулы. Әрине, кейінірек олар өмірді әлдеқайда жеңілдетеді, бірақ бастапқыда «Қара жәшік» кітапханалары түсініксіз және тілді түсінуге нақты ықпал етпейді. Екінші жағынан, олар бағдарламаларды оқуды жеңілдетеді және бастаушыға көп күш жұмсамай-ақ күрделі бағдарламаларды құруға мүмкіндік береді. Сондықтан олардың қатысуы туралы көп алаңдамаңыз. Кем дегенде, алдымен.

Тиімді код.Бағдарламалауды үйрену үшін бағдарламалау ортасын тек ол құрастыратын кодтың қаншалықты тиімді екендігіне негізделген таңдау - жаман идея. Ең бастысы, оқуды бастағанда өзіңді жайлы сезіну – одан шығатыны оныншы нәрсе. Әрине, сіз мұны кейінірек жасай аласыз.

Сиқыршылар.Чиптің бортындағы кез келген құрылғы порттар арқылы конфигурациялануы керек. Процедура өте қиын және деректер парақтары қажет. Сонымен қатар, жаңадан бастағандар үшін оңай емес нюанстар бар. Сондықтан ортада шеберлердің болғаны өте құптарлық. Vyzards - SPI, I2C, USART және т.б. үшін автоматты тюнерлер. Қолдау көрсетілетін құрылғылар неғұрлым көп болса, соғұрлым жақсы. Сіз қажетті перифериялық параметрлерді орнатасыз және шебердің өзі көрсетілген параметрлерді қамтамасыз ететін кодты жасайды. Өмірді әлдеқайда жеңілдетеді.


Жалпы ұсыныстармұндай - бастапқы кезеңде бағдарламалау мүмкіндігінше қарапайым болуы керек (тіпті қарабайыр). Бағдарламалау ортасын үйрену оңай болуы керек (өйткені сізге біріншіден, бағдарламалауды меңгеру керек және параметрлермен айналысуға уақыт жұмсамау керек). Жақсырақ орысшаланған. Орыс нұсқаулығы мен үлгі бағдарламалар да пайдалы болар еді. Кристаллды қоршаған ортадан жыпылықтау мүмкіндігі қажет. Содан кейін, бағдарламалау негіздерін меңгерген сайын, сіз күрделі қабықшаларға ауыса аласыз.


Соңғы бір ұсыныс: нағыз кристалмен жұмыс жасаңыз. Оны өртеп жіберуден қорықпаңыз. Практикалық тәжірибе жинаңыз. Эмуляторлармен жұмыс (мысалы, Proteus), ол сізді дәнекерлеу үтікімен әбігерден босатқанымен, жұмыс бағдарламасынан және жарық диодының бірінші жыпылықтауынан алатын қанағаттануды ешқашан бере алмайды! Өз қолыңызбен нақты жұмыс диаграммасын жасағаныңызды түсіну сізге сенімділік пен алға жылжуға ынталандырады!

(7 377 рет барған, бүгін 1 рет келген)

Микроконтроллерлерді бағдарламалауды алғаш рет қолға алған және бұрын Си тілімен ешқашан таныс болмағандар үшін мен қысқаша кіріспе мақала жазуды шештім. Біз егжей-тегжейлі айтпаймыз, CodeVisionAVR-мен жұмыс істеу туралы жалпы түсінік алу үшін барлығы туралы аздап сөйлесеміз.

Толығырақ ақпаратты ағылшын тілінде CodeVision пайдаланушы нұсқаулығында табуға болады, сонымен қатар мен http://somecode.ru сайтын микроконтроллерлерге арналған C бойынша бейне сабақтары және Дейтелдің «С тілінде бағдарламалау» кітабын ұсынамын. Мен өзім пайдаланған тек жақсы кітап басталды.

Қандай әрекеттерді жасасақ та, бәрі де микроконтроллердің микробағдарламасына байланысты болатынынан бастайық. Микробағдарлама процесінің өзі келесідей жүреді: белгілі бір бағдарламаның көмегімен микробағдарлама файлы таңдалады, параметрлер таңдалады, түйме басылады және микробағдарлама тікелей жыпылықтайды, бұл шын мәнінде көшірме болып табылады. Музыканы немесе құжаттарды компьютерден флэш-дискке көшіргендей, процестің физикасы да бірдей.

Микробағдарламаның өзінде .hex кеңейтімі бар және микроконтроллерге түсінікті бір және нөл түріндегі нұсқаулар жиынтығы. Микробағдарламаны қайдан алуға болады? Сіз оны электроника веб-сайттарынан жүктей аласыз немесе өзіңіз жаза аласыз. Оны әзірлеу ортасы деп аталатын арнайы бағдарламаларда жазуға болады. Маған ең танымалдары AVR Studio, IAR, CodeVision, WinAVR... Бұл орталардың қайсысы жақсы немесе нашар екенін айту мүмкін емес. Бұл бағдарламалар негізінен ыңғайлылығымен, бағдарламалау тілімен және бағасымен ерекшеленеді деп айта аламыз. Бұл сайтта тек CodeVision қарастырылады.

Біз ортаны сұрыптадық, енді микробағдарламаны жазу процесін қарастырайық. CodeVision бағдарламасында алдымен жобаны жасау керек. Оны код шеберінің көмегімен немесе бос түрде жасауға болады. Кез келген жағдайда пайдаланылатын микроконтроллердің түрін таңдап, оның жиілігін көрсету керек. Шеберді пайдаланған кезде сізден бастапқы параметрлерді таңдау және параметрлермен бірге бастапқы кодты жасау сұралады. Содан кейін осы кодты өңдеуге болатын терезе пайда болады. Блокнот бағдарламасында бастапқы кодты жазып, оны параметрлерде жобаға тіркей аласыз.

Бастапқы код файлы - бұл бағдарламалау тіліндегі пәрмендер жиынтығы, CodeVision міндеті - бұл командаларды екілік кодқа аудару, сіздің міндетіңіз - осы бастапқы кодты жазу. CodeVision Си тілін түсінеді, бастапқы код файлдарында «.c» кеңейтімі бар. Бірақ CodeVision-де C тілінде қолданылмайтын кейбір конструкциялар бар, сондықтан көптеген бағдарламашылар оны ұнатпайды және қолданылатын тіл C-тәрізді деп аталады. Дегенмен, бұл маңызды жобаларды жазуға кедергі келтірмейді. Көптеген мысалдар, код генераторы және кітапханалардың үлкен жиынтығы CodeVision-ге үлкен артықшылық береді. Жалғыз теріс - бұл ақылы, бірақ код шегі бар тегін нұсқалары бар.

Бастапқы кодта пайдаланылатын микроконтроллердің түрі мен негізгі функциясы бар тақырып болуы керек. Мысалы, ATtiny13 пайдаланылады

#қосу void main(void) ( ) ;

#қосу void main(void) ( );

Негізгі функция алдында қажетті кітапханаларды қосуға, жаһандық айнымалыларды, тұрақтыларды және параметрлерді жариялауға болады. Кітапхана – бұл әдетте алдын ала жазылған кодты қамтитын «.h» кеңейтімі бар жеке файл. Кейбір жобаларда бізге бұл код қажет болуы мүмкін, бірақ басқаларында бізге қажет емес. Мысалы, бір жобада біз СКД дисплейлерді қолданамыз, ал екіншісінде олай емес. «alcd.h» СКД дисплейімен жұмыс істеу үшін кітапхананы келесідей қосуға болады:

#қосу #қосу void main(void) ( ) ;

#қосу #қосу void main(void) ( );

Айнымалылар - бұл белгілі бір мәндерді орналастыруға болатын жад аймақтары. Мысалы, екі сан қоссаңыз, нәтижені болашақта пайдалану үшін бір жерде сақтау керек. Алдымен айнымалыны жариялау керек, яғни. ол үшін жадты бөліңіз, мысалы:
int i=0;
анау. біз i айнымалысын жариялап, оған 0 мәнін орналастырдық, int — айнымалының түрі, немесе қарапайымырақ айтқанда, бөлінген жадының өлшемін білдіреді. Әрбір айнымалы тип тек белгілі бір мәндер ауқымын сақтай алады. Мысалы, int -32768-ден 32767-ге дейінгі сандар түрінде жазылуы мүмкін. Егер бөлшек бөлігі бар сандарды пайдалану қажет болса, онда айнымалы таңбалар үшін қалқымалы мән ретінде жариялануы керек, char түрін пайдаланыңыз;

бит, _бит 0 немесе 1 таңба -128-ден 127-ге дейін таңбасыз таңба 0-ден 255-ке дейін int -32768-ден 32767-ге дейін таңбасыз int 0-ден 65535-ке дейін ұзын int -2147483648-ден 2147483647-ден ± 919-ға дейін таңбасыз 75e- 38 - ±3,402e38

Негізгі функцияның ішінде негізгі бағдарлама қазірдің өзінде жұмыс істеп тұр. Функцияны орындағаннан кейін бағдарлама тоқтайды, сондықтан олар бір бағдарламаны үнемі қайталайтын шексіз while циклін жасайды.

void main(void) ( while (1) ( ) ; );

void main(void) ( while (1) ( ); );

Сіз бастапқы кодтың кез келген бөлігіне түсініктеме жаза аласыз, ол бағдарламаның жұмысына ешқандай әсер етпейді, бірақ жазылған кодқа ескертулер жасауға көмектеседі. Сіз екі қиғаш сызықпен жолға түсініктеме бере аласыз //одан кейін компилятор бүкіл жолды немесе бірнеше жолды елемейді /**/, мысалы:

/*Негізгі математикалық амалдар:*/ int i= 0 ; //i айнымалысын жариялаңыз және оған 0 мәнін беріңіз//Қосымша: i = 2 + 2 ; //Азайту: i = 2 - 2 ; //осы өрнекті орындағаннан кейін i айнымалысы 0-ге тең болады//Көбейту: i = 2 * 2 ; //осы өрнекті орындағаннан кейін i айнымалысы 4-ке тең болады//Бөліну: i = 2/2 ; //осы өрнекті орындағаннан кейін i айнымалысы 1-ге тең болады

/*Негізгі математикалық амалдар:*/ int i=0; //i айнымалысын жариялау және оған 0 мәнін беру //Қосымша: i = 2+2; //осы өрнекті орындағаннан кейін i айнымалысы 4-ке тең болады //Алу: i = 2-2; //осы өрнекті орындағаннан кейін i айнымалысы 0-ге тең болады //Көбейту: i = 2*2; //осы өрнекті орындағаннан кейін i айнымалысы 4-ке тең болады //Бөлу: i = 2/2; //осы өрнекті орындағаннан кейін i айнымалысы 1-ге тең болады

Көбінесе бағдарлама бір код бөлігінен екіншісіне ауысуы керек, бұл үшін шарттарға байланысты шартты if() операциялары бар, мысалы:

if(i>3) //егер i 3-тен үлкен болса, онда i мәнін 0 ( i=0; ) тағайындаңыз /*егер i 3-тен кіші болса, онда шарттың денесінен кейінгі кодқа өтіңіз, яғни. жақшадан кейін ()*/

Сондай-ақ if else -пен бірге қолданылуы мүмкін - әйтпесе

Егер мен<3) //если i меньше 3, то присвоить i значение 0 { i=0; } else { i=5; //иначе, т.е. если i больше 3, присвоить значение 5 }

Сондай-ақ «==» салыстыру операторы бар, оны «=» тағайындауымен шатастырмау керек. Кері операция «!="-ге тең емес, айталық

if(i==3)//егер i 3 болса, i мәнін 0 ( i=0; ) if(i!=5) //егер i 5 болмаса, i мәнін 0 ( i=0) мәнін тағайындаңыз; )

Күрделі нәрселерге – функцияларға көшейік. Сізде бірнеше рет қайталанатын белгілі бір код бөлігі бар делік. Оның үстіне, бұл кодтың өлшемі өте үлкен. Оны әр кезде жазу ыңғайсыз. Мысалы, i айнымалысын қандай да бір түрде өзгертетін бағдарламада D портының 0 және 3 түймелерін басқан кезде, i айнымалысының мәніне байланысты В портының аяқтарын қосатын бірдей код орындалады.

void main(void) ( егер (PIND.0== 0 ) //PD0 түймешігінің басылғанын тексеріңіз( егер (i== 0 ) //егер i==0 болса PB0 қосыңыз( PORTB.0= 1 ; ) егер (i== 5 ) // егер i==5 болса, PB1 қосыңыз( PORTB.1= 1 ; ) ) … егер (PIND.3== 0 ) // PD3 түймешігін тексеру кезінде де дәл осылай орындаңыз( егер (i== 0 ) ( PORTB.0= 1 ; ) егер (i== 5 ) ( PORTB.1= 1 ; ) ) )

void main(void) ( if(PIND.0==0) //PD0 жүйесіндегі түйменің басылғанын тексеріңіз ( if(i==0) //егер i==0 болса PB0 қосыңыз ( PORTB.0=1); ) if( i==5) // егер i==5 PB1 қосылса ( PORTB.1=1; ) ) ) ... if(PIND.3==0) // PD3 түймешігін тексеру кезінде дәл осылай орындаңыз. ( if(i==0 ) ( PORTB.0=1; ) if(i==5) ( PORTB.1=1; ) ) )

Жалпы алғанда, код өте үлкен емес, бірақ ол бірнеше есе үлкен болуы мүмкін, сондықтан өз функцияңызды жасау әлдеқайда ыңғайлы болар еді.
Мысалы:

void i_check() ( if (i== 0 ) ( PORTB.0= 1 ; ) if (i== 5 ) ( PORTB.1= 1 ; ) )

void i_check() ( if(i==0) ( PORTB.0=1; ) if(i==5) ( PORTB.1=1; ) )

void функцияның ештеңе қайтармайтынын білдіреді, бұл туралы толығырақ төменде i_check() - бұл біздің функцияның атауы, сіз оны қалағаныңызша атай аласыз, мен оны дәл осылай атадым - i тексеріңіз. Енді біз кодты қайта жаза аламыз:

void i_check() ( if(i==0) ( PORTB.0=1; ) if(i==5) ( PORTB.1=1; ) ) void main(void) ( if(PIND.0==0) ) //PD0 жүйесіндегі түйменің басылғанын тексеріңіз ( i_check(); ) ... if(PIND.3==0) ( i_check(); ) )

Код i_check() жолына жеткенде; содан кейін ол функцияның ішіне секіріп, ішіндегі кодты орындайды. Келісіңіз, код неғұрлым ықшам және түсінікті, яғни. функциялары бірдей кодты ауыстыруға көмектеседі, тек бір жол. Функция негізгі кодтан тыс жарияланғанын ескеріңіз, яғни. негізгі функция алдында. Бұл маған не үшін керек деп айта аласыз, бірақ сабақтарды оқып жатқанда сіз жиі функцияларды кездестіресіз, мысалы, СКД экранын тазалау lcd_clear() - функция ешқандай параметрді қабылдамайды және ештеңені қайтармайды, бірақ ол экран. Кейде бұл функция барлық басқа жолдарда қолданылады, сондықтан кодты үнемдеу анық.

Мәндерді қабылдағанда функцияны пайдалану әлдеқайда қызықтырақ көрінеді, мысалы, c айнымалысы бар және int түрінің екі мәнін қабылдайтын функция сомасы бар. Негізгі бағдарлама бұл функцияны орындаған кезде, аргументтер жақшаның ішінде болады, сондықтан «a» екіге, ал «b» 1-ге тең болады. Функция орындалады және «c» 3-ке тең болады. .

int c= 0 ; void sum(int a, int b) ( c= a+ b; ) void main(void ) ( sum(2 , 1 ) ; )

int c=0; void sum(int a, int b) ( c=a+b; ) void main(void) ( sum(2,1); )

Ең көп таралған ұқсас функциялардың бірі СКД дисплейінде курсорды жылжыту болып табылады lcd_gotoxy(0,0); ол, айтпақшы, аргументтерді де қабылдайды - х және у координаталары.

Функцияны пайдаланудың тағы бір нұсқасы, ол мәнді қайтарғанда, енді ол жарамсыз болмайды, екі санды қосу үшін функцияның алдыңғы мысалын жақсартайық:

int c= 0 ; int sum(int a, int b) (қайтару a+ b; ) void main(void) ( с= sum(2, 1) ; )

int c=0; int sum(int a, int b) ( a+b қайтару; ) void main(void) ( с=sum(2,1); )

Нәтиже соңғы рет c=3 болғанымен бірдей болады, бірақ біз «c» айнымалысына енді жарамсыз функцияның мәнін тағайындайтынымызды ескеріңіз, бірақ int түріндегі екі санның қосындысын қайтарады. Осылайша біз функцияларды пайдалану икемділігін қосатын белгілі бір «c» айнымалысына байланысты емеспіз. Мұндай функцияның қарапайым мысалы ADC деректерін оқу болып табылады, функция өлшенген мәнді нәтиже=read_adc(); қайтарады. Функциялармен аяқтаймыз.

Енді массивтерге көшейік. Массив - байланысты айнымалылар. Мысалы, сізде бірнеше нүктелері бар синустар кестесі бар, сіз айнымалы мәндерді жасамайсыз int sinus1=0; int sinus2=1; және т.б. Ол үшін массив қолданылады. Мысалы, келесідей үш элементтен тұратын массив жасауға болады:
int sinus=(0,1,5);
Жиым элементтерінің жалпы саны төртбұрышты жақшада көрсетілген. Үшінші элементтің мәнін «c» айнымалысына келесідей тағайындауға болады:
с=синус;
Жиым элементтерінің нөмірленуі нөлден басталатынын ескеріңіз, яғни. «c» беске тең болады. Бұл массивте синус элементі жоқ!!!
Жеке элементке келесідей мән тағайындауға болады:
синус=10;

CodeVision жүйесінде жол айнымалылары жоқ екенін байқаған боларсыз. Анау. hello="hello" айнымалы жолын жасай алмайсыз; Мұны істеу үшін сізге жеке таңбалар массивін жасау керек.

lcd_putchar(сәлем); lcd_putchar(сәлем); lcd_putchar(сәлем);

және т.б.
Бұл өте қиын болып шықты, бұл жерде циклдар көмекке келеді.
Мысалы, while циклі

while(PINB.0!=0) ( )

Түйме басылмайынша, ештеңе жасамаңыз - бос циклды іске қосыңыз.

Басқа опция for циклі болып табылады

int i; үшін (i= 0 ; i< 6 ; i++ ) { lcd_putchar(hello[ i] ) ; }

int i; үшін(i=0;i<6;i++) { lcd_putchar(hello[i]); }

Мағынасы while мәнімен бірдей, тек бастапқы шарт i=0 және әрбір i++ циклінде орындалатын шарт қосылады. Цикл ішіндегі код мүмкіндігінше жеңілдетілген.

Бағдарламаны жазғаннан кейін бастапқы код құрастырылады және қателер болмаса, сіз жоба қалтасында қалаған микробағдарламаны аласыз. Енді сіз микроконтроллерді жыпылықтап, құрылғының жұмысынан ләззат ала аласыз.

Микробағдарламада циклдарды, массивтерді және функцияларды бірден қолдануға тырыспауыңыз керек. Сіздің негізгі міндетіңіз - микробағдарламаның жұмысын қамтамасыз ету, сондықтан оны сізге оңайырақ етіп жасаңыз және кодтың өлшеміне назар аудармаңыз. Сіз тек жұмыс кодын жазып қана қоймай, оны әдемі және ықшам жазғыңыз келетін уақыт келеді. Сонда Си тілінің жабайы қырларына үңілуге ​​болады. Барлығын меңгергісі келетіндер үшін мен «С тілінде қалай бағдарламалау керек» кітабын ұсынамын, көптеген мысалдар мен тапсырмалар бар. Visual Studio бағдарламасын орнатыңыз, win32 консоль қосымшасын жасаңыз және сол жерде өз қалауыңыз бойынша жаттығу жасаңыз.


Осы avr оқу курсында мен микроконтроллерлерді бағдарламалауда жаңадан бастағандар үшін барлық негіздерді сипаттауға тырыстым авр. Барлық мысалдар микроконтроллерге салынған atmega8. Бұл барлық сабақтарды қайталау үшін сізге тек бір МК қажет болады дегенді білдіреді. Proteus электронды схема эмуляторы ретінде пайдаланылады - менің ойымша, жаңадан бастаушылар үшін ең жақсы нұсқа. Барлық мысалдардағы бағдарламалар avr CodeVision AVR үшін C компиляторында жазылған. Неліктен кейбір ассемблерде емес? Өйткені жаңадан бастаушы ақпаратпен жүктелген және екі санды көбейтетін бағдарлама ассемблерде шамамен жүз жолды алады және күрделі, батыл жобаларда олар C қолданады. CodeVision AVR компиляторы atmel микроконтроллерлеріне бейімделген, ыңғайлы код генераторы бар, жақсы интерфейс және тікелей сіз онымен микроконтроллерді жыпылықтай аласыз.

Бұл оқу курсы төмендегілерді қарапайым мысалдармен түсіндіреді және көрсетеді:

  • Микроконтроллерлерді бағдарламалауды бастаңыз, неден бастау керек, бұл үшін не қажет.
  • Avr үшін микробағдарламаны жазу, компьютерде кодты модельдеу және жөндеу үшін қандай бағдарламаларды пайдалану керек,
  • МК ішінде қандай перифериялық құрылғылар бар, оларды бағдарлама арқылы қалай басқаруға болады
  • Дайын микробағдарламаны микроконтроллерге қалай жазуға болады және оны қалай түзетуге болады
  • Құрылғыңызға PCB қалай жасауға болады
МК бағдарламалаудың алғашқы қадамдарын жасау үшін сізге тек екі бағдарлама қажет:
  • Proteus - бұл эмулятор бағдарламасы (онда сіз нақты дәнекерлеуге жүгінбестен схеманы жасай аласыз, содан кейін біздің бағдарламаны осы схемада сынай аласыз). Біз алдымен Proteus-те барлық жобаларды іске қосамыз, содан кейін біз нақты құрылғыны дәнекерлей аламыз.
  • CodeVisionAVR — AVR үшін C бағдарламалау тілінің компиляторы. Онда біз микроконтроллерге арналған бағдарламаларды әзірлейміз және одан тікелей нақты МК жыпылықтау мүмкін болады.
Proteus орнатқаннан кейін оны іске қосыңыз
Ол бізді өзімен бірге келетін жобаларды қарауға шақырады, біз сыпайы түрде бас тартамыз. Енді ондағы ең қарапайым схеманы құрайық. Мұны істеу үшін белгішені басыңыз және көрнекі түрде ештеңе болмайды. Енді кіші әріпті басу керек P (кітапханадан таңдау)құрамдас тізім тақтасында құрамдас таңдау терезесі ашылады
маска өрісінде кітапханадан тапқымыз келетін компоненттің атын енгізіңіз. Мысалы, бізге mega8 микроконтроллерін қосу керек
нәтижелер тізімінде мега8 тармағын меңзеп, түймесін басыңыз ЖАРАЙДЫ МА. Mega8 микроконтроллері біздің компоненттер тізімінде пайда болады
Осылайша, өріске маска сөзін енгізу арқылы компоненттер тізіміне тағы бір резисторды қосамыз ресжәне жарықдиодты Жарық диодты индикатор

Бөлшектерді диаграммаға орналастыру үшін бөлікті шертіңіз, содан кейін диаграмма өрісін басыңыз, құрамдас бөліктің орнын таңдап, қайтадан басыңыз. Сол жақтағы диаграммаға жер немесе жалпы негатив қосу үшін «Терминал» түймесін басып, Жерді таңдаңыз. Осылайша, барлық компоненттерді қосу және оларды қосу арқылы біз осы қарапайым схеманы аламыз
Міне, енді бірінші схемамыз дайын! Бірақ сіз ол не істей алады деп сұрай аласыз. Ештеңе. Ештеңе емес, өйткені микроконтроллер жұмыс істеуі үшін оған бағдарлама жазу керек. Бағдарлама – микроконтроллер орындайтын командалар тізімі. Бізге микроконтроллер аяққа орнатылуы керек PC0логикалық 0 (0 вольт) және логикалық 1 (5 вольт).

Микроконтроллерге арналған программаны жазу

CodeVisionAVR компиляторы арқылы бағдарламаны Си тілінде жазамыз. Түйіндемені іске қосқаннан кейін ол бізден не жасағымыз келетінін сұрайды: дереккөз немесе жоба Біз соңғысын таңдап, OK түймесін басыңыз. Содан кейін бізден CVAVR CodeWizard шеберін іске қосуды сұрайды (бұл жаңадан бастағандар үшін баға жетпес құрал, өйткені ол бағдарламаның негізгі қаңқасын жасай алады) таңдау Иә
Шебер Чип қойындысынан басталады, мұнда біз МК моделін таңдай аламыз - бұл mega8 және МК жұмыс істейтін жиілік (әдепкі бойынша, mega8 1 мегагерц жиілігіне орнатылған), сондықтан біз орнаттық. барлығы жоғарыдағы скриншотта көрсетілгендей. Порттар қойындысына өтіңіз
Atmega8 микроконтроллерінде 3 порт бар: C порты, D порты, В порты. Әрбір портта 8 түйреуіш бар. Порт аяқтары екі күйде болуы мүмкін:
  • Шығу
DDRx.y регистрін пайдалану арқылы біз пинді кіріс немесе шығыс етіп орнатуға болады. Егер кірсе
  • DDRx.y = 0 - шығыс сияқты жұмыс істейді КІРУ
  • DDRx.y = 1 істік қосулы ШЫҒУ
Істік шығыс ретінде конфигурацияланған кезде, оны логикалық 1 (+5 вольт) және логикалық 0 (0 вольт) етіп орнатуға болады. Бұл PORTx.y регистріне жазу арқылы орындалады. Әрі қарай енгізу/шығару порттары туралы егжей-тегжейлі сөйлесетін боламыз. Енді біз барлығын скриншотта көрсетілгендей орнатып, Файл->Жасау, Сақтау және Шығу түймешігін басыңыз. Содан кейін CodeWizard бізге жобаны сақтауды ұсынады, біз оны сақтаймыз және кодты қарастырамыз:

#қосу //уақыт кідірістерін жасауға арналған кітапхана void main(void) ( PORTB=0x00; DDRB=0x00; PORTC=0x00; DDRC=0x01; // PC0 pinін шығыс PORTD=0x00; DDRD=0x00; // Таймер/санауыш 0 инициализация TCCR0=0x00; // Таймер/Counter TCCR1L=0x00 ; Үзіліс(тер) инициализациясы TIMSK=0x00 // Аналогтық компаратордың инициализациясы ACSR=0x80 while (1) ( )


Мұнда бәрі сізге қорқынышты және бейтаныс болып көрінуі мүмкін, бірақ іс жүзінде бәрі олай емес. Кодты біз пайдаланбайтын MK перифериялық құрылғыларының инициализациясын жою арқылы жеңілдетуге болады. Жеңілдетілгеннен кейін ол келесідей болады:

#қосу //mega8 микроконтроллерімен жұмыс істеуге арналған кітапхана #include //уақыт кідірістерін құруға арналған кітапхана void main(void) ( DDRC=0x01; /* PC0 пинін шығысқа айналдырыңыз 0x01 жазбасы сізге бейтаныс болып көрінуі мүмкін және бұл он алтылық нысандағы 1 саны ғана, бұл жол баламалы болады екілік жүйеде 0b00000001 дейін, содан кейін мен осылай жазамын.*/ while (1) ( )


Барлығы жақсы. Бірақ жарық диоды жыпылықтау үшін біз PC0 істікшесін логикалық деңгейді өзгертуіміз керек. Ол үшін негізгі циклге бірнеше жолды қосу керек:

#қосу //mega8 микроконтроллерімен жұмыс істеуге арналған кітапхана #include //уақыт кідірістерін құруға арналған кітапхана void main(void) ( DDRC=0x01; /* PC0 пинін шығысқа айналдырыңыз 0x01 жазбасы сізге бейтаныс болып көрінуі мүмкін және бұл он алтылық нысандағы 1 саны ғана, бұл жол баламалы болады екілік жүйеде 0b00000001 дейін, содан кейін мен оны дәл осылай жазамын.*/ while (1) // бағдарламаның негізгі циклі (// PORTC бағдарламасының негізгі циклінің операторлық жақшасын ашады.0=1; / / C 1 портының 0-ін delay_ms(500); // 500 миллисекундтық кешіктіруді жасаңыз. ;//бағдарламаның негізгі циклінің оператор жақшасын жабады)


Міне, код қазір дайын. Бағдарламамызды құрастыру (MK процессорының нұсқауларына аудару) үшін «Барлық жоба файлдарын құру» белгішесін басыңыз. Біздің жобада орналасқан Exe қалтасында он алтылық кеңейтімі бар файл пайда болуы керек, бұл біздің MK үшін микробағдарлама файлы. Микробағдарламаны Proteus жүйесіндегі виртуалды микроконтроллерге беру үшін Proteus ішіндегі микроконтроллердің суретін екі рет басу керек. Осындай терезе пайда болады
Бағдарлама файлы өрісіндегі қалта белгішесін басып, микробағдарламаның он алтылық файлын таңдап, OK түймесін басыңыз. Енді біз схеманың симуляциясын іске қоса аламыз. Ол үшін Proteus терезесінің төменгі сол жақ бұрышындағы «Ойнату» түймесін басыңыз.


Бөлісу