Результаты проведенных в этом направлении работ

Так, с работой ядра на предмет переходов и адресации разобрались. Пора обратить свой взор в другую область — память.

Ее тут два вида (EEPROM не в счет т.к. она вообщет переферия, а о ней потом):

  • RAM — оперативка
  • ROM — ПЗУ, она же flash, она же память программ

Так как архитектура у нас Гарвардская, то у оперативы своя адресация, а у флеша своя. В даташите можно увидеть структуру адресации ОЗУ.

Сразу обратите внимание на адреса! РОН и регистры периферии, а также ОЗУ находятся в одном адресном пространстве. Т.е. адреса с 0000 по 001F занимают наши регистры, дальше вплоть до адреса 005F идут ячейки ввода-вывода — порты. Через порты происходит конфигурирование всего, что есть на борту контроллера. И только потом, с адреса 0060 идет наше ОЗУ, которое мы можем использовать по назначению.

Причем обратите внимание, что у регистров I/O есть еще своя адресация — адресное пространство регистров ввода-вывода (от 00 до 3F), она указана на левой части рисунка. Блок IO/Register Эта адресация работает ТОЛЬКО в командах OUT и IN Из этого вытекает интересная особенность.

К регистрам периферии можно обратиться двумя разными способами:

  • Через команды IN/OUT по короткому адресу в пространстве адресов ввода-вывода
  • Через группу команд LOAD/STORE по полному адресу в пространстве адресов RAM

Пример. Возьмем входной регистр асинхронного приемопередатчика UDR он имеет адрес 0x0C(0х2С) в скобках указан адрес в общем адресном пространстве.

LDI R18,10 ; Загрузили в регистр R18 число 10. Просто так OUT UDR,R18 ; Вывели первым способом, компилятор сам; Подставит вместо UDR значение 0х0С STS 0x2C,R18 ; Вывели вторым способом. Через команду Store ; Указав адрес напрямую.

Оба метода дают идентичные результаты. НО! Те что работают адресацией в пространстве ввода-вывода (OUT/IN) на два байта короче. Это и понятно — им не нужно хранить двубайтный адрес произвольной ячейки памяти, а короткий адрес пространства ввода—вывода влезает и в двухбайтный код команды.

Правда тут возникает еще один прикол. Дело в том, что с каждым годом появляются все новые и новые камни от AVR и мяса в них все больше и больше. А каждой шкварке нужно свои периферийные регистры ввода-вывода. И вот, дожили, в ATMega88 (что пришла на замену Mega8) периферии уже столько, что ее регистры ввода-вывода уже не умещаются в лимит адресного пространства 3F.

Опаньки, приплыли. И вот тут у тех кто пересаживается с старых камней на новые начинаются недоуменные выражения — с чего это команды OUT/IN на одних периферийных регистрах работают, а на других нет?

А все просто — разрядности не хватило.

А ядро то единое, его уже не переделать. И вот тут ATMELовцы поступили хитро — они ввели так называемые memory mapped регистры. Т.е. все те регистры, что не влезли в лимит 3F доступны теперь только одним способом — через Load/Store.

Вот такой прикол. Если открыть какой нибудь m88def.inc то там можно увидеть какие из регистров ввода-вывода «правильные» а какие memory mapped.

Будет там бодяга вот такого вида:

; ***** I/O REGISTER DEFINITIONS ***************************************** ; NOTE: ; Definitions marked "MEMORY MAPPED"are extended I/O ports ; and cannot be used with IN/OUT instructions .equ UDR0 = 0xc6 ; MEMORY MAPPED .equ UBRR0L = 0xc4 ; MEMORY MAPPED .equ UBRR0H = 0xc5 ; MEMORY MAPPED .equ UCSR0C = 0xc2 ; MEMORY MAPPED .equ UCSR0B = 0xc1 ; MEMORY MAPPED .equ UCSR0A = 0xc0 ; MEMORY MAPPED бла бла бла, и еще много такого.equ OSCCAL = 0x66 ; MEMORY MAPPED .equ PRR = 0x64 ; MEMORY MAPPED .equ CLKPR = 0x61 ; MEMORY MAPPED .equ WDTCSR = 0x60 ; MEMORY MAPPED .equ SREG = 0x3f ;<------ А тут пошли обычные.equ SPL = 0x3d .equ SPH = 0x3e .equ SPMCSR = 0x37 .equ MCUCR = 0x35 .equ MCUSR = 0x34 .equ SMCR = 0x33 .equ ACSR = 0x30

Вот такие пироги.

И на этой ниве понимаешь, что в сторону кроссмодельной совместимости ассемблерного кода летит летит большой мохнатый орган с целью наглухо его накрыть. Ведь одно дело подправить всякие макроопределения и дефайны, описывающие регистры, а другое сидеть и, аки Золушка, отделять правильные порты от неправильных.

Впрочем есть решение. Макроязык! Не нравится система команд? Придумай свою с блекджеком и шлюхами!
Сварганим свою собственную команду UOUT типо универсальный OUT

Аналогично и для команды IN Вообще, такими вот макросами можно ОЧЕНЬ сильно разнообразить ассемблер, превратив его в мощнейший язык программирования, рвущий как тузик тряпку всякие там Си с Паскалями.

Ну так о чем я… а о ОЗУ.

Итак, с адресацией разобрались. Адреса памяти, откуда начинаются пользовательские ячейки ОЗУ теперь ты знаешь где смотреть — в даташите, раздел Memory Map. Но там для справки, чтобы знать.

А в нашем коде оперативка начинается с директивы.DSEG Помните наш шаблончик?

Include "m16def.inc" ; Используем ATMega16 ;= Start macro.inc =============================== ; Макросы тут;= End macro.inc ================================= ; RAM ============================================= .DSEG ; Сегмент ОЗУ; FLASH =========================================== .CSEG ; Кодовый сегмент; EEPROM ========================================== .ESEG ; Сегмент EEPROM

Вот после.DSEG можно задавать наши переменные. Причем мы тут имеем просто прорву ячеек — занимай любую. Указал адрес и радуйся. Но зачем же вручную считать адреса? Пусть компилятор тут думает.

Поэтому мы возьмем и зададим меточку

0x0060 ## ;Variables 0x0061 ## 0x0062 ## 0x0063 ## ;Variables2 0x0064 ## 0x0065 ## ;Тут могла бы начинаться Variables4

В качестве ## любой байт. По дефолту FF. Разумеется ни о какой типизации переменных, начальной инициализации, контроля за переполнениями и прочих буржуазных радостей говорить не приходится. Это Спарта! В смысле, ассемблер. Все ручками.
Если провести аналогию с Си, то это как работа с памятью через одни лишь void указатели. Сишники поймут. Поймут и ужаснутся. Т.к. мир этот жесток и коварен. Чуть просчитался с индексом — затер другие данные. И хрен ты эту ошибку поймаешь если она сразу не всплывет.

Так что внимание, внимание и еще раз внимание. Все операции с памятью прогоняем через трассировку и ничего у нас не вылезет и не переполнится.

В сегменте данных работает также директива.ORG Работает точно также — переносит адреса, в данном случае меток, от сих и до конца памяти. Одна лишь тонкость — ORG 0000 даст нам самое начало ОЗУ, а это R0 и прочие регистры. А нулевой километр ОЗУ на примере Мега16 даст ORG 0x0060. А в других контроллерах еще какое-нибудь значение. Каждый раз в даташит лазать лениво, поэтому есть такое макроопределение как SRAM_START указывающее на начало ОЗУ для конкретного МК.

Так что если хотим начало ОЗУ, скажем 100 байт оставить под какой нибудь мусорный буффер, то делаем такой прикол.

1 2 3 4 .DSEG .ORG SRAM_START+100 Variables: .byte 3

DSEG .ORG SRAM_START+100 Variables: .byte 3

Готово, расчистили себе буфферную зону от начала до 100.

Ладно, с адресацией разобрались. Как работать с ячейками памяти? А для этих целей существует две группы команд. LOAD и STORE самая многочисленная группа команд.

Дело в том, что с ячейкой ОЗУ ничего нельзя сделать кроме как загрузить в нее байт из РОН, или выгрузить из нее байт в РОН.

Записывают в ОЗУ команды Store (ST**), а считываю команды Load (LD**).

Чтение идет в регистр R16…R31, а адрес ячейки задается либо непосредственно в команде. Вот простой пример. Есть трехбайтная переменная Variables, ее надо увеличить на 1. Т.е. сделать операцию Variables++

DSEG Variables: .byte 3 Variavles2: .byte 1 .CSEG ; Переменная лежит в памяти, сначала надо ее достать. LDS R16, Variables ; Считать первый байт Variables в R16 LDS R17, Variables+1 ; Считать второй байт Variables в R17 LDS R18, Variables+2 ; Ну и третий байт в R18 ; Теперь прибавим к ней 1, т.к. AVR не умеет складывать с константой, только; вычитать, приходиться извращаться. Впрочем, особых проблем не доставляет. SUBI R16,(-1) ; вообще то SUBI это вычитание, но -(- дает + SBCI R17,(-1) ; А тут перенос учитывается. Но об этом потом. SBCI R18,(-1) ; Математика в ассемблере это отдельная история STS Variables,R16 ; Сохраняем все как было. STS Variables+1,R17 STS Variables+2,R18

А можно применить и другой метод. Косвенную запись через индексный регистр.

DSEG Variables: .byte 3 Variavles2: .byte 1 .CSEG ; Берем адрес нашей переменной LDI YL,low(Variables) LDI YH,High(Variables) ; Переменная лежит в памяти, сначала надо ее достать. LD R16, Y+ ; Считать первый байт Variables в R16 LD R17, Y+ ; Считать второй байт Variables в R17 LD R18, Y+ ; Ну и третий байт в R18 ; Теперь прибавим к ней 1, т.к. AVR не умеет складывать с константой, только; вычитать, приходиться извращаться. Впрочем, особых проблем не доставляет. SUBI R16,(-1) ; вообще то SUBI это вычитание, но -(- дает + SBCI R17,(-1) ; А тут перенос учитывается. Но об этом потом. SBCI R18,(-1) ; Математика в ассемблере это отдельная история ST -Y,R18 ; Сохраняем все как было. ST -Y,R17 ; Но в обратном порядке ST -Y,R16

Тут уже заюзаны операции с постинкрементом и преддекрементом. В первой сначала читаем, потом прибавляем к адресу 1. Во второй вначале вычитаем из адреса 1, а потом сохраняем.

Подобными инкрементальными командами удобно перебирать массивы в памяти или таблицы какие.
А там есть еще и косвенная относительная запись/чтение LDD/STD и еще варианты на все три вида индексов (X,Y,Z). В общем, кури даташит и систему команд.

Стек
О, стек это великая вещь. За что я его люблю, так это за то, что срыв стека превращает работоспособную программу в полную кашу. За то что стековые операции требуют повышенного внимания, за то что если где то стек сорвет и сразу не отследишь, то фиг это потом отловишь… В общем, прелесть, а не штуковина.

Почему люблю? Ну дык, если Си это тупое ремесло, быстро и результативно, то Ассемблер это филигранное искусство. Как маньяки вроде Jim’a из бумаги и только из бумаги клепают шедевры, хотя, казалось бы, купи готовую сборную модель и клей себе в удовольствие. Так и тут — от самого процесса прет нипадецки. В том числе и от затраха с отладкой:))))

Так вот, о стеке. Что это такое? А это область памяти. Работает по принципу стопки. Т.е. какую последнюю положил, ту первой взял.

У стека есть указатель, он показывает на вершину стека. За указатель стека отвечает специальный регистр SP, а точнее это регистровая пара SPL и SPH. Но в микроконтроллерах с малым обьемом ОЗУ, например в Тини2313, есть только SPL

При старте контроллера, обычно, первым делом инициализируют стек, записывая в SP адрес его дна, откуда он будет рости. Обычно это конец ОЗУ, а растет он к началу.

Делается это таким вот образом, в самом начале программы:

1 2 3 4 5 LDI R16,Low(RAMEND) OUT SPL,R16 LDI R16,High(RAMEND) OUT SPH,R16

LDI R16,Low(RAMEND) OUT SPL,R16 LDI R16,High(RAMEND) OUT SPH,R16

Где RAMEND это макроопределение указывающий на конец ОЗУ в текущем МК.

Все, стек готов к работе. Данные кладутся в стек командой PUSH Rn, а достаются через POP Rn.
Rn — это любой из РОН.

Еще со стеком работают команды CALL, RCALL, ICALL, RET, RETI и вызов прерывания, но об этом чуть позже.

Давай-ка поиграемся со стеком, чтобы почувствовать его работу, понять как и куда он движется.

Вбей в студию такой код:

CSEG ; Кодовый сегмент LDI R16,Low(RAMEND) ; Инициализация стека OUT SPL,R16 LDI R16,High(RAMEND) OUT SPH,R16 LDI R17,0 ; Загрузка значений LDI R18,1 LDI R19,2 LDI R20,3 LDI R21,4 LDI R22,5 LDI R23,6 LDI R24,7 LDI R25,8 LDI R26,9 PUSH R17 ; Укладываем значения в стек PUSH R18 PUSH R19 PUSH R20 PUSH R21 PUSH R22 PUSH R23 PUSH R24 PUSH R25 PUSH R26 POP R0 ; Достаем значения из стека POP R1 POP R2 POP R3 POP R4 POP R5 POP R6 POP R7 POP R8 POP R9

А теперь запускай студию в пошаговое выполнение и следи за тем как будет меняться SP. Stack Pointer можно поглядеть в студии там же, где и Program Counter.

Вначале мы инициализируем стек и загрузим регистры данными. В результате получится следующая картина:

Дальше, командой POP, мы достаем данные из стека. Обрати внимание на то, что нам совершенно не важно откуда мы положили данные в стек и куда мы их будем сгружать. Главное порядок укладки! Ложили мы из старших регистров, а достанем в младшие. При этом указатель стека будет увеличиваться.

PUSH R16 PUSH R17 POP R16 POP R17

Например, я уже говорил про ограничение младших РОН — они не дают записать в себя число напрямую. Только через регистры старшей группы. Но это же неудобно!

Проблема решается с помощью макроса. Я назвал его LDIL — LDI low

MACRO LDIL PUSH R17 ; Сохраним значение одного из старших регистров в стек. LDI R17,@1 ; Загрузим в него наше непосредственное значение MOV @0,R17 ; перебросим значение в регистр младшей группы. POP R17 ; восстановим из стека значение старшего регистра. .ENDM

Теперь можно легко применять нашу самодельную команду.

1 LDIL R0,18

Со временем, файл с макросами обрастает такими самодельными командами и работать становится легко и приятно.

Стековые ошибки
Стек растет навстречу данным, а теперь представьте что у нас в памяти есть переменная State и расположена она по адресу, например, 0х0450. В опасной близости от вершины стека. В переменной хранится, например, состояние конечного автомата от которого зависит дальнейшая логика работы программы. Скажем если там 3, то мы идем делать одно, если 4 то другое, если 5 то еще что-то и так до 255 состояний. И по логике работы после 3 должна идти 4ре, но никак не 10

И вот было там 3. И тут, в один ужасный момент, условия так совпали, что стек разросся и его вершина дошла до этой переменной, вписав туда значение, скажем 20, а потом борзо свалила обратно. Оставив гадость — классический пример переполнения стека. И логика программы вся нахрен порушилась из-за этого.

Либо обратный пример — стек продавился до переменных, но в этот момент переменные обновились и перезаписали стековые данные. В результате, со стека снялось что-то не то (обычно кривые адреса возврата) и программе сорвало крышу. Вот такой вариант, кстати, куда более безобидный, т.к. в этом случае косяк видно сразу и он не всплывает ВНЕЗАПНО спустя черт знает сколько времени.

Причем эта ошибка может то возникать, то исчезать. В зависимости от того как работает программа и насколько глубоко она прогружает стек. Впрочем, такое западло чаще встречается когда пишешь на Си, где не видно насколько активно идет работа со стеком. На асме все гораздо прозрачней. И тут такое может возникнуть из-за откровенно кривого алгоритма.

На долю ассемблерщиков часто выпадают другие стековые ошибки. В первую очередь забычивость. Что то положил, а достать забыл. Если дело было в подпрограмме или в прерывании, то искажается адрес возврата (о нем чуть позже), стек срывает и прога мгновенно рушится. Либо невнимательность — сохранял данные в одном порядке, а достал в другом. Опа и содержимое регистров обменялось.

Чтобы избегать таких ошибок нужно, в первую очередь, следить за стеком, а во вторых грамотно планировать размещение переменных в памяти. Держа наиболее критичные участки и переменные (такие как состояния конечных автоматов или флаги логики программы) подальше от стековой вершины, поближе к началу памяти.

У некоторых возникнет мысль, что можно же взять и стек разместить не на самом конце ОЗУ, а где нибудь поближе, оставив за ним карман для критичных данных. На самом деле не слишком удачная мысль. Дело в том, что стек можно продавить как вниз, командой PUSH так и вверх — командами POP. Второе хоть и случается намного реже, т.к. это больше грех кривых рук, чем громоздкого алгоритма, но тоже бывает.
Но главное это то, что стек сам по себе сверхважная структура. На ней держится весь механизм подпрограмм и функций. Так что срыв стека это ЧП в любом случае.

Стековые извраты
Моя любимая тема. =)))) Несмотря на то, что стековый указатель сам вычисляется при командах PUSH и POP, никто не мешает нам выковырять его из SP, да использовать его значения для ручного вычисления адреса данных лежащих в стеке. Либо подправить стековые данные как нам угодно.
Зачем? Ну применений можно много найти, если напрячь мозг и начать думать нестандартно:))))

Плюс через стек, в классическом Си и Паскале на архитектуре х86 передаются параметры и работают локальные переменные. Т.е. перед вызовом функции вначале все переменные пихаются в стек, а потом, после вызова функции, в стек пихаются байты будущих локальных переменных.

После, используя SP как точку отсчета, мы можем обращаться с этими переменными как нам угодно. А при освобождении стека командой POP они аннигилируются, освобождая память.

В AVR все несколько не так (видимо связано с малым обьемом памяти, где в стек особо не насуешься, зато есть прорва РОН, но механизм этот тоже можно попробовать использовать.

Правда это уже напоминает нейрохирургию. Чуть ошибся и пациент труп.

Благодаря стеку и ОЗУ можно обходиться всего двумя-тремя регистрами, не особо испытывая напряг по поводу их нехватки.

Флеш память

Память EEPROM маленькая, всего считанные байты, а иногда нужно сохранить кучу данных, например, послание инопланетянам или таблицу синусов, чтобы не тратить время на ее расчет. Да мало ли что нужно заранее заныкать в памяти. Поэтому данные можно забивать в память программ, в те самые килобайты флеша, что имеет контроллер на борту.

Записать то мы запишем, а как достать? Для этого сначала надо туда что-либо положить.
Поэтому добавляй в конце программы, в пределах сегмента.CSEG метку, например, data и после нее, используя оператор.db, вписывай свои данные.

Оператор DB означает что мы на каждую константу используем по байту. Есть еще операторы задающий двубайтные константы DW (а также DD и DQ).

1 data: .db 12,34,45,23

data: .db 12,34,45,23

Теперь, метка data указывает на адрес первого байта массива, остальные байты находятся смещением, просто добавляя к адресу единичку.

Одна тонкость — дело в том, что адрес метки подставляет компилятор, а он считает его адресом перехода для программного счетчика. А он, если ты помнишь, адресует двубайтные слова — ведь длина команды у нас может быть либо 2 либо 4ре байта.

А данные у нас лежат побайтово и контроллер при обращении к ним адресует их тоже побайтово. Адрес в словах меньше в два раза чем адрес в байтах и это надо учитывать, умножая адрес на два.

Для загрузки данных из памяти программ используется команда из группы Load Program Memory

Например, LPM Rn,Z

Она заносит в регистр Rn число из ячейки на которую указывает регистровая пара Z. Напомню, что Z это два регистра, R30 (ZL) и R31 (ZH). В R30 заносится младший байт адреса, а в R31 старший.

В коде выглядит это так:

LDI ZL,low(data*2) ; заносим младший байт адреса, в регистровую пару Z LDI ZH,high(data*2) ; заносим старший байт адреса, в регистровую пару Z ; умножение на два тут из-за того, что адрес указан в; в двубайтных словах, а нам надо в байтах. ; Поэтому и умножаем на два; После загрузки адреса можно загружать число из памяти LPM R16, Z ; в регистре R16 после этой команды будет число 12, ; взятое из памяти программ. ; где то в конце программы, но в сегменте.CSEG data: .db 12,34,45,23


Что такое программа
Что такое алгоритм

Я, наверное, немного поспешил, назвав статью «Программирование микроконтроллеров AVR — первый шаг» . Скорее, эта статья, как и все последующие, — маленький шажок в мир микроконтроллеров. И таких «шажков» у нас будет много, пока не дойдем до того момента, когда сможем сказать: «Микроконтроллер — последний шаг». Но и это, скорее всего, из области фантастики — нельзя объять необъятное, — мир микроконтроллеров постоянно развивается и совершенствуется. Наша задача — сделать первый шаг, логическим итогом которого должна стать первая, самостоятельно разработанная и собранная конструкция на микроконтроллере. А дальше, -дальше каждый поплывет своей дорогой в совершенствовании полученных на сайте знаний. И тогда, завершающую статью можно будет назвать так: «Программирование микроконтроллеров — последний шажок первого шага» (надо же, как загнул!).
И так, приступаем.

Три условия для желающих освоить микроконтроллер

1. Желание и настойчивость в достижении поставленной цели
Этот пункт, на мой взгляд, — самый главный. Не будет желания, а еще хуже — настойчивого желания, то и не будет результата. Главное не пасовать и не останавливаться, проявите настойчивость — и все получится (и не только в деле освоения микроконтроллеров).
2. Знание устройства микроконтроллера.
Немаловажный фактор. Ведь, согласитесь, не зная как устроен микроконтроллер, что он имеет в своем распоряжении, как это все работает, — мы не сможем использовать все возможности микроконтроллера, выжать из него все, на что он способен.
Возможно и не стоит очень глубоко копаться во «внутренностях» микроконтроллера, но основное, так сказать — азы, мы знать должны (этим мы и будем заниматься на страницах сайта — изучать азы работы с микроконтроллером).
3. Знание команд управления микроконтроллерам.
Микроконтроллер, как собака (такое вот интересное сравнение), будет смотреть на нас умными глазами и вилять своим хвостом, пока не подадим ему команду на выполнение каких-то действий.
В отличие от умной собаки, микроконтроллер понимает намного больше команд — более 130 штук.
Так вот, чтобы микроконтроллер не только вилял хвостом, но и выполнял нужную нам работу, — необходимо знать команды управления им.
Сразу хочу сказать, для начала не надо зубрить все 130 команд, достаточно будет знания и половины (и даже меньше). К тому же, многие команды дублируют друг-друга. Но чем больше команд мы будем знать, тем эффективней мы сможем управлять микроконтроллером и тем красивее и элегантнее будут выходить из-под нашего пера программы.

Итого, если у вас есть настойчивое желание освоить микроконтроллер, тогда продолжаем.

Что такое программа

Какие задачи вы возлагаете на микроконтроллер, и как он будет их выполнять, определяется заложенной в него программой – программой которую для микроконтроллера составляете вы сами.

Программа (в переводе это слово означает – “предписание”) – предварительное описание предстоящих событий или действий.

К примеру, мы хотим, чтобы микроконтроллер помигал светодиодом. Довольно простая задача, но тем не менее, для того, чтобы микроконтроллер выполнил ее, мы, предварительно, должны шаг за шагом описать все действия микроконтроллера — написать программу , которую он должен выполнить для получения нужного нам результата – мигающий светодиод.
Что-то вроде такого:
♦ Зажечь светодиод:
— настроить вывод микроконтроллера,к которому подключен светодиод, для работы на вывод информации
— подать на этот вывод логический уровень, который позволит зажечь светодиод
♦ Подождать некоторое время:
— перейти к подпрограмме формирующей паузу (которую тоже нужно “прописать”)
— по выполнению подпрограммы паузы вернуться в основную программу
♦ Погасить светодиод:
— подать на вывод микроконтроллера логический уровень, гасящий светодиод
и так далее.

С термином Программа неразрывно связан другой термин – Алгоритм .

Что такое алгоритм

Алгоритм – набор инструкций, описывающих порядок действия для достижения нужного результата.

Если в программе мы подробнейшим образом прописываем все действия микроконтроллера, то в алгоритме , — мы определяем порядок действий микроконтроллера, на основе которых мы потом создадим программу. По аналогии с вышеприведенном примером:
♦ Зажечь светодиод
♦ Подождать некоторое время
♦ Погасить светодиод
и так далее.
Таким образом, алгоритм – это предшественник программы . И чем тщательно и продумано будет создан алгоритм, тем проще будет создавать программу.

Язык программирования

К сожалению, если любимой собачке мы можем подавать команды на человеческом языке, то общение с микроконтроллером должно происходить на языке, который понятен ему — языке микроконтроллерных команд.

Команды для микроконтроллера имеют вид набора единичек и нулей, типа:
00110101 011000100
так называемые – коды команд , а коды команд – это язык который понимает микроконтроллер. А для того, чтобы перевести наш язык общения на язык микроконтроллера – в эти самые наборы нулей и единичек, существуют специальные программы.
Эти программы позволяют описать порядок работы для микроконтроллера на более-менее понятном для нас языке, а затем перевести этот порядок на язык понятный микроконтроллеру, в результате чего получается так называемый машинный код – последовательность команд и инструкций (те самые нули и единички) которые только и понимает микроконтроллер. Текст программы, написанный программистом, называется исходным кодом . Перевод программы с языка программирования (исходного кода) на язык микроконтроллера (машинный код) производится трансляторами . Транслятор превращает текст программы в машинные коды, которые потом записываются в память микроконтроллера.
В таких программах порядок работы микроконтроллера описывается специальным языком – языком программирования.

Язык программирования – это способ передачи команд, инструкций, чёткого руководства к действию для микроконтроллера.

Из множества языков программирования можно выделить два типа :
языки программирования низкого уровня
языки программирования высокого уровня
Чем они отличаются. А отличаются они своей близостью к микроконтроллеру.

На заре зарождения микропроцессорной техники, программы писали в машинных кодах, то есть весь алгоритм работы последовательно прописывали в виде нулей и единичек. Вот так, примерно, могла выглядеть программа:
01010010
01000110
10010011
Трудно, даже профессионалу, разобраться в такой комбинаций из двух цифр. Для облегчения своей жизни, программисты стали создавать первые языки программирования . Так вот, чем ближе язык программирования к такому набору нулей и единиц тем больше он “низкого уровня”, а чем дальше от них – тем больше “высокого уровня”.

Самые распространенные языки программирования для микроконтроллеров:
— язык низкого уровня – Ассемблер
— язык высокого уровня – С (Си)
Давайте посмотрим на примере их различия (эти примеры абстрактные).
Допустим нам надо сложить два числа: 25 и 35.
В машинных кодах эта команда может выглядеть так:
00000101 1101001
На языке низкого уровня:
ADD Rd, Rr
На языке высокого уровня:
25+35
Различие языков низкого и высокого уровня видны невооруженным глазом.
Но давайте копнемся в этих примерах поглубже. Пример машинного кода разбирать не будем, так как он идентичен примеру на Ассемблере. По своей сути, Ассемблерные команды это те же машинные коды (команды) которым просто, чтобы не заблудиться в нулях и единицах, присвоены буквенные аббревиатуры. Ассемблерной командой ADD Rd, Rr мы ставим микроконтроллеру задачу сложить два числа, которые находятся (а для этого мы должны их туда предварительно записать) – первое в Rd, второе в Rr, а результат сложения поместить в Rd. Как видите мы ставим очень конкретную задачу микроконтроллеру: где взять, что с этим сделать и куда поместить результат. В этом случае мы работаем напрямую с микроконтроллером.
Команда на языке высокого уровня: 25+35, привычная для нас математическая запись, радующая наш глаз. Но в этом случае мы не работаем напрямую с микроконтроллером, мы просто ставим ему задачу сложить два числа. Результат и последовательность действий в данном случае будет тот-же, что и при выполнении ассемблерной команды: сначала эти два числа будут куда-то записаны, затем сложены а результат куда-то помещен.
И вот тут кроется главное отличие языков высокого уровня и низкого уровня. Если в Ассемблере мы контролируем весь процесс (хотим мы того, или нет): мы знаем где записаны эти два числа, и мы знаем где будет находиться результат, то в языке высокого уровня мы процесс не контролируем. Программа сама решает куда предварительно записать числа и куда поместить результат. В большинстве случаев нам это и не надо знать, ведь для нас главное итог – число 60 на выходе. Как результат, программы на языках высокого уровня более читаемы (спорный вопрос), приятны для глаза (спорный вопрос) и меньше по размеру – ведь нам не приходится “лезть во все дыры” и расписывать каждый шаг микроконтроллера, программа это делает потом за нас, когда компилирует ее – переводит в машинные коды. Но тут есть и минус. Два одинаковых алгоритма написанных на Ассемблере и на Си, после преобразования их в машинные коды будут иметь разный размер: программа написанная на Ассемблере будет на 20-40% короче программы написанной на Си – черт его знает, каким путем идет Си для достижения нужного нам результата. И бывают случаи, когда нет доверия к языку высокого уровня и в программе на Си делают вставки кода, написанные на Ассемблере.

Продвинутые программисты, как правило, знают несколько языков программирования, творчески соединяя их возможности и преимущества в одной программе. Ну а нам, любителям, надо знать хотя бы один язык (для начала), и начинать надо (а я в этом твердо уверен)с языка низкого уровня – Ассемблера.

Компания ЭРЕМЕКС объявляет о релизе Delta Design версии 2.0.

В новой версии произошло значительное увеличение функционала, подробнее о котором можно посмотреть в истории изменений . Ознакомиться с Delta Design версии 2.0 можно на примере триальной версии, размещенной в разделе СКАЧАТЬ .

В современных средах разработки радиоэлектронных устройств должна быть обеспечена совместная работа различных специалистов, работающих как над функционалом устройства, так и над его внешним видом. В новой версии Delta Design расширены возможности интеграции с программами компаний «АСКОН» и «ТЕСИС» - наших партнеров по Консорциуму отечественных разработчиков инженерного программного обеспечения.

  1. Двухсторонний обмен данными с САПР КОМПАС 3D в формате IDF: контур платы (включая вырезы), схема размещения компонентов (модели или габаритные размеры).
  2. Передача в КОМПАС-3D и ЛОЦМАН: PLM перечня элементов и расширенной ведомости покупных изделий в табличном формате.
  3. Передача данных в формате DXF для построения сборочного чертежа , схемырасположения компонентов и других чертежей.
  4. Передача данных для проведения теплового моделирования в среде FlowVision.

Разработчики команды ЭРЕМЕКС стремятся облегчить клиентам миграцию на Delta Design с любых других САПР. Пользователи могут продолжать использовать все свои наработки - и библиотеки электро-радиоэлементов, и проектные данные. В версии 2.0 мы существенно улучшили интеграцию с системой P-CAD. Несмотря на то, что P-CAD не обновляется более десяти лет, эту систему продолжают использовать многие отечественные предприятия.

Результаты проведенных в этом направлении работ

  1. Возможность работать с библиотеками P-CAD непосредственно в Delta Design:
    • доступ к библиотекам P-CAD из Менеджера библиотек Delta Design;
    • просмотр всех библиотечных данных: компонентов, УГО (в том числе несколько УГО для многосекционных компонентов), посадочных мест;
    • использование компонентов в новых проектах без процедуры импорта.
  2. Экспорт нетлистов в форматах:
    • Кeyin netlist (файлы *.kyn );
    • PCAD netlist (файлы *.net );
    • Tango netlist (файлы *.net ).
  3. Возможность объединения в едином проекте Delta Design файлов схемы (*.sch) и платы (*.pcb).
  4. Значительное повышение качества импорта библиотек, схем и плат из P-CAD за счет:
    • массовой замены стилей атрибутов УГО;
    • массового удаления лишних выводов на УГО;
    • выравнивания выводов и проводников по сетке.

В итоге для клиента значительно упрощена миграция с P-CAD на Delta Design. Более того, можно использовать во время переходного периода обе системы одновременно.

Для улучшения интеграции между различными продуктами компании сделаны следующие шаги.

  • Интеграция SPICE-моделей в библиотеку Delta Design.
  • Подготовка схемы для моделирования непосредственно в схемотехническом редакторе.
  • Создана кнопка для вызова программы моделирования.

Упрощена связь с редактором топологии и автотрассировщиком TopoR - теперь передача платы из Delta Design в редактор TopoR осуществляется нажатием кнопки «Открыть в TopoR».

Расширен комплект стандартной поставки. Теперь он включает:

  • демонстрационную библиотеку с наиболее часто применяемыми при проектировании SPICE-моделями (пассивные компоненты, транзисторы, источники питания и т.п.);
  • демонстрационные проекты для SPICE-моделирования.
  • демонстрационный проект печатной платы.

Помимо вышеперечисленного, за прошедший год в системе Delta Design был улучшен интерфейс, доработан мастер создания посадочных мест и др.

Главные изменения системы связаны с редактором печатных плат RightPCB. Год назад данный редактор был выпущен в виде прототипа. В настоящий момент RightPCB - это полноценный редактор печатных плат, который позволяет:

  • разрабатывать конструкции плат любого уровня сложности (с возможностью импорта из механических САПР);
  • осуществлять интерактивную трассировку печатных проводников и дифференциальных пар под углами, кратными 45º;
  • контролировать правила проектирования как в момент трассировки, так и по запросу пользователя;
  • создавать на плате регионы изменения правил проектирования;
  • оперативно просматривать информацию о связях любой пары объектов, размещенных на плате.

Необходимо отметить, что редактор RightPCB полностью интегрирован в сиcтему Delta Design, что позволяет:

  • автоматически синхронизировать разрабатываемые схему и плату;
  • обеспечить параллельную работу с объектами схемы и платы;
  • использовать однотипные инструменты в разных редакторах системы.

В завершение стоит отметить, что компания ЭРЕМЕКС презентует новые программные продукты, позволяющие организовать совместную сетевую работу в системе Delta Design.

Речь идет о расширении Delta Design Workgroup, которое дает возможность работать с одной базой данных нескольким пользователям через локальную сеть предприятия. Это решение уже доступно для приобретения.

Также презентуется новый продукт Delta Design Enterprise Server , интегрирующим несколько баз данных в единое информационное пространство. Выход коммерческой версии продукта запланирован на 2017 год.

В данной версии произошло значительное увеличение функционала, подробнее о котором можно посмотреть в истории изменений. В современных средах разработки радиоэлектронных устройств должна быть обеспечена совместная работа различных специалистов, работающих как над функционалом устройства, так и над его внешним видом. В данной версии Delta Design расширены возможности интеграции с программами компаний «АСКОН » и «ТЕСИС » - партнеров по Консорциуму отечественных разработчиков инженерного программного обеспечения.

  • Двухсторонний обмен данными с САПР КОМПАС 3D в формате IDF: контур платы (включая вырезы), схема размещения компонентов (модели или габаритные размеры).
  • Передача в КОМПАС-3D и ЛОЦМАН: PLM перечня элементов и расширенной ведомости покупных изделий в табличном формате.
  • Передача данных в формате DXF для построения сборочного чертежа, схемырасположения компонентов и других чертежей.
  • Передача данных для проведения теплового моделирования в среде FlowVision.

Пользователи могут продолжать использовать все свои наработки - и библиотеки электро-радиоэлементов, и проектные данные. В версии 2.0 улучшена интеграция с системой P-CAD . Несмотря на то, что P-CAD не обновляется более десяти лет, эту систему продолжают использовать многие отечественные предприятия.

Результаты проведенных в этом направлении работ

  • Возможность работать с библиотеками P-CAD непосредственно в Delta Design:
  • доступ к библиотекам P-CAD из Менеджера библиотек Delta Design;
  • просмотр всех библиотечных данных: компонентов, УГО (в том числе несколько УГО для многосекционных компонентов), посадочных мест;
  • использование компонентов в новых проектах без процедуры импорта.
  • Экспорт нетлистов в форматах:
  • Кeyin netlist (файлы *.kyn);
  • PCAD netlist (файлы *.net);
  • Tango netlist (файлы *.net).
  • Возможность объединения в едином проекте Delta Design файлов схемы (*.sch) и платы (*.pcb).
  • Значительное повышение качества импорта библиотек, схем и плат из P-CAD за счет:
  • массовой замены стилей атрибутов УГО;
  • массового удаления лишних выводов на УГО;
  • выравнивания выводов и проводников по сетке.

В итоге для клиента значительно упрощена миграция с P-CAD на Delta Design. Более того, можно использовать во время переходного периода обе системы одновременно.

Для улучшения интеграции между различными продуктами компании сделаны следующие шаги.

  • Интеграция SPICE-моделей в библиотеку Delta Design.
  • Подготовка схемы для моделирования непосредственно в схемотехническом редакторе.
  • Создана кнопка для вызова программы моделирования.

Упрощена связь с редактором топологии и автотрассировщиком TopoR - теперь передача платы из Delta Design в редактор TopoR осуществляется нажатием кнопки «Открыть в TopoR».

Расширен комплект стандартной поставки. Теперь он включает:

  • демонстрационную библиотеку с наиболее часто применяемыми при проектировании SPICE-моделями (пассивные компоненты, транзисторы, источники питания и т.п.);
  • демонстрационные проекты для SPICE-моделирования.
  • демонстрационный проект печатной платы.

Помимо вышеперечисленного, за прошедший год в системе Delta Design был улучшен интерфейс, доработан мастер создания посадочных мест и др.

Главные изменения системы связаны с редактором печатных плат RightPCB. Год назад данный редактор был выпущен в виде прототипа. В настоящий момент RightPCB - это полноценный редактор печатных плат, который позволяет:

  • разрабатывать конструкции плат любого уровня сложности (с возможностью импорта из механических САПР);
  • осуществлять интерактивную трассировку печатных проводников и дифференциальных пар под углами, кратными 45º;
  • контролировать правила проектирования как в момент трассировки, так и по запросу пользователя;
  • создавать на плате регионы изменения правил проектирования;
  • оперативно просматривать информацию о связях любой пары объектов, размещенных на плате.

Необходимо отметить, что редактор RightPCB полностью интегрирован в сиcтему Delta Design, что позволяет:

  • автоматически синхронизировать разрабатываемые схему и плату;
  • обеспечить параллельную работу с объектами схемы и платы;
  • использовать однотипные инструменты в разных редакторах системы.

В завершение стоит отметить, что компания ЭРЕМЕКС презентует новые программные продукты, позволяющие организовать совместную сетевую работу в системе Delta Design.

Delta Design 1.1

Назначение продукта

  • обеспечить сквозной цикл проектирования печатных плат, позволяя формировать и вести базы данных радиоэлектронных компонентов;
  • разрабатывать принципиальные электрические схемы;
  • моделировать работу аналоговых и цифровых узлов устройств;
  • разрабатывать конструкции печатных плат;
  • размещать компоненты и осуществлять полуавтоматическую и автоматическую трассировку печатных плат;
  • формировать и выпускать конструкторскую и производственную документацию.

Скриншот окна программы (2015)

Delta Design обеспечивает проектирование, посредством которого достигается высокая степень сохранности проектных данных, гарантируется их целостность и однозначность при переходах между различными этапами разработки, унифицированный ввод всей необходимой для проектирования информации.

Менеджер библиотек LIBerty обеспечивает ведение базы данных электронных компонентов для последующего использования в процессе проектирования. Для автоматизированного проектирования электрических схем предусмотрен схемотехнический редактор Flexy S. Пользователю доступна система управления правилами и технологическими ограничениями DRM, она обеспечивает полный контроль над параметрами проекта.

В состав Delta Design входит высокопроизводительный автотрассировщик печатных плат TopoR, который успешно используется не только в России, но и за рубежом.

Система имеет интуитивно понятный интерфейс, созданный на основе методологических наработок и современных программных технологий.

Изначально продукт создан с поддержкой российских ГОСТов, однако совместим с международными стандартами.

Программное обеспечение, представляющее собой симулятор работы цифровой аппаратуры.

Основное назначение программы Delta Design HDL Simulator – симуляция, верификация и валидация программных и аппаратных команд, написанных на языке VHDL. Данное программное обеспечение просто в обращении, удобно для начинающих разработчиков и является одной из частей единой среды под названием Delta Design.

Рабочие проекты состоят из VHDL-файлов, создание и правка которых выполняется во встроенном редакторе. После написания кода запускаются процессы компиляции и моделирования. Порядок следования файлов не имеет значения, а компиляция многопоточна. Важной особенностью программного обеспечения Delta Design HDL Simulator является быстрый ответ при старте симуляции, без длительного ожидания окончания компиляции проекта.

Временные диаграммы сигналов отображаются в окне встроенного виртуального осциллографа в режиме он-лайн, позволяя «на лету» выявлять баги. Все объявленные в проекте сигналы автоматически добавляются в осциллограф. Кроме того осциллограф имеет широкие настройки масштабирования результатов по времени.

В программе предусмотрены возможности хранения, импорта/эспорта, структурирования рабочих проектов, а также результатов симуляций. Стоит отметить наличие системы контроля версий, возможность отладки до окончания процесса симуляции, пользовательскую настройку используемого набора инструментов, панелей и окон, удобную организацию работы с файлами исходного кода.

Программа Delta Design HDL Simulator не является готовым, полностью законченным продуктом. В настоящее время данное ПО находится на стадии бета-тестирования и отладки. В симулятор планируется добавление таких возможностей как: моделирование аналоговых процессов (VHDL-AMS); поддержка высокоуровневых языков программирования, Verilog и SystemVerilog; интеграция с пакетом Delta Design Schematic; совместное проектирование/моделирование HDL с прошивками для микроконтроллерных (встраиваемых) систем.

Программа Delta Design HDL Simulator была написана специалистами отечественной компании Эремекс, расположенной в Москве. Данная организация уже много лет занимается проблемами создания конкурентоспособных программных продуктов в сфере автоматизации процессов разработки плат. К числу известных изделий компании Эремекс относится высокопроизводительный топологический трассировщик , пакет SPICE-моделирования электронных схем и операционная система для микроконтроллерных устройств FX-RTOS.

Бета-версия приложения Delta Design HDL Simulator распространяется совершенно свободно. Процесс установки симулятора протекает в автоматическом режиме, однако в конце потребуется заполнить онлайн-анкету о подтверждении участия в бета-тестировании системы. После этого на указанную почту будет выслан код бета-тестера, необходимый для завершения инсталляции программы. В настоящий момент ПО не имеет пользовательского руководства.

Интерфейс программы Delta Design HDL Simulator представлен на английском языке.

Приложение предназначено для работы в 32- или 64-разрядных операционных системах Microsoft Windows – XP, 2000, Vista, 7 и 8, поддержка Linux не планируется.

Распространение программы: бесплатная.

  • Сергей Савенков

    какой то “куцый” обзор… как будто спешили куда то