Практическо програмиране на микроконтролери Atmel AVR на асемблер. (3-то издание)

10.09.2021

Веднъж видях интересно видео в интернет, демонстрираше игра на змия, реализирана на микроконтролер и 8x8 LED матрица, след което намерих още няколко подобни видеоклипа, които ме заинтересуваха. Сред тях имаше и видео, в което играта Tetris беше сглобена на „мощен“ микроконтролер. След като гледах, реших да разработя своя собствена версия на устройството, която комбинира и двете игри, използвайки микроконтролер PIC16F688 и две LED матрици, които показват игралното поле с резолюция 8x16 пиксела.

Схемата на устройството е показана по-долу. Извеждането на информация към матрици H1, H2 в динамичен режим се извършва с помощта на регистри за смяна DD2, DD3, DD4. Изходите на микросхемите DD2, DD3 са свързани към анодите на матриците. Катодите на двете матрици са свързани към колекторите на транзисторите VT1-VT8, управляващите сигнали за които се генерират от микросхемата DD4. Микроконтролерът зарежда данни в регистър DD4, когато се препълни, информацията от пин 9 се прехвърля към входа на регистър DD3, след което по същия начин данните се прехвърлят към регистър DD2. Резисторите R1-R16 ограничават тока през матричните светодиоди. Резисторите R17-R23 задават базовия ток на транзисторите VT1-VT8. Микроконтролерът работи на 8 MHz от вътрешен осцилатор. Честотата на опресняване на изображението е 100Hz.


След подаване на захранване скрийнсейвърът на играта „Змия“ се показва на игралното поле. Числото 1 се показва в горната част на полето, а в долната част има изображение на фрагмент от играта. Когато натиснете бутона SB5 “Старт/Пауза”, отивате в менюто на играта, в горната част на което се показва нивото на играта под формата на числа от 1 до 9. Нивото на играта се задава от SB1 “Нагоре” бутон, с всяко натискане номерът на нивото последователно се увеличава с единица. След числото 9 се показва отново числото 1, което зависи от зададеното ниво на играта, така че за 1-во ниво дължината е 3 точки, за 9-то ниво е 11 точки. В долната част на менюто се показва информация за скоростта на движение на змията. Номер 1 съответства на минимална скорост, а числото 9 е максимално. Стойността на скоростта се задава от бутона SB4 „Надолу“, подобно на настройката на нивото на играта. Светенето на светодиоди около периметъра на полето в менюто означава, че е избран режим на игра с наличие на граници около периметъра на полето. В този режим, когато змията напусне игралното поле, настъпва загуба. Ако в менюто светодиодите около периметъра на полето са изключени, тогава е избран режимът без граници. В този случай при напускане на игралното поле главата на змията се появява от противоположната страна на полето. Използвайте бутоните SB2 “Right” и SB3 “Left”, за да зададете желания режим на игра. Когато за първи път влезете в менюто на играта, стойностите на дължината и скоростта се задават на едно и се избира режимът с граници.

След натискане на бутона “Старт/Пауза” от менюто на играта, на игралното поле се показват змия в основната й позиция и произволна свободна точка. Натискането на някой от бутоните „Нагоре“, „Наляво“, „Надясно“ кара змията да се движи в съответната посока. След като движението започне, бутонът „Надолу“ също става достъпен за управление на змията. При удар в светеща точка дължината на змията се увеличава. След като съберете 14 точки, преминавате към следващото ниво на играта. След 9-то ниво има преход към първо ниво. Ако змията удари собственото си тяло или излезе извън игралното поле в граничен режим, настъпва загуба. След 3 загуби се връщате в менюто на играта, където са посочени текущото ниво и скорост на играта. След като змията започне да се движи, можете да направите пауза и да възобновите играта, като натиснете бутоните „Старт/Пауза“.

За да излезете от менюто на играта, трябва да задържите бутона “Старт/Пауза” за 1 секунда, след което на игралното поле ще се появи началният екран на играта. Превключването между игрите става чрез натискане на някой от бутоните „Нагоре“, „Надолу“, „Наляво“, „Надясно“. В същото време се показва началният екран на съответната игра.

В горната част на скрийнсейвъра на играта Tetris се показва числото 2, в долната част има изображение на фрагмент от играта. Отидете в менюто на играта, като натиснете бутона "Старт/Пауза". Броят точки, отбелязани от играча, се показва в горната част на менюто. За всеки изтрит ред се дават точки. Броячът на точки брои до 99, след което се нулира и започва отново. В началото на всеки нова игра, броячът също се нулира. В долната част на менюто се показва информация за скоростта на движение на фигурите, която се задава съответно с бутоните „Нагоре” и „Надолу”. След натискане на бутона “Старт/Пауза” от менюто, играта започва, в горната част на полето се появяват случайни фигури, които се местят с бутоните “Наляво” и “Надясно” в съответната посока. Бутонът Up завърта формата на 90 градуса по часовниковата стрелка при всяко натискане. Като задържите бутона надолу, можете да ускорите движението на фигурата. Бутонът „Старт/Пауза“ ви позволява да поставите на пауза и да възобновите играта. Играта приключва, когато новата фигура не може да се побере на игралното поле, след което тя отива в менюто, където можете да видите броя точки, които играчът е отбелязал. Излизането от менюто се извършва по същия начин, както в играта „Змия“.

Ако не се натисне бутон в рамките на 4 минути, устройството преминава в режим на ниска мощност, микроконтролерът изключва светодиодните матрици и преминава в режим на заспиване. Устройството се "събужда" след натискане на бутона "Старт" и се връща в предишното си състояние.

Устройството използва резистори – размер 1206 за повърхностен монтаж. Кондензаторите С2, С3 са керамични, размер 1206. LED матрици H1, H2 – TOM-1088BG-B зелен цвят с LED диаметър 3mm и резолюция 8x8 пиксела. Бутоните са стандартни тактилни.

Източникът на захранване е стабилизирано захранване с напрежение 3.7-5V, можете да използвате и галванични клетки или батерии, например 3 батерии 1.5V AA или AAA свързани последователно, аз например използвам 3 батерии AA. Устройството остава работоспособно, когато захранващото напрежение се намали до 3,3 V, докато яркостта на LED матриците намалява.

Добър вечер на всички! Излъчвам от уютен свят, наречен „монтажник“. Веднага ще поясня, че темата се отнася до AVR микроконтролери - и все още не знам дали тази публикация ще бъде полезна за тези, които искат да използват асемблер за всяка друга задача. Факт е, че буквално преди няколко дни започнах да уча асемблер от нулата - трябва да направя едно устройство - и реших да направя всичко в него сам. И така, един прекрасен ден го осъзнах Ученето на асемблер е абсолютно безполезно!Асемблерният език може да се разбира само! Тоест на всички, които искат да програмират на асемблер горещо препоръчвам да се задълбочат в детайли как работи ФИЗИЧЕСКИ микроконтролера и след това да проучат тънкостите на командите.
Така че вероятно ще започна малка поредица от статии, в които ще ви разкажа от самото начало как точноРазбрах някои неща в програмирането на асемблерен език - мисля, че за тези, които изобщо не разбират какво е ASM, ще бъда точно такъв „преводач“ от езика на тези, които са много добри в този въпрос.

Веднага ще кажа, че повече или по-малко влязох в тази тема по инициатива на DIHALT - следователно тези статии ще бъдат вид превод от супер-дупер асемблерен микроконтролер на език, разбираем за повечето хора. Е, надявам се, че гурутата ще ме коригират, докато пиесата напредва, и ако изведнъж обясня нещо неправилно, те ще ме коригират.
И така, първите изводи за асемблера, които направих преди няколко дни, ме шокираха до дъно - седях да чета статии за DI HALT от 23:00 до 5 сутринта - след което си легнах доволен и щастлив, разбрах същността на програмиране на асемблер за микроконтролери.
Как може това да се обясни още по-просто? Мисля, че трябва да започнем от самата същност.
***
Първоначално няма да навлизаме в технически подробности (ще говорим за тях в следващата статия) - просто представете си, че има 3 знака:
1. Микроконтролер -Това е англичанинът Стив, който дойде при руснака. Той знае перфектно английски език, но той изобщо не разбира руски - нито една дума. Само английски. Той загуби спора и обеща да направи всичко, което руснакът поиска от него, без да задава въпроси.
2. Асемблер -Това е преводачът Вася, чиято майка е англичанка, а баща – руснак. Владее перфектно английски и руски.
3. Ние -Това е руснак, при когото е дошъл англичанин. Е, това е, ние сме ние =) В същото време ние знаем руски перфектно и (!!!) малко английски - само малко, с речник.
***
Представете си тази ситуация – англичанин седи на стол във вашата стая. И вие седите на компютъра си и четете тази публикация, когато изведнъж прозорецът ви изведнъж се отвори! Това е лош късмет! Вятърът духа, завесата се е превърнала в платно... Би било хубаво да я затворите! Но е твърде мързеливо да станете от стола, да свалите краката си от системния блок, да ги напъхате в чехли, да оставите чашата си кафе (бира) и да отидете да се биете със стихиите. И тогава изведнъж осъзнавате, че имаме англичанин в стаята, който е загубил залога си и е време да го преследваме! И ти му казваш толкова сладко: „Пич! Моля, затворете прозореца и тогава можете да седнете отново на стола!“ а той седи, гледа те с недоумение и нищо не прави! Можете, разбира се, да ударите зелевата супа - но тогава той пак няма да ви разбере! След това викате вашия приятел преводач Василий - той идва и сяда до англичанина на един стол. И вие казвате - Превод: "Стив, иди и затвори прозореца, а след това се облегни на стола!" Преводачът превежда на английски - англичанинът разбира и отива и затваря прозореца, а след това идва и сяда на един стол.
На този етап просто трябва да разберете ролята на асемблера в тази верига „Ние-асемблер-контролер“
Тоест как всеки ще разбере какво е асемблер? След това прочетете.
***

И така, нека си представим тази ситуация. Казвате на Вася - „Слушай, добре, накратко, това е така - забравих калкулатора вкъщи, раздели 56983 на 2 и кажи на Стив да направи толкова много лицеви опори с юмруци“ и Вася брои на калкулатора и казва на Стив на английски „Направете лицеви опори с юмруци 28491 пъти“ Нарича се "ДИРЕКТИВА"- с други думи, директивата е задача за Вася, резултатът от която е действието на Стив.

Има и друга ситуация - казвате на Вася „Кажете на Стив да направи 28491 лицеви опори“ и Вася просто превежда думите ви на английски. Нарича се ОПЕРАТОР

Просто е - има директива и има оператор. Операторът е вашата директна инструкция на Стив какво да прави - Вася тук само превежда вашата заявка на английски. А Директивата е задача за самия Вася - и Вася първо прави това, което си му казал, а след това, в зависимост от резултата, казва нещо на Стив.

Сега ще измъчваме редовно англичанина! Но първо трябва да опознаем по-добре нашия преводач Вася. Трябва да знаете следното - Вася винаги ви се подчинява безпрекословно - каквото му се каже, това прави. Калкулаторът на Вася няма десетични знаци - ако погледнете примера с лицеви опори, тогава 56983 \ 2 = 28491,5 - но всичко на Вася след десетичната запетая е отрязано - и той вижда само цяло число - и това няма значение дали ще има 28491.000001 или ще има 28491.9999999 - за Вася това е една голяма работа ще бъде 28491 и в двата случая. Нищо не е закръглено. повече важна информацияотносно Вася. Вася е жесток - не го интересува фактът, че Стив прави лицеви опори двадесет и осем хиляди пъти. Казаха му, че Вася превежда. И не само преведе, но и ме принуди да направя това, което поискахте. Така че, ако Стив умре на двадесет и три хиляди петстотин и тринадесета лицева опора, вината ще бъде изцяло ваша.

Всъщност това е всичко за сега. В следващата публикация ще копаем по-дълбоко - засега е достатъчно просто да разберете това. Просто си представете тази ситуация и разберете какво е какво, кой каква роля играе и как директивата се различава от оператора.
И тогава ще се опитаме да наречем всичко с правилното му име и грубо да оценим как асемблерът работи с микроконтролер като възрастен.


Така че, надявам се, че съвестният читател вече е сглобил програмист, експериментална платка, а също така е инсталирал и конфигурирал необходимия софтуер.

Сега, след като написах първата статия от поредицата, разбирам, че малко се развълнувах и направих същата грешка като моите предшественици, поставяйки фразата „за начинаещи“. Би било по-точно да се формулира темата „За начинаещи в програмирането на асемблерен език“, тоест предполагам, че читателят вече има поне повърхностно разбиране за това какво е микроконтролер, в противен случай ще ни отнеме много време само за запознайте се с тази тема. За тези, които изобщо не са запознати с тях, мога да препоръчам една абсолютно прекрасна поредица от статии на С. Рюмик, според мен " AVR микроконтролери", публикуван в сп. Радиолюбител (№ 1-11 за 2005 г.). В този цикъл ATmega8 е избран като базов контролер, но общ. функционални единициГорният контролер и ATtiny13 са практически еднакви.

За да се запознаете директно с микроконтролера ATtiny13, препоръчвам книгата на A.V. Евстифеев "Микроконтролери AVR от малкото семейство. Ръководство за потребителя" (М .: Издателство "Додека-XXI", 2007. - 432 стр.). Той съдържа преведени и систематизирани таблици с данни за цялата гама контролери от малкото семейство и, по мое мнение, трябва да бъде настолен справочник за тези, които се занимават с програмиране на микроконтролери.

Въпреки това, докато историята напредва, ще дам малко информация относно онези възли и модули на контролера, които ще бъдат използвани в написаните програми.

Но всичко това е лирично отклонение. Да се ​​върнем директно към историята.

Контролерът ATtiny13, въпреки малкия си размер, има много добри функционални характеристики. И малкият брой щифтове е повече от компенсиран от броя на функциите, които всеки от тях изпълнява. Разпределението и описанието на щифтовете са представени по-долу:

Таблицата е взета от гореспоменатата книга на A.V. Евстифеева.

Както можете да видите, всеки щифт може да изпълнява поне три функции или дори много повече. Първоначално няма да разглеждаме алтернативни функции, а само основната - цифров вход/изход.

Както може да се види от фигурата и таблицата, всички щифтове, с изключение на захранващите щифтове, имат името PB, последвано от сериен номер. какво значи това Всички щифтове на контролера са комбинирани в 8 части за лесна работа с тях и на всяка група от 8 щифта са разпределени три специални I/O регистъра. Като цяло концепцията за регистрите е ключова при работа с контролери, особено в асемблера. Нека разгледаме по-подробно всеки от трите гореспоменати регистъра. Всички те са еднобайтови клетки в паметта на контролера. Всеки бит съответства на един от изходите на контролера, а номерът на бита в регистъра съвпада с номера на изхода (например 0-тият бит отговаря за изхода PB0, 1-вият бит отговаря за изхода PB1 и т.н.). Всички регистри имат собствено име, с което се осъществява достъп при писане на програми. Що за имена са това?

1. Регистърът DDRB отговаря за посоката на предаване на информация на всеки щифт на контролера. Ако някой бит от този регистър е "0", тогава съответният изход ще бъде вход, а ако е "1", тогава изходът. Освен това всеки изход се конфигурира индивидуално и навсякъде в програмата. Това означава, че при различни условия или по различно време един и същ щифт може да бъде конфигуриран като вход или като изход, независимо от другите щифтове.

2. Регистърът PINB съдържа текущото състояние на всички изводи: ако към извода е приложено напрежение, тогава в съответния бит се записва логическа „1“, ако няма напрежение, се записва логическа „0“. Този регистър се използва главно за четене на състоянието на щифт, който е в режим на въвеждане.

3. Регистърът PORTB изпълнява двойна функция в зависимост от посоката на предаване на информацията. Ако щифтът работи като цифров изход, тогава записът на „1“ към който и да е бит от регистъра PORTB предизвиква появата на напрежение на съответния щифт, а записът на „0“ води до изчезване на напрежението. По този начин, в режим на изход, този регистър е този, който определя състоянието на всеки щифт. В режим на цифров вход, записването на логическа "1" на който и да е бит кара вградения изтеглящ резистор да бъде свързан към съответния щифт и записването на "0", за да го деактивира. Що за нещо е този "издърпващ резистор" и за какво е предназначен? Ако щифтът действа като цифров вход, тогава съпротивлението на входния буфер е доста високо и входният ток е доста малък. Следователно всяка електрическа намеса може да доведе до спонтанно превключване на изхода в произволно състояние. За да се предотврати това, между входа и източника на захранване е свързан резистор със съпротивление от няколко десетки килоома, който „издърпва“ входния потенциал до захранващото напрежение (оттук и името). Токът, протичащ през този резистор, е достатъчно малък, за да не пречи на останалата част от веригата, но достатъчно голям, за да предотврати случайно превключване на щифтовете. Често ще използваме издърпващи резистори, когато работим с бутони, защото когато не са натиснати, щифтовете, към които са свързани, по същество "висят" във въздуха и са обект на смущения.

Трябва да се спомене, че при включване всички регистри се нулират на 0 и всеки щифт действа като цифров вход без издърпващ резистор.

Сега, когато имаме поне някаква представа КАКВО е необходимо за работа с контролерни входове, време е да научим КАК да работим с тях.

Нека напишем нашия първи работна програмав асемблер. Първо ще дам пълен алгоритъмсъздаване на нов проект, в бъдеще ще го пропусна, като се съсредоточавам само върху текста на самата програма.

1. Отидете в папката asm и създайте нова папка в нея. Преименувайте го на удобно за нас име. За да бъда конкретен, ще ги наричам с нашия номер на стъпка. В този случай "стъпка 2".

2. Щракнете с десния бутон върху файла build.bat и променете пътя до изходния файл, сочейки към новосъздадената папка (стъпка 2). След това съдържанието ми изглежда така:

"F:\Prog\AVR\asm\avrasm32 -fI %F:\Prog\AVR\asm\step2\main.asm
пауза"

Може да се различава за вас в зависимост от това къде сте разопаковали архива.

3. Отидете в папката Asmedit и стартирайте програмата ASM_Ed.exe

4. В прозореца, който се отваря, напишете текста на програмата. Ще се спра на тази точка по-подробно, тъй като тя е основната в нашия урок днес, както и в следващите.

Какъв е текстът на асемблерна програма? Може да включва няколко елемента, написани съгласно определени правила:

Инструкции за асемблиране със или без операнди в зависимост от синтаксиса на инструкцията. Между името на командата и първия операнд трябва да има интервал, табулация или произволен брой от двете. Операндите са разделени със запетая, която също може да бъде предшествана или последвана от произволен брой интервали или раздели;

Директиви, всяка от които започва с ".";

Етикети, които са места в програмата, произволно наименувани от потребителя, до които може да се наложи навигация. Всеки етикет завършва със знак ":";

Коментари, започващи с ";". Целият текст от началото на коментара до края на реда се игнорира при създаването на шестнадесетичния файл и може да бъде напълно произволен;

Празни редове за по-добра структура и четливост на програмата.

Не може да има повече от една команда на всеки ред. Допуска се обаче едновременното присъствие на етикет в ред, последван от команда и коментар.

Използвайки тези правила, ще напишем програма, която ще включва LED2, докато бутонът SB1 е натиснат, и ще го изключва, ако бутонът бъде освободен. Текстът на програмата е представен по-долу:

.include "F:\Prog\AVR\asm\Appnotes\tn13def.inc"
sbi DDRB, 4 ;РВ4 - изход (LED2)
sbi PORTB, 2 ; Включете издърпващия резистор на PB2 (бутон SB1)
sbic PINB, 2 ; Ако PB2=0 (натиснат бутон), пропуснете следващия. линия
sbi PORTB, 4 ; Инсталиране на PB4 в 1 (изключване на светодиода)
sbis PINB, 2 ; Ако PB2=1 (бутонът е освободен), пропуснете следващия. линия
cbi PORTB, 4; Настройване на PB4 на 0 (LED включен)

Нека го разгледаме по-подробно. Първият ред съдържа директивата "include", написана според горните правила с точка в началото. Целта му е да включи посочения зад него файл в текста на програмата. Както казах в първата стъпка, имаме нужда от файла "tn13def.inc". В този ред ще трябва да промените пътя до местоположението на папката Appnotes на вашия компютър. Защо трябва да включим този файл? Любознателният читател може да го разгледа и да прочете съдържанието му, но най-вероятно в началото ще разбере малко от него. Засега ще кажа, че съдържа съответствие между имената на регистри, които асемблерът не знае по подразбиране, с физическите им адреси в контролера.

Следващите редове са команди на асемблер. Внимателният читател ще забележи, че се използват общо четири различни команди. Нека да разгледаме целта на всеки.

Инструкцията sbi има два операнда: първият е името на регистъра, вторият е номерът на бита. В резултат на неговото изпълнение зададеният бит в посочения регистър се установява на "1".

Командата cbi е подобна по синтаксис на горната и изпълнява точно обратната функция - нулира посочения бит в посочения регистър на "0".

Командата sbis също е подобна по синтаксис на горната. Но за разлика от тях, той не извършва никакви операции с регистрите, а само проверява състоянието на зададения бит в посочения регистър и ако е равен на "1", пропуска реда след командата. В противен случай се изпълнява редът след него, както и всички останали след него.

Командата sbiс е противоположна на командата sbis. Той пропуска следващия ред, ако зададеният регистърен бит е "0".

Сега, обобщавайки всичко по-горе, нека се опитаме да разберем алгоритъма на програмата. Като начало ще направя това буквално ред по ред.

1 ред. Директивата за включване включва файла tn13def.inc, който съдържа дефиниции на регистри.

2-ри ред. Командата sbi задава "1" в бит 4 на регистъра DDRB, като по този начин превключва щифта PB4 към изхода. Ако погледнете диаграмата на платката (фиг. 1 от предишната стъпка), можете да видите, че LED2 е свързан към този щифт. След командата и знака ";" е написан коментар, който накратко обяснява смисъла на действията, извършени в реда.

3 линия. Същата команда sbi задава "1" в бит 2 на регистъра PORTB, свързвайки вътрешния издърпващ резистор към щифта PB2, към който е свързан бутонът SB1. Тъй като не променихме състоянието на бит 2 от регистъра DDRB, този щифт ще остане вход, което е точно това, от което се нуждаем.

4 ред. Командата sbic проверява за наличието на логическа "0" на входа PB2, използвайки PINB регистъра. Ако погледнете внимателно диаграмата, можете да видите, че бутоните, когато са натиснати, затварят съответния терминал с общия проводник. Това е стандартна техника, тъй като когато бутонът бъде освободен, на изхода се появява логическа „1“ поради изтеглящия резистор, а при натискане на бутона се появява логическа „0“ поради връзката на изход към общ проводник. Така че, ако има логическа „0“ на пин PB2, тоест бутонът е натиснат, прескачаме следващия ред и ако бутонът е освободен, тогава го изпълняваме.

5 ред. В него командата sbi задава логическа "1" в бит 4 на регистъра PORTB, като по този начин изключва LED2. Един проницателен читател може да се чуди защо светодиодът се изключва, ако подадем напрежение към изхода. Отговорът се крие в дизайна. Светодиодът е свързан с анода към захранващия проводник, а катода към изхода на контролера. Следователно, ако подадете напрежение към изхода, потенциалите на анода и катода ще бъдат равни и светодиодът ще изгасне. Ако на изхода се изведе логическа „0“, тогава към светодиода ще бъде приложено напрежение и той ще светне. По този начин двойка линии 4 и 5 изключва LED2, когато бутонът бъде освободен.

6 ред. Значението е противоположно на 4-то. Командата sbis проверява за наличието на логическа „1” на входа PB2, тоест проверява дали бутонът е отпуснат. Ако бутонът бъде освободен, следващият ред се пропуска и следващият ред преминава към следващия. Но тъй като 7-ми ред е последният, има преход към 2-ри ред. При натискане на бутона се изпълнява ред 7.

7 ред. Срещу 5-ти. Командата cbi нулира бит 4 от регистъра PORTB на "0", като по този начин включва LED2. Така двойка линии 6 и 7 включва LED2 при натискане на бутона SB1.

Както можете да видите, не направихме нищо особено трудно. Използвайки познания само за 3 регистъра и 4 инструкции, написахме първата си програма. Какво да правя с нея по-нататък? Ако все още не сте забравили, ние продължаваме да пишем алгоритъма за създаване на програма.

5. След като напишете текста на програмата в прозореца на редактора, изберете елемента от менюто „Файл“ и в списъка, който се отваря, щракнете върху „Запазване като...“. В прозореца за запазване на файлове изберете папката step2, която създадохме, и посочете името на файла „main“, тъй като това е името, което посочихме във файла „build.bat“

След запазване прозорецът на програмата трябва да изглежда така:

6. Създайте шестнадесетичен файл. За да направите това, щракнете върху бутона "II" на лентата с инструменти. Трябва да се появи следният прозорец:

Той ни уведомява, че асемблирането е завършено без грешки и файлът на фърмуера „main.hex“ е създаден с обем от 6 думи, тоест 12 байта. Отбелязвам, че подобна програма на C би имала поне 5 пъти по-голям обем.

7. Отивайки в папката step2, намираме допълнение към нея под формата на новосъздадения main.hex файл, който вече може да бъде зашит в контролера с всеки програмист, което трябва да се направи, за да видите резултатите от програмата, която написахме. След флашване на контролера, ако схемата е сглобена правилно, всичко трябва да работи според алгоритъма, който разработихме: когато бутоните са освободени, LED2 трябва да е изключен, а докато бутонът SB1 е натиснат, той трябва да свети.

Преди следващата стъпка ви предлагам да изпълните следните задачи:

1. Добавете към програмата обработка на натискане на бутон SB2 с обратен алгоритъм: при отпускане на бутона SB2 LED1 трябва да свети, а при натискане да не свети.

2. Напишете програма за управление на LED2 с помощта на двата бутона. При натискане на бутона SB1 светодиодът трябва да светне и да свети до натискане на бутона SB2, което го изключва до следващото натискане на SB1.

Клонинг на известния Tetris, написан на асемблер. Той се вписва изцяло в 512-байтовия зареждащ сектор (изисква само 446 байта пространство, което е точно максималния размер на зареждащото устройство в MBR).

MBR е раздел, съдържащ кода и данните, необходими за последващото зареждане на операционната система и разположен в първите физически сектори. Първите 446 байта от диска се предават на кода на буутлоудъра. Именно на това място е написан TetrOS.

Естествено, поради такива свойства, той се зарежда преди всички операционна система- не изисква никаква ОС, работи самостоятелно. Да, да, чухте правилно, TetrOS е собствен буутлоудър.

Ето как изглежда на екрана:

И изходният код на сектора за зареждане изглежда така:

И да, така е всичкиизточник. Помните ли, че тежи само 446 байта?

Можете да стартирате тази „чудодейна операционна система“ под qemu или дори действително да я инсталирате на дяла за зареждане на диск или флаш устройство.

Стартирайте

Просто инсталирайте qemu:

sudo apt-get инсталирайте qemu

и стартирайте:

Зареждане на USB флашка

Копирайте изображението на флашка. Да речем, че ако флаш устройството е монтирано като /dev/sde, ще трябва да изпълните следната команда, за да запишете в неговия сектор за зареждане на TetrOS:

sudo dd if=tetros.img of=/dev/sde

Описание на играта

Разработчикът успя да натъпче не толкова скучен дизайн в само 512 байта памет. Всяка тухла в играта има свой собствен цвят, управлява се с бутони, при поражение играта приключва, тухлите се генерират на случаен принцип... BolgenOS дори не е близо!

За съжаление, поради размера, някои функции трябваше да бъдат изоставени. Играта няма точкуване, рестартирайте играта без рестартиране или покажете коя ще бъде следващата тухла.