Как пишут программы для процессоров

Обновлено: 07.07.2024

Итак, у вас есть процессор. Вы наверняка понимаете, что процессор можно как-то запрограммировать, чтобы он делал то, что вы хотите. Но чтобы сделать какую-то полезную работу, необходимо сперва написать полезную программу и отдать её процессору для исполнения.

В целом, неважно, с каким именно процессором вы имеете дело: это может быть последний Intel Pentium в вашем ноутбуке или микроконтроллер на плате Arduino. Общие принципы написания программы, т. е. программирования, в обоих случаях одни и те же. Различается лишь быстродействие и объём возможностей по работе с другими устройствами.

Что такое программа и куда её писать

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

Байт инструкции Что он означает для процессора
00001001 означает: взять следующий байт и запомнить его в ячейке №1
00000110 …это как раз следующий байт, который мы запоминаем в ячейке №1: число 5
00011001 означает: отнять от значения в ячейке №1 единицу и оставить там обновлённый результат
00101001 означает: сравнить значение в ячейке №1 с нулём, и если оно ноль — перепрыгнуть через столько байт, сколько указано в следующем байте
00000100 …если результат был ноль, мы хотим прыгнуть через 4 байта, к предпоследней инструкции
10000011 означает, что мы хотим вывести на экран символ, код которого записан в следующем байте
01000001 …букве «A» как раз соответствует этот код
00101000 означает, что мы хотим прыгнуть назад на столько байт, сколько указано в следующем байте
00000110 …прыгать будем на 6 байт назад, к инструкции №3
10000011 означает, что мы хотим вывести на экран символ, код которого записан в следующем байте
00100001 …знаку «!» как раз соответствует этот код

В результате исполнения такой последовательности инструкций на экран будет выведена паническая фраза «АААА!».

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

Зачем нужны языки программирования

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

Проблема в том, что такие языки непонятны процессору, и перед тем, как дать ему эту программу на выполнение, её нужно транслировать (translate): перевести с естественного языка на язык процессора (на машинный язык). Трансляция-перевод может осуществляться непосредственно слово за словом (выражение за выражением) — это осуществляют программы-интерпретаторы языков (англ. interpreter — истолкователь). Их действие аналогично синхронному переводу, когда переводчики-синхронисты переводят фразы, выражающие законченный смысл, в темпе их произнесения или поступления. Трансляция-перевод может осуществляться и всего текста (листинга) программы целиком — это осуществляют программы-компиляторы (англ. compiler — составитель, собиратель). Их действие схоже с переводом обычных законченных текстов. У каждого языка, если только он не остался на уровне фантазий, есть свой транслятор-переводчик: либо интерпретатор либо компилятор, или и тот, и другой. Для популярных языков их обычно несколько на выбор, от разных производителей и для разных платформ. Большинство из них свободно доступно в интернете.

Итак, есть программы на вполне понятном человеку языке: их ещё называют «исходным кодом», просто «кодом» или «исходниками». Они пишутся в простые текстовые файлы с помощью любого текстового редактора, хоть с помощью Notepad. Затем они превращаются в понятные процессору наборы нулей и единиц с помощью транслятора (интерпретатора или компилятора), который интерпретирует исходный код и непосредственно выполняет заключённые в нём инструкции, используя ресурсы процессора, а компилятор получает на вход исходный код, а на выходе создаёт бинарный (двоичный) исполняемый файл, тот самый, который понятен процессору и называется исполняемой программой.

Бинарные файлы непригодны для чтения людьми и предназначены, в общем, лишь для исполнения процессором. Они могут иметь разный тип в зависимости от того, для чего получены: .exe — это файл исполняемой программы для операционной системы Windows, .hex — это файл исполняемой программы, приготовленный для загрузки на выполнение микроконтроллером типа Arduino, т. е. для выполнения практически на «чистом железе» (без ОС и прочих системных программ).

Почему же существует столько языков программирования и в чём разница?

Почему? Потому что на Земле много людей и компаний, и многие считали, что могут сделать лучше всех: удобнее, понятнее, быстрее, стройнее. В чём разница: разные языки — это разный баланс скорости написания, понятности при чтении и скорости исполнения.

Посмотрим на одну и ту же программу, которая выводит на экран песенку про 99 бутылок пива на разных языках программирования.

Например, язык Perl. Пишется быстро; понять, что имел в виду программист невозможно; исполняется медленно:

Язык Java. Пишется относительно долго; читается просто; исполняется довольно быстро, но занимает много памяти:

Язык Assembler. Пишется долго; читается сложно; исполняется очень быстро:

На чём программируется Arduino

Если говорить об Arduino или о микроконтроллерах компании Atmel, на каком языке можно писать программы для них? Теоретический ответ: на любом. Но на практике выбор ограничивается языками Assembler, C и C++. Это связанно с тем, что в сравнении с настольным компьютером у них очень ограниченные ресурсы. Килобайты памяти, а не гигабайты. Мегагерцы на процессоре, а не гигагерцы. Это плата за дешевизну и энергоэффективность.

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

Assembler, как вы видели, нельзя назвать самым простым и элегантным и, естественно, как результат, флагманским языком для Arduino является C/C++.

Во многих источниках говорится, что Arduino программируется на особом языке: Processing, Wiring. Это не совсем корректное утверждение. Контроллер программируется на C/C++, а то, что называется этими словами — это просто удобный «обвес», который позволяет решать многие типичные задачи, скрывая частности и детали, да не изобретая велосипед каждый раз.

Почему C и C++ упоминаются в одном предложении? C++ — это надстройка над C. Всякая программа на C является корректной программой для C++, но не наоборот. Вы можете пользоваться и тем, и другим. Чаще всего вы даже не будете задумываться о том, что используете, решая текущую задачу.

Ближе к делу: первая программа

Давайте напишем первую программу для Arduino и заставим плату её исполнять. Вам необходимо создать текстовый файл с исходным кодом, скомпилировать его и подсунуть полученный бинарный файл микроконтроллеру на плате.

Пойдём по порядку. Напишем исходный код. Можно написать его в блокноте или любом другом редакторе. Однако для того, чтобы работа была удобной, существуют так называемые среды разработки (IDE, Integrated Development Environment). Они в виде единого инструмента предоставляют и текстовый редактор с подсветкой и подсказками, и компилятор, запускаемый по кнопке, и много других радостей. Для ардуинок такая среда называется Arduino IDE. Она свободно доступна для скачивания на нашем сайте.

Установите среду и запустите её. В появившемся окне вы увидите, что большая часть места отдана текстовому редактору. В него и пишется код. Код в мире Arduino ещё называют скетчем (англ. sketch — набросок, эскиз). К слову, «скетч» как имя нарицательное пришло в мир искусства программирования из мира искусства и художников.

Итак, давайте напишем скетч (набросаем эскиз), который ничего не делает. То есть минимально возможную правильную программу на C++, которая просто прожигает время.

Не будем пока заострять внимание на значении написанного кода. Скомпилируем его. Для этого в Arduino IDE на панели инструментов есть кнопка «Verify». Нажмите её, и через несколько секунд бинарный файл будет готов. Об этом возвестит надпись «Done compiling» под текстовым редактором.


В результате у нас получился бинарный файл с расширением .hex , который может исполнять микроконтроллер.

Теперь необходимо подсунуть его контроллеру. Этот процесс называется загрузкой, прошивкой или заливкой. Для загрузки полученной программы на устройство в среде Arduino IDE есть кнопка «Upload» на панели инструментов. Соедините вашу плату с компьютером через USB-кабель, нажмите «Upload», и через несколько мгновений программа будет загружена в ардуинку. При этом программа, которая была в контроллере ранее, будет стёрта.

Об успешной прошивке возвестит надпись «Done Uploading».


Если при попытке загрузки вы столкнулись с ошибкой убедитесь, что:

В меню Tools → Board выбран тот порт, к которому действительно подключена Arduino. Можете вынуть и вставить пару-тройку раз USB-кабель, чтобы понять какой порт появляется и исчезает: это и есть ваша плата. Вы установили необходимые драйверы для вашей платы. Это необходимо для Windows, не требуется под Linux и необходимо только для старых плат на MacOS.

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

как работает процессор и языки программирования

Эта статья будет полезна всем, кто по каким-либо причинам не знает, как работает процессор, как и зачем появились языки программирования и принцип их работы.

Все описанное ниже как всегда упрощено для лучшего понимания.

Процессор и оперативная память

процессор управляет всеми устройствами и процессами в компьютере

Начнем вот с чего. Процессор не понимает русский, английский и другие языки. Он понимает числа, которые являются для него простыми командами, например: взять из памяти какие-то данные, добавить какие-то данные, сложить и т.д.

Процессор знает много команд и у каждой из них есть свой числовой код, например:


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


Понимаете прикол? Это значит, что вам нужно писать код для каждой архитектуры процессора. Жуть.

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

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

как работает процессор и оперативная память

Ассемблер

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

Для того, чтобы заставить процессор выполнить какую-то программу, например решить уравнение 2 + 2 * 2, нам нужно написать цепочку простых числовых команд.

процессор выполняет цепочка команд из числовых кодов команд

Согласитесь, что писать такой код очень сложно и легко запутаться. И это мы всего лишь написали код для решения простого уравнения. А теперь представьте, как написать ВКонтактик или Инстаграм.

Для упрощения жизни люди придумали инструмент Ассемблер и язык программирования на ассемблере.

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

Помните примеры кодов команд, которые были указаны выше? Теперь они выглядят так:

Также к названию команд были добавлены операнды (один или более), которые дают дополнительную информацию для выполнения команды.

пример кода на языке assembler

Что-то слишком много непонятного кода для такой пустяковой задачи, не правда ли?

Языки программирования высшего уровня

Помните в самом начале я писал, что каждый производитель процессоров делает свою архитектуру? И что у каждой архитектуры свои числовые коды команд?

Это усложняет портативность. Добавим сюда сложность в написании больших программ и получим необходимость в создании новых инструментов.

Так стали появляться языки программирования высокого уровня.

Компилируемые языки

Первыми появились компилируемые языки программирования. К ним относится С, С++, Java и другие.

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

процессор не понимает код высшего порядка напрямую

Но процессор не поймет этой команды. Как мы помним, он знает и понимает только маленькие числовые команды. Поэтому компилятор языка C преобразует команду в ассемблированный код, а затем в машинный код, понятный процессору.

как работает компилятор

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

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

компилятор языка C собрал исполняемый файл

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

Интерпретируемые языки

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

Вот тут в ход идут интерпретируемые языки программирования такие как: Python, PHP, Perl, Pascal и другие.

Это тоже языки высшего порядка, которые также упрощают написание кода. Но у них есть как минимум два преимущества перед компилируемыми языками:

как работает интерпретатор

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

Подытожим

Я надеюсь, что теперь вы лучше представляете, как работает ваш компьютер или смартфон и будете терпеливее относится к их затупам 🙂 Ведь железка не виновата, что тупит, а виноват горе-программист, который написал плохой код.


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

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

Микроконтроллеры бывают разных фирм, которые делают одно и тоже дело, но разными методами. Сравнить это можно с человеческими расами: европейцы, китайцы и африканцы например. Я лично работаю с микроконтроллерами фирмы Атмел, про них и буду говорить. Ну уж пошло сравнение с расами, пускай это будут европейцы.) Программы для микроконтроллеров пишут на языках программирования. Я рекомендую начать с языка Си. Это древний и простой язык. Для написания текста програмы используют программы компиляторы. Они позволяют создавать, редактировать и переваривать написанный программистом текст программы в код (прошивку), который можно загрузить (прошить) в микроконтроллер. Таких программ есть множество. Пример для Атмел: Code VisionAVR, родная от Атмел AVR Studio, Bascom-avr и ещё.
Эти программы делают одно и тоже дело, но своими методами, особенностями достоинствами и недостатками. При это текст Си в тих программах компиляторах немного отличается, но в общем похож. Можно сравнить с различием украинского, русского и белорусского языка. Я использую Code VisionAVR, что и советую начинающим.

Далее я приведу простой текст программы, написанный на языке Си в компиляторе Code VisionAVR для микроконтроллера ATTiny13A. В конце темы есть проект, прошивка и проект для эмулятора протеуса. Микроконтроллер в этой программе умеет делать простую вещь: при помощи кнопки менять логическое состояние на двух выходах, при этом короткое нажатие меняет состояние первого выхода а длинное — второго. В автомобиле например эту схему можно применить для управления одной кнопкой обогревом заднего стекла (которая есть у многих штатно) и добавленным обогревом зеркал. Нажал коротко на кнопку — сработал обогрев стекла, нажал ещё — обогрев стекла выключился. Если нажать и удерживать кнопку, то через какое-то время включиться обогрев зеркал. Если нажать и удерживать кнопку повторно — обогрев зеркал отключится.

Для понятия текста нужно знать грамматику, правила писанины языка Си, этого материала в интернете предостаточно. Так же желательно ознакомиться хотя бы с материалом, по использованию мастера создания проектов в CodeVisionAVR.

Project :
Version :
Date : 28.01.2012
Author :
Company :
Comments:

Chip type : ATtiny13A
AVR Core Clock frequency: 9,600000 MHz
Memory model : Tiny
External RAM size : 0
Data Stack size : 16
*****************************************************/

unsigned char b, trig;

void main(void)
// Declare your local variables here

PORTB=0x01;
DDRB=0x06;

TCCR0A=0x00;
TCCR0B=0x00;
TCNT0=0x00;
OCR0A=0x00;
OCR0B=0x00;

GIMSK=0x00;
MCUCR=0x00;

ACSR=0x80;
ADCSRB=0x00;
DIDR0=0x00;

А теперь поподробнее.

Project :
Version :
Date : 28.01.2012
Author :
Company :
Comments:

Chip type : ATtiny13A
AVR Core Clock frequency: 9,600000 MHz
Memory model : Tiny
External RAM size : 0
Data Stack size : 16
*****************************************************/

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

Это ссылка на библиотеку. Если какая либо библиотека необходима, то она должна быть здесь указана. У нас есть библиотека самого микроконтроллера tiny13a.h, и библиотека задержек времени.

unsigned char a, b, trig;

Объявление трех переменных. unsigned char . Что это такое можно посмотреть здесь Вообще всё непонятное копируем в буфер и ищем в поисковике.

void main(void)
// Declare your local variables here

void main(void) — это оператор, говорящий что началась основная часть программы на Cи и микроконтроллер будет её с этого места выполнять. Все что начинается с // — это комментарий. Старайтесь чаще ими пользоваться. Вообще конкретный комментарий генерирует сам компилятор, как и во многих других местах. Большинство комментариев я удалил, что уменьшить текст.

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

Микроконтроллер имеет тактовый генератор, который задается в мастере и который потом можно изменить в свойствах проекта если что. У нас эта частота 9.6 мегагерца, как видно в шапке.

При прошивке микроконтроллера эту же частоту нужно указать во фьюзах.
CLKPR=0x80; и CLKPR=0x00; это команды настройки регистра внутреннего делителя этой частоты. Задается оно в мастере в первом окне "CHIP". Если у нас выбран делитель 1, то тактовая частота делиться на 1, то есть остается без изменений. Если указать например делитель 128, то соответственно тактовая частота делиться на это число. 9.6Мгц / 128 = 75кГц. и значения регистра делителя будет выглядеть:
CLKPR=0x80;
CLKPR=0x07;

Особо внимательные заметили, в регистр делителя CLKPR сначала пишется число 0x80 а затем сразу 0x00. Нафига пишется сначала одно значение а потом сразу другое? Если у вас возникают какие либо вопросы по регистрам и не только, приучайтесь сразу читать даташиты. Там все подробные ответы на чистом английском языке. Открываете даташит, вставляете в поисковик текста название регистра (CLKPR ) и ищете его описание, за что какие биты данного регистра отвечают. Конкретно у этого регистра для изменения делителя необходимо записать единичку в седьмой бит, после чего микроконтроллер даст изменить и выбрать необходимый делитель в первых четырех битах этого регистра. После того, как пройдет четыре такта выполнения команд процессора, изменить регистр будет уже нельзя. Нужно снова сначала изменить седьмой бит CLKPR=0x80 а затем указать делитель CLKPR=нужный делитель

PORTB=0x01;
DDRB=0x06;

Команды управления и настройкой портов микроконтроллеров — ножек чипа. Задается тоже в мастере. В этих регистрах задается работа на вход порта PB0 и подключается к нему внутренний Pull-up резистор. Порты PB1 и PB2 настраиваются "на выход" с логическим нулем на выходе в их состоянии.

В колонке DataDitection мы указывает тип порта: вход или выход (in или out)
В колонке PullUp/Output Value указываем подключение подтягивающего резистора pullup если порт настроен на вход (P — подключен, Т — неподключен) Если порт настроен на выход, то можно указать его логическое состояние 0 или 1. У нас нули. Строчки Bit0 — Bit5 это порты микроконтроллера PORTB0 — PORTB5

Если посмотреть сгенерированный компилятором комментарий, то можно увидеть соответствие пинов и их настройку:
// Input/Output Ports initialization
// Port B initialization
// Func5=In Func4=In Func3=In Func2=Out Func1=Out Func0=In
// State5=T State4=T State3=T State2=0 State1=0 State0=P

Если перевести из 16-тиричного в двоичный значение регистров, то можно понять даже без даташита назначение битов в регистре:

PORTB=0x01 PORTB=0b00000001
DDRB=0x06 DDRB=0b00000110

Напоминаю, что при разложении в двоичный код младшие значения справа а старшие слева.
Незначащие нули слева можно не писать:

PORTB=0b1;
DDRB=0b110;

А можно вообще написать в десятичной системе:
PORTB=1;
DDRB=6;

Далее по тексту кода идет:

TCCR0A=0x00;
TCCR0B=0x00;
TCNT0=0x00;
OCR0A=0x00;
OCR0B=0x00;
TCCR0A=0x00;
TCCR0B=0x00;
TCNT0=0x00;
OCR0A=0x00;
OCR0B=0x00;
GIMSK=0x00;
MCUCR=0x00;
TIMSK0=0x00;
ACSR=0x80;
ADCSRB=0x00;
DIDR0=0x00;
ADCSRA=0x00;

Настройка таймера микроконтроллера, прерываний, АЦП, компаратора и всего такого пока сложного. Пока его не используем — рановато. У всех этих регистров стоят в значениях нули, это значит, что они отключены. А особо внимательные заметили, что какой-то регистр ACSR имеет значение =0x80; Лезем в даташит и читаем:

Analog Comparator Control and Status Register – ACSR

Вообще, как правило название всех регистров это сокращение от первых букв или части их полного названия.

Если стоит значение данного регистра 0x80, значит в двоичной системе это число 10000000, значит стоит единичка в 7 бите этого регистра, значит читаем в даташите, что он означает:

• Bit 7 – ACD: Analog Comparator Disable
When this bit is written logic one, the power to the Analog Comparator is switched off.
This bit can be set at any time to turn off the Analog Comparator. This will reduce power
consumption in Active and Idle mode. When changing the ACD bit, the Analog Comparator
Interrupt must be disabled by clearing the ACIE bit in ACSR. Otherwise an interrupt
can occur when the bit is changed.

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

После того, как микроконтроллер настроен запущен и выполнена инициализация необходимых частей и выполнены необходимые первоначальные команды в void main(void) в дело вступает его величество главный цикл. Все что находиться внутри этого главного цикла while (1) и заключено в скобки начала и конца > будет крутиться, команды выполняться по кругу от начал до конца. А у нас в нашем коде будет крутиться алгоритм опроса кнопки, подключенной к порту PB0, от состояния которой (нажата кнопка или нет) будет меняться состояние выходных портов PB1 и PB2

На картинке видна схема собранную в эмуляторе Протеус схему, которая позволяет видеть работу кода программы.

Теперь про сами основные команды, которые находятся внутри цикла. Все команды используют один оператор if Это условие ЕСЛИ.

Если в регистре PINB в бите, отвечающем за порт PB0 микроконтроллера.0 содержится значение равное нулю ==0, то выполняем кучку кода, которая находится далее в границах скобок и >
Короче, если нажата кнопка то выполняется следующий код в границах последующих скобок и >
Далее после кучки кода в скобках видим оператор else и ещё кучку кода за ним в скобках и >

Оператор else переводится не как ещё а как иначе

Оператор if и else всегда работают в паре, сначала идет if затем else. Оператор else можно не использовать совсем, если он не нужен.

В нашей ситуации алгоритм можно описать так:

если (нажата кнопка подключенная к порту PB0)

то выполняем кучку кода;
>
иначе (кнопка не нажата)

выполняем эту кучку кода;
>

Так как это все находится внутри главного цикла, то этот код будет выполняться по кругу, будет постоянно опрашиваться кнопка и будет выполняться нужная кучка кода

Теперь рассмотрим кучку кода, которая выполняется, если кнопка нажата:

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

Если переменное значение trig равняется нулю, то выполняем инкремент переменной b Инкремент — операция увеличения значения, хранящегося в переменной, на 1. То есть при проходе выполнения кода, если процессор натыкается на команду инкремента b++, то процессор прибавляет единичку в число, которое находится в переменной b
Так же здесь применяется упрощенная "орфография" написания условия и команды, без скобок и >:

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

Немного отвлеклись, возвращаемся:

if (trig==0) b++; — если значение переменной равно нулю (а оно у нас равно нулю) то выполняем инкремент переменной b — переменная в была равна нулю, теперь стало единице.

Если переменная b больше ста, то выполняем кучку кода внутри скобок.

Переменная b за каждый круг цикла прибавляется на единичку и в итоге через сто "кругов" главного цикла выполниться условие, которая находится далее внутри скобок и >

Теперь рассмотрим что же там делается, если нажата кнопка, если прошло сто кругов цикла:

if (PINB.2==0)PORTB.2=1;
else PORTB.2=0;
trig=1;
b=0;

Здесь мы видим ещё одно условие (жирная такая матрешка получилась))

if (PINB.2==0)PORTB.2=1;
Если регистр состояния выходного порта PB, а точнее PB2 равен нулю, то меняем его состояние на единичку PORTB.2=1.
else PORTB.2=0;
Иначе пишем в регистр нолик. Или если по-другому: если регистр состояния выходного порта PB2 равен единице, то меняем его на ноль.

Короче если происходит выполнение этих условий и команд, то меняется логическое состояние выхода 2 (PB2) на схеме.

Если полностью описать: если нажата кнопка, если прошло сто кругов главного цикла, то меняем логическое состояние выхода 2 — PORTB.2 в коде он же порт PB2 на схеме.

Как уже стало понятно этот кусок кода отрабатывает длительное нажатие кнопки.
Но этого мало, дальше ещё есть две выполняемые команды присвоения:

trig=1; присвоение единице этой переменной необходимо, что бы описанное выше условие работы инкремента b++ перестало работать
b=0; обнуляем переменную b.

В итоге при длительном нажатии кнопки, условие при котором меняется состояние порта PB2 выполняется единожды, до тех пор, пока кнопка не будет отжата кнопка, ибо инкремент не будет работать и условие if (b>100) больше не сработает, если тупо нажать кнопку и не отпускать совсем.

Теперь вторая часть кучки кода, которая следует за первым условием:
else
if (b>4)
if (PINB.1==0)PORTB.1=1;
else PORTB.1=0;
b=0;
>
b=0;
trig=0;
>

Если кнопка отжата:
Опишем её с конца:

trig=0; присваиваем переменной trig значение ноль. Необходимо, что бы после длительного нажатия, когда наступит последующее отжатие кнопки микроконтроллер снова был готов к нажатиям кнопки ( срабатывало условие инкремента if (trig==0) b++;)

b=0; При не нажатой кнопке значение переменной b равняется нулю.

if (b>4)
if (PINB.1==0)PORTB.1=1;
else PORTB.1=0;
b=0;
>
Подробнее:
if (b>4)
Если значение переменной b больше четырех, то выполняем следующий код:
if (PINB.1==0)PORTB.1=1;
else PORTB.1=0;

Если состояние порта BP1 равно нулю, то делаем единицу, если нет, то ноль.

Это условие и команда отрабатывает кроткое нажатие кнопки. Если нажата кнопка, то начинает работать инкремент b++; значение которого начинает увеличиваться. Если отжать кнопку и при этом значение переменной b будет больше четырех ( но меньше ста — а то сработает длинное нажатие) то состояние выходного порта PB1 (он же выход 1 на схеме, он же PORTB.1 в коде) поменяется, сработает алгоритм короткого нажатия кнопки.

Если значение переменной b при отжатии меньше четырех, то условие не срабатывает и ничего не происходит. необходимо для работы "дребезга контактов" и ложных срабатываний.

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

В оконцовке главного цикла виднеется команда:

Это задержка в главном цикле. То есть, выполняется пошагово команды, затем процессор натыкается на команду delay_ms(10); и начинает её выполнять. В итоге процессор будет 10 миллисекунд ждать и ничего не делать в этой строчке, затем опять приступит к выполнению команд.
Находясь в одном общем цикле, скорость нарастания значения инкремента b++ зависит от времени задержки, указанной в delay_ms.

Как видно из описания, длинное нажатие срабатывает от фронта сигнала нажатия кнопки ( начинает работать инкремент) а короткое нажатие кнопки — по спаду, то есть срабатывает по отжатию кнопки.

Вообще выполняемая здесь последовательность: условие + инкремент достаточно часто используемая команда и в языке Си присутствует отдельный оператор для этого for

К концу 2014 года программистов было уже более 18 миллионов, но это не сделало профессию менее востребованной. Специалистов много, но вакансий для действительно хороших программистов еще больше.

Неудивительно, что профессия программиста так популярна: она позволяет, не вставая из-за стола, совершенствовать продукты и создавать решения, которыми будут пользоваться миллионы людей. Некоторых останавливает то, что разработчиков уже и так много. Но программисты нужны — особенно те, которые умеют наблюдать, проектировать и находить новые решения проблем.

Бесплатный курс Geekbrains «Основы программирования» нужен тем, кто хочет обучиться этой профессии и получить реальный опыт разработки, но не знает, с чего начать. Воспользовавшись материалами курса, мы составили краткий план того, как создать первую программу.


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

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

Для тех, кому нужно найти самый дешевый отель, создали программу Booking. Если нужно написать заметку — Evernote, отредактировать фотографию — Photoshop. Для пользователя программа — это продукт, который должен решить его задачу.

Как это выглядит для компьютера

В обработке программы участвуют три компонента компьютера: процессор (ЦПУ), запоминающее устройство (HDD) и оперативная память (ОЗУ). Процессор обрабатывает и исполняет указанные инструкции, жесткий диск их хранит, а оперативная память служит буфером для процессора: отсюда берутся данные и команды, необходимые процессору для выполнения операций.

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

Постановка задачи

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

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

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

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

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

В курсе «Основы программирования» от Geekbrains используется язык программирования JavaScript. Во-первых, у него широкая область применения: JavaScript используют в веб-разработке, в разработке офисных и серверных приложений. Во-вторых, он универсален. Для работы с JavaScript не нужно устанавливать среду разработки, то есть систему для написания программного обеспечения — все операции проводятся в браузере.

Начать писать на JavaScript довольно просто. Нужно создать файл с расширением HTML (подойдет любой текстовый редактор, даже «Блокнот») и прописать в нем несколько строчек кода.

На Windows лучше всего использовать программу Notepad++. На OS X ее нет, но есть неплохие аналоги, например Sublime Text или TextMate. Чтобы вывести на экран всем знакомую надпись 'Hello, World!', нужно прописать в редакторе следующие строчки:

После этого сохранить файл в формате HTML и открыть. Он откроется в браузере — если все сделано верно, то появится окно с введенным текстом.

Циклы и массивы

Чтобы не повторять одну и ту же команду несколько десятков или сотен раз, используются циклы. Это конструкции, которые автоматически повторяют определенные наборы команд.

В JavaScript существует три основных вида циклов:

  • while — выполняет команды, пока условие их выполнения не станет ложным;
  • do-while — команды выполняются хотя бы один раз, даже если условие их выполнения ложно;
  • for — начальное выражение выполняется один раз, а условия проверяются перед каждой итерацией цикла.

Массив — это набор ячеек для хранения данных одного типа.

Представьте себе супермаркет, при входе в который нужно сдавать сумки. Одна ячейка в камере хранения является переменной, в которую вы положите значение, равное своей сумке. А вот сама камера хранения — набор ячеек — является массивом. Проверим данный пример с точки зрения определения массива. Действительно, набор ячеек упорядочен (у каждой есть свой номер), и в них мы кладем данные одинакового типа (тип «сумка»).

Цитата из методички курса

Пройдя курс по основам программирования, создав свою первую программу и на практике осознав, насколько вам интересно это направление, можно определяться со специализацией. Разработка приложений для Windows, OS X, разработка мобильных платформ, веб-разработка — каждое из этих направлений требует знания разных языков программирования, о которых подробно рассказывается в одном из последних уроков курса. Таким образом, ваш выбор языка и технологии будет осознанным.

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

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

Читайте также: