Как программируют чипы. Программирование микроконтроллеров для начинающих

Эту статью (а точнее цикл статей…) я решил полностью посвятить микроконтроллерам фирмы Atmel. Конечно, тема эта избитая… НО! На собственном опыте знаю, что познать истину среди этого, извините, БАРДАКА, очень и очень сложно! Поэтому решил попытаться внести хотя бы какую-нибудь ясность в головы жаждущих познать этого страшного зверя, зовущегося «Микроконтроллер».

Итак, цель этой статьи в том, чтобы описать и по возможности показать весь процесс создания устройства на основе микроконтроллера с «нуля». То есть, от задумки (например, решили мы собрать новогоднюю мигалку, подобную описанной уважаемым alx32 в статье …) до воплощения в железе. Разумеется, минуя все промежуточные стадии: постановка задачи, выбор МК, подбор обвязки, формулировка алгоритма, написание программы, отладка, создание платы и, самое долгожданное – запуск!!!

Обновлено: добавлены файлы. Итак, задача : нам нужно создать устройство, способное зажигать в определенном порядке (пусть будет по очереди) , N-ное количество светодиодов (пускай будет 8 штук).
(это для начала……..)


Теперь можно браться за программирование. Писать можно на чем угодно, но начинающим советую отдать предпочтение языку C , т.к. программировать проще и нагляднее. Лично я пользуюсь компилятором CodeVision AVR (он есть в файловом архиве), дальнейшие листинги программ будут приводиться именно для этого компилятора.

Определимся с алгоритмом . Нам нужно по очереди через определенный промежуток времени активировать один из выходов МК.

Включать/выключать можно разными способами :
- присваивать значения каждому выводу отдельно;
- записывать значения сразу всех выводов.

Значения (последовательность) можно получить :
- набрав все команды вручную;
- из массива;
- математическим методом.

Временной интервал можно задать :
- функциями delay (задержка);
- через таймер.

Поэкспериментируем со всеми этими способами. Но сначала нужна заготовка…

Чтобы создать заготовку программы воспользуемся генератором кода, встроенным в CVAVR . Для этого запускаем программу, нажимаем File -> New , в открывшемся окне выбираем “Project” и жмем OK . На вопрос «Воспользоваться генератором кода?» отвечаем “Yes”.
Появилось окно генератора кода. В нем выбираем тип МК и его тактовую частоту, остальное оставляем как есть:


Далее переходим на вкладку “Ports” и там в “PortB” и выставляем следующее:


Так мы определили все выводы порта B как выходы, а нолики означают, что при включении питания на них будет устанавливаться логический "0 ".
Остальные функции нам пока не нужны.

Жмем “File -> Generate, Save and Exit” , выбираем куда сохранить файлы проекта и видим окно с созданным генератором кодом.

Теперь давайте введем в программу наш код .
Простейший вариант реализации (хотя и самы не красивый с точки зрения программирования) – записываем значения каждого вывода, а задержки делаем через функцию delay .

delay_ms(x ); - задержка на x миллисекунд

delay_us(x ); - задержка на x микросекунд

PORTB - порт, с которым мы работаем.

PORTB.x - обращение к выводу x порта B

Находим в конце текста такие строки


Это бесконечный цикл (т.е.выполняется всё время, пока включено питание) нашей программы. Всё, что перед ним – команды предварительной настройки микроконтроллера. Строки, начинающиеся с “//” – комментарии, их тоже полезно иногда читать.

Исключён фрагмент. Наш журнал существует на пожертвования читателей. Полный вариант этой статьи доступен только


Жмем кнопочку Make the project

(в панели инструментов).

Матерится?
И правильно! Компилятор не знает функции delay_ms() , поэтому надо указать ему файл, в котором эта функция описана.
Для этого в самом начале текста программы нужно вставить строку #include (тут точка_с_запятой не нужна! )
Примерно вот так:

Снова жмем волшебную кнопочку.
Проект создан .
Теперь в папке, в которую мы сохранили сам проект, появился файл название_проекта .hex – это и есть прошивка микроконтроллера!

Но подождите, не торопитесь хвататься за паяльник… Мы ведь учимся программировать, а не паять!

Именно поэтому предлагаю проверить нашу программу в виртуальном режиме, а именно – в таком замечательном и любимом мною продукте от Labcenter Electronics - Proteus VSM Там можно моделировать абсолютно любые схемы (даже примитивы Лапласа есть!). Взять ее можно в прикрепленном архиве, вместе с файлами проекта. Правда версия не совсем крякнутая, поэтому не работает сохранение. Что с этим делать расскажу в отдельной статье.

Итак, запускаем ISIS (среда разработки принципиальных схем). В этом окне нажимам кнопочку “P”.

В строке “Keywords” вводим “attiny2313” и справа получаем:


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


Это значит, что элемент добавлен.

Теперь введите в поле “Keywords” слова “LED-RED” и “RES” . Добавьте резистор и светодиод в проект и закройте окно выбора элементов.

Пробуем собрать схему (вывод RESET обязательно подключите к +5V, иначе ничего не заработает! и в жизни это тоже желательно!)

Вот небольшая подсказка :

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

Собрали? Надеюсь, не покалечили при этом себя, близких и окружающие предметы.

Простите за издевательство, просто если разберешься сам – уже не забудешь, так что, постигайте, программа очень мощная и она стоит того, чтобы ее освоить! :laughing:

Когда схема собрана, можно прошить наш виртуальный МК. Для этого щелкаем по нему дважды и видим окно.

Здравствуйте, уважаемые Хабражители!

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

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

1. Программатор
На рынке предлагается много вариантов - от самых дешевых ISP (In-System Programming) программаторов за несколько долларов, до мощных программаторов-отладчиков за пару сотен. Не имея большого опыта в этом деле, для начала я решил попробовать один из самых простых и дешевых - USBasp. Купил в свое время на eBay за $12, сейчас можно найти даже за $3-4. На самом деле это китайская версия программатора от Thomas Fischl . Что могу сказать про него? Только одно - он работает. К тому же поддерживает достаточно много AVR контроллеров серий ATmega и ATtiny. Под Linux не требует драйвера.

Для прошивки надо соединить выходы программатора VCC, GND, RESET, SCK, MOSI, MISO с соответствующими выходами микроконтроллера. Для простоты я собрал вспомогательную схему прямо на макетной плате:

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

2. Микроконтроллер
С выбором микроконтроллера я особо не заморачивался и взял ATmega8 от Atmel - 23 пина ввода/вывода, два 8-битных таймера, один 16-битный, частота - до 16 Мгц, маленькое потребление (1-3.6 мА), дешевый ($2). В общем, для начала - более чем достаточно.

Под Linux для компиляции и загрузки прошивки на контроллер отлично работает связка avr-gcc + avrdude. Установка тривиальная. Следуя инструкции , можно за несколько минут установить все необходимое ПО. Единственный ньюанс, на который следует обратить внимание - avrdude (ПО для записи на контроллер) может потребовать права супер-пользователя для доступа к программатору. Выход - запустить через sudo (не очень хорошая идея), либо прописать специальные udev права. Синтаксис может отличаться в разных версиях ОС, но в моем случае (Linux Mint 15) сработало добавление следующего правила в файл /etc/udev/rules.d/41-atmega.rules:

# USBasp programmer SUBSYSTEM=="usb", ATTR{idVendor}=="16c0", ATTR{idProduct}=="05dc", GROUP="plugdev", MODE="0666"

После этого, естественно, необходим перезапуск сервиса
service udev restart
Компилировать и прошивать без проблем можно прямо из командной строки (кто бы сомневался), но если проектов много, то удобнее поставить плагин и делать все прямо из среды Eclipse.

Под Windows придется поставить драйвер. В остальном проблем нет. Ради научного интереса попробовал связку AVR Studio + eXtreme Burner в Windows. Опять-таки, все работает на ура.

Начинаем программировать

Программировать AVR контроллеры можно как на ассемблере (AVR assembler), так и на Си. Тут, думаю, каждый должен сделать свой выбор сам в зависимости от конкретной задачи и своих предпочтений. Лично я в первую очередь начал ковырять ассемблер. При программировании на ассемблере архитектура устройства становится понятнее и появляется ощущение, что копаешься непосредственно во внутренностях контроллера. К тому же полагаю, что в особенно критических по размеру и производительности программах знание ассемблера может очень пригодиться. После ознакомления с AVR ассемблером я переполз на Си.

После знакомства с архитектурой и основными принципами, решил собрать что-то полезное и интересное. Тут мне помогла дочурка, она занимается шахматами и в один прекрасный вечер заявила, что хочет иметь часы-таймер для партий на время. БАЦ! Вот она - идея первого проекта! Можно было конечно заказать их на том же eBay, но захотелось сделать свои собственные часы, с блэк… эээ… с индикаторами и кнопочками. Сказано - сделано!

В качестве дисплея решено было использовать два 7-сегментных диодных индикатора. Для управления достаточно было 5 кнопок - “Игрок 1” , “Игрок 2” , “Сброс” , “Настройка” и “Пауза” . Ну и не забываем про звуковую индикацию окончания игры. Вроде все. На рисунке ниже представлена общая схема подключения микроконтроллера к индикаторам и кнопкам. Она понадобится нам при разборе исходного кода программы:

Разбор полета

Начнем, как и положено, с точки входа программы - функции main . На самом деле ничего примечательного в ней нет - настройка портов, инициализация данных и бесконечный цикл обработки нажатий кнопок. Ну и вызов sei() - разрешение обработки прерываний, о них немного позже.

Int main(void) { init_io(); init_data(); sound_off(); sei(); while(1) { handle_buttons(); } return 0; }
Рассмотрим каждую функцию в отдельности.

Void init_io() { // set output DDRB = 0xFF; DDRD = 0xFF; // set input DDRC = 0b11100000; // pull-up resistors PORTC |= 0b00011111; // timer interrupts TIMSK = (1<

Настройка портов ввода/вывода происходит очень просто - в регистр DDRx (где x - буква, обозначающая порт) записивается число, каждый бит которого означает, будет ли соответствующий пин устройством ввода (соответствует 0) либо вывода (соответствует 1). Таким образом, заслав в DDRB и DDRD число 0xFF, мы сделали B и D портами вывода. Соответственно, команда DDRC = 0b11100000; превращает первые 5 пинов порта C во входные пины, а оставшиеся - в выходные. Команда PORTC |= 0b00011111; включает внутренние подтягивающие резисторы на 5 входах контроллера. Согласно схеме, к этим входам подключены кнопки, которые при нажатии замкнут их на землю. Таким образом контроллер понимает, что кнопка нажата.

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

Обработка прерываний

ISR (TIMER0_OVF_vect) { display(); if (_buzzer > 0) { _buzzer--; if (_buzzer == 0) sound_off(); } } ISR(TIMER1_COMPA_vect) { if (ActiveTimer == 1 && Timer1 > 0) { Timer1--; if (Timer1 == 0) process_timeoff(); } if (ActiveTimer == 2 && Timer2 > 0) { Timer2--; if (Timer2 == 0) process_timeoff(); } }

При срабатывании таймера управление передается соответствующему обработчику прерывания. В нашем случае это обработчик TIMER0_OVF_vect, который вызывает процедуру вывода времени на индикаторы, и TIMER1_COMPA_vect, который обрабатывает обратный отсчет.

Вывод на индикаторы

Void display() { display_number((Timer1/60)/10, 0b00001000); _delay_ms(0.25); display_number((Timer1/60)%10, 0b00000100); _delay_ms(0.25); display_number((Timer1%60)/10, 0b00000010); _delay_ms(0.25); display_number((Timer1%60)%10, 0b00000001); _delay_ms(0.25); display_number((Timer2/60)/10, 0b10000000); _delay_ms(0.25); display_number((Timer2/60)%10, 0b01000000); _delay_ms(0.25); display_number((Timer2%60)/10, 0b00100000); _delay_ms(0.25); display_number((Timer2%60)%10, 0b00010000); _delay_ms(0.25); PORTD = 0; } void display_number(int number, int mask) { PORTB = number_mask(number); PORTD = mask; }

Функция display использует метод динамической индикации. Дело в том, что каждый отдельно взятый индикатор имеет 9 контактов (7 для управления сегментами, 1 для точки и 1 для питания). Для управления 4 цифрами понадобилось бы 36 контактов. Слишком расточительно. Поэтому вывод разрядов на индикатор с несколькими цифрами организован по следующему принципу:

Напряжение поочередно подается на каждый из общих контактов, что позволяет высветить на соответствующем индикаторе нужную цифру при помощи одних и тех же 8 управляющих контактов. При достаточно высокой частоте вывода это выглядит для глаза как статическая картинка. Именно поэтому все 8 питающих контактов обоих индикаторов на схеме подключены к 8 выходам порта D, а 16 управляющих сегментами контактов соединены попарно и подключены к 8 выходам порта B. Таким образом, функция display с задержкой в 0.25 мс попеременно выводит нужную цифру на каждый из индикаторов. Под конец отключаются все выходы, подающие напряжение на индикаторы (команда PORTD = 0;). Если этого не сделать, то последняя выводимая цифра будет продолжать гореть до следующего вызова функции display, что приведет к ее более яркому свечению по сравнению с остальными.

Обработка нажатий

Void handle_buttons() { handle_button(KEY_SETUP); handle_button(KEY_RESET); handle_button(KEY_PAUSE); handle_button(KEY_PLAYER1); handle_button(KEY_PLAYER2); } void handle_button(int key) { int bit; switch (key) { case KEY_SETUP: bit = SETUP_BIT; break; case KEY_RESET: bit = RESET_BIT; break; case KEY_PAUSE: bit = PAUSE_BIT; break; case KEY_PLAYER1: bit = PLAYER1_BIT; break; case KEY_PLAYER2: bit = PLAYER2_BIT; break; default: return; } if (bit_is_clear(BUTTON_PIN, bit)) { if (_pressed == 0) { _delay_ms(DEBOUNCE_TIME); if (bit_is_clear(BUTTON_PIN, bit)) { _pressed |= key; // key action switch (key) { case KEY_SETUP: process_setup(); break; case KEY_RESET: process_reset(); break; case KEY_PAUSE: process_pause(); break; case KEY_PLAYER1: process_player1(); break; case KEY_PLAYER2: process_player2(); break; } sound_on(15); } } } else { _pressed &= ~key; } }

Эта функция по очереди опрашивает все 5 кнопок и обрабатывает нажатие, если таковое случилось. Нажатие регистрируется проверкой bit_is_clear(BUTTON_PIN, bit) , т.е. кнопка нажата в том случае, если соответствующий ей вход соединен с землей, что и произойдет, согласно схеме, при нажатии кнопки. Задержка длительностью DEBOUNCE_TIME и повторная проверка нужна во избежание множественных лишних срабатываний из-за дребезга контактов. Сохранение статуса нажатия в соответствующих битах переменной _pressed используется для исключения повторного срабатывания при длительном нажатии на кнопку.
Функции обработки нажатий достаточно тривиальны и полагаю, что в дополнительных комментариях не нуждаются.

Полный текст программы

#define F_CPU 4000000UL #include #include #include #define DEBOUNCE_TIME 20 #define BUTTON_PIN PINC #define SETUP_BIT PC0 #define RESET_BIT PC1 #define PAUSE_BIT PC2 #define PLAYER1_BIT PC3 #define PLAYER2_BIT PC4 #define KEY_SETUP 0b00000001 #define KEY_RESET 0b00000010 #define KEY_PAUSE 0b00000100 #define KEY_PLAYER1 0b00001000 #define KEY_PLAYER2 0b00010000 volatile int ActiveTimer = 0; volatile int Timer1 = 0; volatile int Timer2 = 0; volatile int _buzzer = 0; volatile int _pressed = 0; // function declarations void init_io(); void init_data(); int number_mask(int num); void handle_buttons(); void handle_button(int key); void process_setup(); void process_reset(); void process_pause(); void process_timeoff(); void process_player1(); void process_player2(); void display(); void display_number(int mask, int number); void sound_on(int interval); void sound_off(); // interrupts ISR (TIMER0_OVF_vect) { display(); if (_buzzer > 0) { _buzzer--; if (_buzzer == 0) sound_off(); } } ISR(TIMER1_COMPA_vect) { if (ActiveTimer == 1 && Timer1 > 0) { Timer1--; if (Timer1 == 0) process_timeoff(); } if (ActiveTimer == 2 && Timer2 > 0) { Timer2--; if (Timer2 == 0) process_timeoff(); } } int main(void) { init_io(); init_data(); sound_off(); sei(); while(1) { handle_buttons(); } return 0; } void init_io() { // set output DDRB = 0xFF; DDRD = 0xFF; // set input DDRC = 0b11100000; // pull-up resistors PORTC |= 0b00011111; // timer interrupts TIMSK = (1< 5940 || Timer2 > 5940) { Timer1 = 0; Timer2 = 0; } } void process_reset() { init_data(); } void process_timeoff() { init_data(); sound_on(30); } void process_pause() { ActiveTimer = 0; } void process_player1() { ActiveTimer = 2; } void process_player2() { ActiveTimer = 1; } void handle_button(int key) { int bit; switch (key) { case KEY_SETUP: bit = SETUP_BIT; break; case KEY_RESET: bit = RESET_BIT; break; case KEY_PAUSE: bit = PAUSE_BIT; break; case KEY_PLAYER1: bit = PLAYER1_BIT; break; case KEY_PLAYER2: bit = PLAYER2_BIT; break; default: return; } if (bit_is_clear(BUTTON_PIN, bit)) { if (_pressed == 0) { _delay_ms(DEBOUNCE_TIME); if (bit_is_clear(BUTTON_PIN, bit)) { _pressed |= key; // key action switch (key) { case KEY_SETUP: process_setup(); break; case KEY_RESET: process_reset(); break; case KEY_PAUSE: process_pause(); break; case KEY_PLAYER1: process_player1(); break; case KEY_PLAYER2: process_player2(); break; } sound_on(15); } } } else { _pressed &= ~key; } } void handle_buttons() { handle_button(KEY_SETUP); handle_button(KEY_RESET); handle_button(KEY_PAUSE); handle_button(KEY_PLAYER1); handle_button(KEY_PLAYER2); } void display() { display_number((Timer1/60)/10, 0b00001000); _delay_ms(0.25); display_number((Timer1/60)%10, 0b00000100); _delay_ms(0.25); display_number((Timer1%60)/10, 0b00000010); _delay_ms(0.25); display_number((Timer1%60)%10, 0b00000001); _delay_ms(0.25); display_number((Timer2/60)/10, 0b10000000); _delay_ms(0.25); display_number((Timer2/60)%10, 0b01000000); _delay_ms(0.25); display_number((Timer2%60)/10, 0b00100000); _delay_ms(0.25); display_number((Timer2%60)%10, 0b00010000); _delay_ms(0.25); PORTD = 0; } void display_number(int number, int mask) { PORTB = number_mask(number); PORTD = mask; } void sound_on(int interval) { _buzzer = interval; // put buzzer pin high PORTC |= 0b00100000; } void sound_off() { // put buzzer pin low PORTC &= ~0b00100000; }

Прототип был собран на макетной плате.

Я категорически против такого подхода. Обычно это все заканчивается - либо ничем, либо забитые форумы с мольбами помочь. Даже если кому то помогают, то в 90% он больше никогда не всплывет на сайтах по электронике. В остальных 10% он так и продолжает заливать форумы мольбами, его будут сначала пинать, затем поливать грязью. Из этих 10% отсеивается еще 9%. Далее два варианта: либо таки до глупой головы доходит и все же происходит goto к началу, либо в особо запущенных вариантах, его удел копировать чужие конструкции, без единой мысли о том как это работает. Из последних зачастую рождаются ардуинщики.

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

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

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

2. Перед решением задачи, дробите ее до абсурда вплоть до «припаять резистор», это помогает, проверено. Мелкие задачи решать куда проще. Когда большая задача разбита на кучу мелких действий, то все что остается - это выполнить их. Могу привести еще один годный совет, хоть он вам и покажется бредовым - заведите блокнотик и пишите в него все что собираетесь сделать. Вы думаете, итак запомню, но нет. Допустим сегодня у меня хорошее настроение и думаю о том, как собрать плату. Запиши план действий: сходить купить резистор, подготовить провода, сделать крепление дисплея. Потом все забудешь, откроешь блокнотик и смотришь - ага сегодня настроение попилить и построгать, сделаю крепление. Или собираешь ты плату и уже осталось допаять последний компонент, но не тут то было резисторы кончились, вот записал бы перед тем как паять, то вспомнил.

3. Не пользуйтесь кодогенераторами, нестандартными фичами и прочими упрощалками, хотя бы на первых этапах. Могу привести свой личный пример. Во времена активного использования AVR я пользовался кодогеном CAVR. Меня он полностью устраивал, хотя все говорили, что он кака. Звоночки звенели постоянно, были проблемы с библиотеками, с синтаксисом, с портированием, но было тяжело от этого отказаться. Я не разбирался как это работает, просто знал где и как поставить галочки.

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

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

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

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

Очень многие начинающие брезгуют изучением языка, поэтому если вы не будете как все, то сразу станете на две ступени выше остальных новичков. Так же не никакой разницы, где изучать язык. На мой взгляд, микроконтроллер для этого не очень подходит. Гораздо проще поставить какую нибудь Visual studio или Qt Creator и порешать задачки в командной строке.

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

5. Изучение ассемблера? Бояться его не нужно, равно как и боготворить. Не нужно думать, что умея написать программу на ассемблере, вы сразу станете гуру микроконтроллеров, почему то это частое заблуждение. В первую очередь это инструмент. Даже если вы не планируете использовать его, то все равно я бы настоятельно рекомендовал написать хотя бы пару программ. Это сильно упростит понимание работы микроконтроллера и внутреннего устройства программ.

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

7. Часто народ просит прислать даташит на русском. Даташит - это то, что должно восприниматься как истина, самая верная информация. Даже там не исключены ошибки. Если к этому добавятся ошибки переводчика, он ведь тоже человек, может даже не нарочно, просто опечататься. Либо у него свое видение, может что-то упустить, на его взгляд не важное, но возможно крайне важное для вас. Особенно смешной становится ситуация, когда нужно найти документацию на не сильно популярные компоненты.

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

Мною был проведен эксперимент: в наличии был студент, даташит и гугл переводчик. Эксперимент №1: студенту вручен даташит и дано задание самостоятельно найти нужные значения, результат - «да как я смогу», «да я не знаю английский», «я ничего не нашел/я не понял» типичные фразы, говорящие о том, что он даже не пытался. Эксперимент №2: тому же студенту, вручен все тот же даташит и тоже задание, с той разницей, что я сел рядом. Результат - через 5 минут он сам нашел все нужные значения, абсолютно без моего участия, без знания английского.

8. Изобретайте велосипед. Например, изучаете какую то новую штуку, допустим транзистор, дядька Хоровиц со страниц своей книги авторитетно заявляет, что транзистор усиливает, всегда говорите - НЕ ВЕРЮ. Берем в руки транзистор включаем его в схему и убеждаемся что это действительно так. Есть целый пласт проблем и тонкостей, которые не описываются в книгах. Прочувствовать их можно только, когда возьмешь в руки и попробуешь собрать. При этом получаем кучу попутных знаний, узнаем тонкости. Кроме того, любая теория без практики забудется намного быстрее.

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

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

9. А как бы я сделал это, если бы находился на месте разработчиков? Могу ли я сделать лучше? Каждый раз задавайте себе эти вопросы, это очень хорошо помогает продвигаться в обучении. Например, изучите интерфейсы 1wire, i2c, spi, uart, а потом подумайте чем они отличаются, можно ли было сделать лучше, это поможет осознать почему все именно так, а не иначе. Так же вы будете осознавать, когда и какой лучше применить.

10. Не ограничивайтесь в технологиях. Важно что этот совет имеет очень тонкую грань. Был этап в жизни, когда из каждой подворотни доносилось «надо бы знать ПЛИС», «а вот на ПЛИС то можно сделать». Формально у меня не было целей изучать ПЛИСины, но и пройти мимо было никак нельзя. Этому вопросу было выделено немного времени на ознакомление. Время не прошло зря, у меня был целый ряд вопросов, касаемых внутреннего устройства микроконтроллеров, именно после общения с плисинами я получил ответы на них. Подобных примеров много, все знания, которые я приобретал в том или ином виде, рано или поздно пригодились. У меня нет ни единого бесполезного примера.

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

11. Если спросить начинающего радиолюбителя, что ему больше нравится программирование или схемотехника, то с вероятностью 99% ответ будет программирование. При этом большую часть времени эти программисты тратят на изготовление плат ЛУТом/фоторезистом. Причины в общем то понятны, но довольно часто это переходит в некий маразм, который состоит в изготовлении плат ради изготовления плат.

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

12. Следующий совет, особенно болезненный, мне очень не хочется его обсуждать, но надо. Часто мне пишут, мол ххх руб за ууу дорого, где бы подешевле достать. Вроде бы обычный вопрос, но обычно я сразу напрягаюсь от него, так как зачастую он переходит в бесконечные жалобы на отсутствие денег. У меня всегда возникает вопрос: почему бы не оторвать пятую точку и не пойти работать? Хоть в тот же макдак, хоть на стройку, потерпеть месяц, зато потом можно приобрести парочку плат, которых хватит на ближайший год. Да я знаю, что маленьких городах и селах сложно найти работу, переезжайте в большой город. Работайте на удаленке, в общем нужно крутиться. Просто жаловаться нет смысла, выход из ситуации есть, кто ищет его тот находит.

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

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

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

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

Еще в самом начале, когда микроконтроллеры были для меня хобби, я много помогал с курсовыми и дипломами разных вузов, просто чтобы оценить свой уровень. Могу сказать уверенно, что уровень в целом невысок вне зависимости от имени вуза. Учиться несколько лет, для того чтобы написать такой диплом, совершенно необязательно. Достигнуть этого можно самостоятельно за весьма короткий срок. И все же зачастую бывали моменты, когда студенты знали какой то предмет, который они проходили на 2-3 курсе, а я этого не знал. Хоть все эти знания и компенсировались самообразованием, но все же лучше было бы не тратить на это время.

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

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

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

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

16. Поздно ли начинать программировать в 20, 30, 40, 50 лет? Практика других людей показывает, что возраст вообще не помеха. Многие почему то не учитывают то, что есть целый пласт работы, которую молодые в силу своих амбиций не хотят делать. Поэтому работодатели предпочитают брать тех, кто будет ее тащить. Это ваш шанс зацепиться, а дальше все зависит только от вас.

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

Рассказывает об опыте введения программирования микроконтроллеров в школьную программу для детей с ОВЗ. Текст публикуется с разрешения автора.

Почему робототехника с Arduino?

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

Уважаемые коллеги, еще раз хочу обратить ваше внимание. Робототехника — это не только информатика, но и физика, химия, биология и т. п. И в этих предметных областях можно столько интересных проектов с учениками сделать, если еще раз хорошенько присмотреться к робототехнике. Подсказка: датчики. Их можно смастерить самим (материала предостаточно в интернете), некоторые можно купить. Плюс к этому — плата (или любой аналог), Troyka Shield и лаборатория готова (ну почти готова, нужно не забыть откалибровать собранный прибор).

Но многие почему-то все же обходят эту тему стороной, считая ее сложной для понимания. Кто-то все никак не может решиться, ведь это отнимает уйму времени. А кто-то надеется, что когда-нибудь в школе появится Lego или цифровые лаборатории (с датчиками PASCO, например), вот тогда уж… или ждут, когда учебник напишут, да методические пособия с планированием. Но посмотрим, что происходит — пока мы тут раскачиваемся, наши с вами ученики уже и в этом вопросе обходят нас (они самостоятельно осваивают эту тему, строят собственных роботов и конструируют 3D-принтеры).

Программирование микроконтроллеров. Начало

Сначала я планировал вести кружок по робототехнике, но все-таки решил, что стоит попробовать включить в основную программу 11-го класса изучение темы «программирование микропроцессоров».

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

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

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

Если смотреть со стороны технического оснащения, использовать было решено CMPC (я рассчитывал, что это ускорит работу и позволит избежать потерю времени на уроке) и платы Freeduino Nano с платами расширения.

Но включив компьютер, на первом же уроке я понял, что нужно срочно сносить лишний софт (особенно e-Learning 6.0 очень замедляет работу, интересно, что, когда я помогал проводить уроки по другим предметам, оказывая техническую поддержку, меня это так не раздражало). А вообще, у меня в мыслях установить Linux , но пока проблемы со временем.

С платами Freeduino (аналог Arduino , куплены для себя за собственный счет) оказалось, что возить их туда-обратно постоянно тоже не удобно, поэтому думаю купить в Амперке нормальный комплект к новой четверти, чтобы постоянно был в школе.

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

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

Спустя примерно неделю купил в Амперке набор «Матрешка Z» . Мне повезло: комплекты были в наличии, поэтому долго ждать не пришлось и через два дня после заказа на сайте я уже раскладывал детали по ячейкам в коробке (что входит в комплект можно посмотреть на сайте, поэтому я не буду останавливаться на этом).

Набор «Матрешка Z»

Набор «Матрешка Z»

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

В первый день, когда дети увидели сей набор, восторга было словами не передать. Особенно мне понравилась реакция моей девичьей группы. Для каждой детальки они тут же придумали свое название (стульчик, кроватка, жучок, шашлычок, паучок и т.п.). И пока переустанавливали программное обеспечение под Arduino Uno (нужна была более свежая версия), они разыграли целый спектакль (вот такие творческие у меня ученицы).

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

В результате мною был приобретен еще один набор, только уже Матрешка Y , а с ним еще:

  • IO Shield,
  • соединительные провода,
  • трехосный акселерометр,
  • инфракрасный датчик движения,
  • латунные стойки, 2 комплекта,
  • Breadboard Mini, 2 штуки,
  • Proto Shield в сборе,
  • датчик газа,
  • блок питания.

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

  • (довольно дешевый вариант, правда, паять придется все от начала до конца),

  • датчик магнитного поля,
  • датчик линии (QTR-8A Reflectance Sensor Array более глазастый),
  • датчик линии (этот датчик для начальных экспериментов),
  • Freeduino USB complete KIT (а-ля спаяй сам Freeduino, взял, чтобы потренироваться перед пайкой робота, ну и в хозяйстве пригодится (про процесс пайки подробно в ближайшее время тоже расскажу, все заснял на фотоаппарат)),
  • iPodEXT Assembled (дает возможность подключится к Ipad и Iphone, но пока не знаю, насколько это получится),
  • датчик температуры и влажности.

Но это все железная сторона вопроса.

Самое главное, пожалуй, это то, что за это время стало вырисовываться, что и в каком порядке давать (в смысле какие темы). Подбираются практические задания, которые я постепенно оформлю и опубликую. Да, отдельное спасибо хочу сказать Паршеву Александру Анатольевичу (не только от меня, но от моих учеников), его личный блог меня очень выручил. По приезду из Лондона дел успело накопиться много (помимо урочной деятельности), а здесь — готовые задания и как раз в нужный момент: Занятие 2 , Занятие 4 , Занятие 5 .

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

Практика применения различных комплектов (собранных самостоятельно и уже готовых наборов) показала, что:

  • самый оптимальный вариант на сегодня для школы это Матрешка Y и Матрешка Z ,
  • с одним комплектом работать могут не более одного ученика,
  • если у вас 2 часа в неделю робототехники и занятия не спаренные, то комплектов понадобится в двое больше
  • количество датчиков в наборах не достаточное (только на начальный уровень), поэтому нужно планировать их закупку дополнительно, а также специальных плат (IO Shield) для возможности подключения нескольких датчиков, двигателей, сервоприводов к Arduino,
  • дополнительно придется докупить и сервоприводы (по одному на набор Матрешка),
  • плюс к этому нужно выбрать уже готовые робот-платформы (это может быть и рука манипулятор), которые в заключение ученики будут иметь возможно обучить чему-то (собрать робота реально только в рамках дополнительного образования, хорошо, когда параллельно есть уроки по программированию микропроцессоров и кружок по робототехнике).

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

В набор входит комплект перемычек.

Так как они очень незаметные на макетной плате, дети постоянно их забывают вынуть (можно что-нибудь спалить из железа).

Программирование микроконтроллеров. Еще раз про Матрешку

Матрешка Y и Z версии хорошо использовать — в основном из-за удачной комплектации, а также ко всему прочему существует Амперка/Вики в поддержку данного проекта, где выложены замечательная подборка видеоуроков по Arduino от Джереми Блюма , переведенных на русский и много других интересных проектов, некоторые из которых можно без какого-либо изменения использовать на уроке.

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

Но вот настал момент, и мы решили собрать таймер из двух 7-сегментных индикаторов (в наборе они прописаны, как Комплект «7-сегментов» , он содержит два 7-сегментных индикатора, микросхему-драйвер CD4026 для управления и десяток резисторов на 220 Ом), схему подключения с подробным описанием смотрите .

Начался урок, я рассказываю детям, чем мы будем заниматься на уроке. Они открыли страницу со схемой подключения, достали макетную плату детали, провода и микросхему-драйвер. Ни о чем не подозревая, разместили два индикатора по бокам, как показано на схеме, разместили драйверы. И тут мои ученики посчитали количество ног у микросхемы и в один голос с недоумением говорят мне: «А двух ног не хватает. Что делать?». Мне осталось констатировать тот факт, что при комплектации была положена другая микросхема, ее аналог. В место CD4026 положили К176ИЕ4 (но нигде в описании об этом не упоминалось.)



Запаивая еще одну микросхему на очередную плату или перерезая дорожку на плате в десятый раз для внесения очередных (но не последних) изменений в новое устройство, вы начинаете подумывать: «А не бросить мне это нудное занятие?!» Ваше новое устройство получается не таким, как вам бы хотелось, но и изменять схему и переделывать всё на плате вам уже надоело.
Перелистывая журналы по электронике, вы всё чаще встречаете слова: процессор, микроконтроллер, прошивка, программирование. Но эти слова для вас не имеют конкретного значения. Вы где-то слышали, а может даже и держали в руках то, о чем вы даже думаете с благоговейным трепетом… микроконтроллеры! То, что уменьшает размеры устройств, наделяя их недостижимыми для вас возможностями…Нет, вам, как электронщику, понятны общие идеи работы этих устройств, но об их практическом применении в своих изделиях не может быть и речи! Вы уже несколько раз пытались освоить микроконтроллеры, даже приобрели пару книг из серии «… для чайников» и скачали из интернета несколько популярных самоучителей. Проходило какое-то время, и всё останавливалось на самом интересном месте: схемы, показанные в книгах, вам были понятны, но вот методы создания программы для вас так и остались загадкой. Набрать несколько символов на английском (или каком-то там) языке в указанной книгой программе для вас не проблема. Но не ясна СУТЬ и МЕТОДЫ использования этих загадочных символов, последовательность которых в книге называли программой. Вы винили себя в тупости и откладывали идею освоения микроконтроллеров в дальний ящик. Да и зачем? Вы и так прекрасно справляетесь: у вас есть много-много микросхем, на которых вы разрабатываете свои устройства… Устройства на больших платах, которые вы долго-долго отлаживаете и переделываете…
Но знакомитесь с парнишкой из соседнего дома: он пишет программы, загружает их в микроконтроллер и то, что вам приходится отлаживать месяцами, он делает за несколько дней. Вы в панике, начинаете искать заброшенные книжки, и вспоминать всё ранее прочитанное… Он может, а вы – нет. Вы поближе знакомитесь с этим парнишкой, и под видом стороннего разговора начинаете расспрашивать его о микроконтроллерах и их возможностях. И он спокойно говорит о том, что контроллеры для него хобби. Вы просите его рассказать вам об их устройстве. Его ответы просты и незатейливы.

Микроконтроллеры. Что такое микроконтроллер?
Микроконтроллер - это маленький специализированный компьютер, по-русски микро-ЭВМ. Причем, эта микро-ЭВМ выполнена в одной микросхеме, на одном кристалле. Отсюда и полное название: «однокристальная микро-ЭВМ». Как и компьютер, микроконтроллер - это электронное устройство, работой которого управляет программа - последовательность команд, заранее загруженная в память. Эти команды выполняет процессор: этакий «мега-мозг», имеющий в своем составе АЛУ - арифметически-логическое устройство. Т.е, процессор «умеет» выполнять математические действия и производить логические операции над данными.

Разрядность процессора. Методы представления информации.
И процессор, и память - цифровые устройства, которые «понимают» сигналы только двух уровней: есть напряжение/ток, и нет напряжения/тока на линии. Эти два состояния принято записывать так: логическая единица - «1», и логический ноль - «0». Команды и данные - это набор единичек и нулей. Одна линия (называют разрядом) при двух её состояниях может передать только два значения. Но при увеличении количества разрядов увеличивается и количество значений: два разряда - уже четыре, а восемь разрядов - уже 256 значений. Разряд принято называть битом: один разряд это один бит. А набор из восьми разрядов - байтом: восемь бит это один байт. Но один байт имеет только 256 значений. Для передачи большего количества информации используется несколько, последовательно расположенных в памяти, байт. Два байта передают уже 65536 значений. Три байта - 16777216 значений! И так далее. Самыми распространенными являются процессоры, которые за одно действие могут обработать восемь разрядов, поэтому такие процессоры и называют восьмиразрядными.

Система команд процессора.
При разработке процессора в него закладывают возможность выполнения определенных команд. Команды, которые данный процессор в состоянии выполнять, называют набором команд. Что это за команды? Самые распространенные арифметические и логические команды, а также команды работы с портами - линиями связи процессора с внешним миром. Процессор, считав значение из ячейки памяти или состояние порта в собственную память - регистр, может произвести над ним математические или логические действия. Математически действия нам понятны: сложение, вычитание и другие. Под логическими действиями понимаются такие действия: сравнение - больше, меньше, равно; работа над разрядами ячейки памяти или регистра: обнуление или его установка, а также операции сдвига разрядов влево или вправо.

Память и её типы.
Данные могут быть считаны из памяти. Память - место, где какое-то время могут храниться программа и/или данные. Они могут храниться кратковременно - до отключения питания, или долговременно - независимо от наличия напряжения питания. Память первого типа используется для хранения промежуточных данных, используемых при выполнении различных операций. Поэтому её так и называют - «оперативная память». Память второго типа чаще используется для хранения программы. Типов долговременной памяти несколько: однократно программируемая память, память с электрическим стиранием и память, стираемая ультрафиолетовым или рентгеновским излучением. Физическое устройство и принцип работы памяти может быть разным, но суть одна: хранить данные. Для описания хранилища данных используют понятие «ячейка». Следовательно, чем больше ячеек, тем больше данных может быть сохранено. У каждой из ячеек имеется индивидуальный адрес. Процессор обращается к значению ячейки памяти именно по её адресу.

Порты. Режимы работы портов.
Данные так же могут быть получены из внешних устройств через линии связи - выводы микроконтроллера. Эти линии связи называют портами, а по-научному: устройства ввода и вывода данных. Выводы порта могут быть входами, с использованием которых процессор получает информацию извне от разных датчиков, или быть выходами, подавая сигналы на которые можно управлять внешними устройствами. В современных микроконтроллерах выводы практически всех портов двунаправленные, т.е., могут быть и входами, и выходами. Универсальные порты необходимо настраивать - установить режим работы на ввод или вывод. Для этого имеется специальная ячейка в памяти - регистр управления режимами работы порта. Например, для того, чтобы сделать входом необходимый вывод (разряд) порта, в разряд регистра управления записывают 1 или 0, в зависимости от модели микроконтроллера.

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

Семейства микроконтроллеров.
Наличие всех перечисленных устройств в составе микроконтроллера необязательно. Чаще всего производитель выпускает несколько моделей изделий, имеющих в своем составе различные периферийные устройства. Микроконтроллеры с одним типом процессора (и набором исполняемых машинных кодов), но различными периферийными устройствами, относят к одному семейству. Так и говорят: микроконтроллеры семейства ATtiny.

Многофункциональность выводов микроконтроллера.
Может возникнуть вопрос: как все эти устройства «общаются» с внешним миром, если у большинства микросхем в корпусе DIP не более 40 выводов? Для решения проблемы нехватки выводов используют метод объединения функций нескольких устройств с использованием одного вывода. Например, выводы одного из портов (8 разрядов – 8 выводов) также используется и для работы аналогово-цифрового преобразователя, а выводы другого порта - как входы аналоговых компараторов, последовательного порта или для подключения других встроенных узлов. Для управления режимами работы выводов используется специальный регистр управления режимами работы порта (о нем рассказывалось ранее, при объяснении принципов работы портов). В большинстве микроконтроллеров выводы имеют несколько функций. Если обратиться к технической документации на контроллер, то при описании функции вывода будет сделано замечание об основной и об альтернативной функции данного вывода. Например: PD0/RX - нулевой разряд порта D одновременно является и входом последовательного порта, PB1/Ain0 - первый разряд порта В одновременно является входом аналогового компаратора.

Алгоритмы. Программы.
Команды для процессора даются в определенном порядке, в соответствии с ранее разработанным алгоритмом. Алгоритм - это последовательность выполнения процессором. Причем команды должна быть понятна процессору, и при этом иметь однозначное толкование, без какой-либо самостоятельности при её выполнении. Алгоритм можно записывать словесно. Например: начало программы; сделать нулевой разряд порта входом; сделать седьмой разряд порта выходом; считать значение нулевого разряда порта; если он равен логической единице, то выполнить следующие действия: загрузить в седьмой разряд порта логическую единицу; вернуться к началу программы. Так мы описали алгоритм работы схемы, состоящей из выключателя, лампочки (или другой нагрузки) и источника питания. Результат выполнения будет таков: при нажатии кнопки на вход порта поступает напряжение, процессор выполняет программу - подает на выход порта напряжение. И пока контакты буду замкнуты, на выходе порта будет напряжение.
Но такое написание весьма сложно воспринимать. Поэтому были разработаны методы графического описания алгоритма. Вот пример графической записи вышеописанного алгоритма.
Рис. Алгоритм-1. Графический метод описания алгоритма

Команды ветвления: условный и безусловный переходы.
К особым командам процессора относятся команды условного и безусловного перехода. Для того чтобы понять это, необходимо объяснить такое понятие как «указатель адреса выполняемой команды». У процессора имеется специальный регистр, в котором хранится адрес выполняемой в текущий момент команды. При подаче питания этот регистр обнуляется - в него записывается ноль. Далее процессор начинает выполнять команды, хранящиеся в памяти, начиная с нулевого адреса - ведь в регистре указателя адреса выполняемой команды указан ноль. Выполнив команду, этот указатель инкриминируется, т.е., его значение увеличивается. Процессор считывает следующую команду из памяти по адресу, указанную в указателе. Т.е, команды выполняются последовательно. Нарушить последовательность выполнения программы можно, используя команды условного и безусловного переходов. Для этого в одной из ячеек памяти хранится команда, указывающая процессору изменить значение регистра указателя адреса выполняемой команды. Команда безусловного перехода указывает процессору изменить порядок последовательно выполнения программы и начать выполнять команды, хранящиеся в памяти, начиная с ранее указанного адреса.
Команда условного перехода сложнее: при ее выполнении проверяется выполнения какого-либо условия. Например, необходимо сравнить значение двух ячеек памяти. Если значение первой ячейки больше, то продолжить выполнение программы по адресу А, иначе (т.е., значение первой ячейки меньше) - перейти по адресу С.

Прерывания и их типы. Приоритеты прерываний.
Имеется еще один способ «заставить» процессор прекратить последовательное исполнение программы и перейти к выполнению программы по определенному адресу - вызвать «прерывание». Понятие прерывание появилось вместе с первыми процессорами. Всё дело в том, что процессор управляет менее скоростными, чем он, устройствами. Например, процессор должен обрабатывать данные до появления определенного сигнала. Приведем простой пример: процессор выполняет программу подсчета количества импульсов, поступивших на один из его портов. При нажатии кнопки процессор должен прервать выполнение этой программы и выполнить другую программу: включить какое-либо устройство (т.е., подать на один из разрядов порта логическую единицу - «1»). Как решить эту задачу? Можно в самой программе постоянно опрашивать необходимый разряд порта, к которому подключена кнопка. Но при этом часть ресурсов (скорости) процессора будет практически впустую тратиться на опрос порта. Второй способ - это использование прерываний. У процессора (следовательно, и у микроконтроллера) имеется специальный вывод. Обычно его обозначают как «Int» (англ. «Interrupt» - прерывание). При подаче сигнала на вывод «Int» происходят следующие действия:
- остановка выполнения основной программы,
- в оперативной памяти сохраняется значение регистра указателя адреса выполняемой команды (место прерывания выполнения программы),
- после чего в этот же регистр загружается новый адрес (зависит от желания производителя процессора),
- в ячейке памяти с указанным адресом расположена команда безусловного перехода: «перейти по адресу хх»,
- в памяти, начиная с ячейки с адресом хх, расположена еще одна программа, назовем ее служебной программой.

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

Управляем процессором. Языки программирования. Трансляторы.
Машинные коды. Ассемблер.
Команды для процессора - последовательности единиц и нулей. Часто команды процессора называют машинными кодами, подчеркивая, что данные команды изначально рассчитаны на конкретного исполнителя - машину, но не человека. Запоминать команды из цифр (машинные коды) весьма сложно. Поэтому для упрощения работы был придуман способ замены цифровых последовательностей на более понятные человеку символьные сокращения. Например, для команды «загрузить данные» придумали понятное сокращение «ld» (англ. «load» - загрузить), для команды «сравнить» - «cp» (англ. «compare» - сравнение) и так далее. Данный метод символьной записи команд процессора называют «ассемблер». Если при работе с машинными кодами программист непосредственно вводит команды управления процессором в память устройства, то при работе с ассемблером между программой и процессором имеется своеобразный посредник, который преобразует символьные обозначения в машинные коды. Программу, являющуюся посредником, называют транслятором, т.е., переводчиком. Но тут есть маленький нюанс: ассемблером называют не только метод символьного обозначения цифровых команд (машинных кодов), но и программу-транслятор, которая помогает программисту перевести символьные обозначения команд непосредственно в машинные команды. Поэтому часто используется следующий прием: когда говорят о языке - пишут Ассемблер, когда о программе - просто ассемблер.
У Ассемблера есть огромное достоинство: программы, написанные на Ассемблере, очень быстро выполняются процессором. Дело в том, что Ассемблер - это практически машинная команда. Но у ассемблера есть и минусы: основной минус – сложность написания программ, второй - даже относительно несложные программы имеют большой обьем исходного текста, что затрудняет анализ программы.

Модульность программ. Часто повторяющиеся задачи.
Каждый программист за время своей работы накапливал определенное количество программ. Но многие программы содержат одинаковые действия. Например, во многих программах производится опрос клавиатуры и анализ нажатой кнопки. Значит, эту часть кода программы можно переносить из одной программы в другую. Из таких кусочков (модулей) постепенно сформировались библиотеки программ. Программисты стали «лепить» программу из модулей: т.е., вставляли необходимый модуль в необходимое место программы. Такой подход ускорял процесс написания программы и увеличивал надежность работы программы в целом за счет использования уже отлаженных модулей. Но с первых дней возникла проблема совместного использования модулей: ведь каждый программист писал модули по собственному «стандарту» - как ему было удобнее в тот или иной момент. Поэтому постепенно выработался стандарт (точнее, несколько стартов) написания этих модулей. В них была описана структура модулей для их более удобного «склеивания» в одну программу.

Языки программирования и их функциональное разделение.
Постепенно эти разрозненные стандарты использования модулей сформировали то, что позднее будет названо «языками программирования». Как и человеческие языки, язык программирования имеет несколько подуровней, которые определяют как написание отдельных слов (модулей) и методы их записи, так и правила их использования. Со временем языки программирования преобразовывались и видоизменялись. Постепенно все языки программирования разделились на несколько групп, в зависимости от «профессиональной ориентации»:
- прикладные языки программирования (FORTRAN для математиков, FoxPro для финансовых работников);
- универсальные (Pascal и Basic);
- системные (Ассемблер и Си).

Системные слова языки стали называть низкоуровневыми, т.е., программист работает на нижнем, наиболее приближенном к процессору, уровне. А языки, при работе с которыми программист не сталкивается с непосредственным управлением работой процессора, стали называть Языками Высокого Уровня (часто обозначают как ЯВУ). Не путайте это сокращение с названием языка «Ява» - «Java».

Трансляция программы. Методы трансляции программы.
Как и при использовании Ассемблера, программу, написанную на любом языке высокого уровня, необходимо преобразовать в понятные процессору команды. Вначале это делалось в ручную: в таблице находили команду на ассемблере и записывали ее в машинном коде. Для ускорения процесса преобразования (трансляции) программы были написаны специальные программы - трансляторы. Существует два метода трансляции программы: интерпретация и компиляция. Следовательно, и транслятор называют либо интерпретатор, либо компилятор. При использовании интерпретатора исходный текст программы анализируется и последовательно, команда за командой, выполняется интерпретатором. В интерпретаторе содержатся модули всех используемых действий. Такое покомандное преобразование очень медленное. Но данный метод имеет большой плюс: программу можно остановить, изменить ее код и продолжить её выполнение. Это удобно при отладке программы. Так же в данном случае мы имеем исходный текст программы и можем его многократно редактировать.
При использовании компилятора текст программы анализируется, и создается файл с машинными командами, так называемый исполняемый файл. Это обеспечивает очень высокую скорость выполнения откомпилированной программы - ведь преобразование текста программы в машинные коды происходит только один раз при её компиляции. Но изменить программу «на лету» не получится: необходимо изменить текст программы и заново её откомпилировать. Если исходный текст отсутствуют по какой-либо причине, то перекомпилировать программу невозможно, а изменить исполняемый файл крайне сложно.

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

Интегрированная среда разработки программ.
В последнее время появился новый подход: «Интегрированная Среда Разработки» (англ. «IDE»). Под интеграцией понимается выполнение в одной программе всего процесса создания программы: написав текст программы, программист щелчком мыши запускает трансляцию текста программы в машинные коды, после чего полученный исполняемый файл автоматически загружается в память процессорного устройства. Т.е., все делается в одной программе. Такой подход ускоряет работу программиста.

Первые сложности.
Все предыдущие главы были вводным курсом, готовящим вас к восприятию новой информации. На пути у нас имеется несколько проблем.
1. Большой объем разносторонней информации : электроника, устройство микроконтроллеров, алгоритмы, синтаксис языков программирования, описания работы с программным инструментарием. И как писать? Один читатель - хороший электронщик, но ни разу не писал программы, другой - программист, но электроника – на уровне радио кружка, третий - что-то среднее...

2. Выбор МК : если все микроконтроллеры хороши, то на основе какого изделия и какого производителя строить процесс дальнейшего обучения и практического применения микроконтроллеров?
Для того чтобы выбрать микроконтроллер для ОБУЧЕНИЯ нам необходимо выполнить следующие условия:
А) выбранный для обучения микроконтроллер должен быть доступным и недорогим.
Б) он должен быть современным изделием, но не самым новым.

Теперь подробнее о каждом пункте.
С пунктом А всё понятно: какой смысл изучать изделие, которое трудно приобрести или его цена заоблачная для новичка.
Пункт Б требует пояснения. Дело в том, что новые изделия всегда имеют какие-либо недоработки. Они обнаруживаются только через какие-то время, пока кто-то случайно не наткнётся на данную проблему в ходе работы с данным изделием. Но новинки не сразу попадают в новые конструкции: требуется время на написание программ для новых моделей. Тут присутствует человеческий фактор: у разработчиков уже имеются готовые решения на предыдущих моделях микроконтроллеров, и переходить на новые - сложно.
Также все новые микроконтроллеры имеют только фирменное описание. А оно написано на английском языке и с использованием многочисленных профессиональных терминов: ведь на профессионалов и рассчитано! А мы - ученики… Через какие-то время появляются примеры конструкций, более подробные описания с многочисленными комментариями и советами. Потом кто-то начнет переводить документацию на русский язык (не всё, но хотя бы самое сложное или наиболее часто используемое).
К новому микроконтроллеру может не быть и инструментария: компиляторы, отладчики и программаторы «не понимают» это изделие. Опять ожидание, пока авторы этих программ не обновят свои творения...

3. Необходимо выбрать язык программирования , на котором мы планируем писать программы для МК.
Выбор языка программирования - весьма щепетильное занятие. Для обучения программированию микроконтроллеров хотелось бы использовать язык программирования с простым синтаксисом: программист должен заниматься программой, но не ее оформлением!
Тут надо заранее сделать пояснение: в настоящее время среди разработчиков программ и устройств на микроконтроллерах популярны три «семейства» языков: Си (Пишут как «С»), Паскаль (Pascal) и Бейсик (BASIC). Паскаль изначально разрабатывался как инструмент изучения программированию. Бейсик самой структурой похож на Паскаль, но запись команд упрощена и требований к оформлению программы значительно меньше. Си – принято считать языком для профессионалов. Си – это как китайская философия: важен не только символ (команда), но и его начертание и цвет. Шутки шутками, но моё мнение таково: Си – это кошмар. Его использование оправдывается лишь в некоторых, весьма узко профильных, задачах. Но наша задача – попробовать свои силы, и минимально их тратить на задачи, не имеющих прямой связи с основной целью.

4. Нам необходима среда разработки программ для микроконтроллеров . Её выбор напрямую зависит от типа используемого МК и языка программирования.
Среда разработки программ очень важна для успешного освоения программирования микроконтроллеров. Писать программы в текстовом редакторе вроде «Блокнота» можно, но неудобно (проверено!). Да и в командной строке вызывать компилятор - дело неблагодарное в наш, графическо-оконный, век.
Выбор среды разработки напрямую зависит от микроконтроллера, на котором мы будет строить практическую часть обучения. Ко всему прочему нам надо иметь бесплатный инструментарий. Но, как показало тестирование таких программ, бесплатное ПО чаще всего имеет посредственное качество как с точки зрения и пользования, так и с точки зрения изучения программирования МК: наличие ошибок или недоработок в самих трансляторах создают дополнительные сложности и лишают уверенности в собственных силах.
Сойдет и демонстрационная версия, которая имела бы минимум ограничений и работала хотя бы пол года - именно такой срок необходим для получения навыков работы с микроконтроллерами в домашних условиях.

5. Программатор, с использованием которого будем загружать написанные программы в память МК . Выбор программатора также зависит от типа используемого МК. Есть, конечно, «универсальные» программаторы, позволяющие работать с разными микроконтроллерами и микросхемами памяти, но они дорогие. Да и не нужны в большинстве случаев. Поэтому проще изготовить что-то узкоспециализированное для данного семейства МК.
Но дело не столько в сложности схем программатора, а в методе подключения этого программатора к ПК. Тут необходимо пояснить: программатор - это электронный адаптер, преобразующий сигналы компьютерных интерфейсов (порты СОМ, LPT и USB) в сигналы, подаваемые на выводы МК для загрузки программы в его память. Электронным адаптером управляет программа ПК, которая и «заставляет» адаптер выдавать необходимые последовательности сигналов на выводы МК.
Если адаптер программатора, подключаемый к ПК через порты COM и LPT, возможно изготовить в домашних условиях - «на коленке», то изготовления такого адаптера, но подключаемого к USB порту, уже несколько проблематично: сердцем такого адаптера часто является… микроконтроллер. Тут возникает парадокс: для того чтобы запрограммировать МК нам необходимо запрограммировать МК.
Напрашивается логичный вопрос: а для чего изготавливать сложный адаптер, подключаемый к USB, когда можно сделать простой и подключить его к LPT или COM порту. Все дело в том, что многие (практически все) современные ПК не имеют в своем составе этих портов. Поэтому придется изготавливать более сложный адаптер для программирования МК.

Март 2010

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

Ответ на вопрос номер 1
Если материалы предыдущих глав еще как-то можно было логически систематизировать и преподносить поэтапно, то материалы в последующих главах даются параллельно: одно подразумевает другое. Возможно, вам мой метод подачи новых материалов покажется несколько сумбурным, но придумать что-то более красивое по оформлению я не смог.

Ответ на вопрос номер 2
Микроконтроллер производства компании ATMEL ATMEGA48. Хорошо описан, выпускается уже несколько лет, не планируется к снятию с производства еще как минимум 3 года, имеет оптимальные технические параметры.

Ответы на вопросы 3 и 4
Среда программирования - BASCOM (производитель MCS Electronics, автор Марк Альбертс). Язык программирования по стилю и требованиям к оформлению текста программы схож с Паскалем, но синтаксис команд взят из BASIC.
Причины выбора:
- полнофункциональная демонстрационная версия компилятора (единственное ограничение: генерируемый компилятором код ограничен объемом 4 КБайт)
- желание автора программы сотрудничать (я сделал перевод сообщений интерфейса и справочной системы на русский язык, он добавил русский язык в эту программу)
- наличие русскоязычного форума пользователей данного компилятора

Ответ на вопрос номер 5
Совместить простоту схемы и USB не получилось. Было решено описать две модели программаторов: одна подключается к LPT порту компьютера, вторая к COM порту. При отсутствии этих портов вторая версия программатора может быть подключена к компьютеру с использованием преобразователя USB-COM. Так получаем связку USB-COM-программатор-микроконтроллер.
Первая модель программатора известна как STK-200/300, содержит микросхему буфера с третьим состоянием и несколько резисторов. Вторая модель - известный программатор USBasp.