Программирование микроконтроллеров для начинающих. Устройство и программирование микроконтроллеров AVR

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

Какие микроконтроллеры существуют?

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

Как микроконтроллеры программируются?

Программирование микроконтроллеров осуществляется, как правило, с помощью специальных приспособлений, которые называются программаторами. Программаторы могут быть или покупными или самодельными. Но при прошивке микроконтроллера с помощью самодельного программатора шанс того, что он превратится в «кирпич», довольно высокий. Есть ещё один вариант, который можно рассмотреть на примере платы «Ардуино». Плата работает на МК фирмы Atmel, и в ней осуществляется программирование микроконтроллеров AVR. В плате уже есть заранее прошитый бутлоадер и порт USB, которые позволяют безопасно прошить используемый микроконтроллер, не давая пользователю доступа к данным, что могут этот самый МК вывести из строя. Программирование микроконтроллеров для начинающих не так сложно, как может показаться, и при определённой сноровке и сообразительности избавит вас от необходимости ехать за новым механизмом.

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

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

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

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

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

Напутствие

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

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

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

Тема микроконтроллеров меня заинтересовала очень давно, году этак в 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 лет? Практика других людей показывает, что возраст вообще не помеха. Многие почему то не учитывают то, что есть целый пласт работы, которую молодые в силу своих амбиций не хотят делать. Поэтому работодатели предпочитают брать тех, кто будет ее тащить. Это ваш шанс зацепиться, а дальше все зависит только от вас.

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

Доброго дня уважаемые радиолюбители!
Приветствую вас на сайте “ “

Что такое микроконтроллер, и для чего он нужен. Давайте обратимся к его определению:

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

То есть, по сути, микроконтроллер – это устройство, позволяющее воплотить в жизнь наши идеи (даже бредовые), но, естественно, в пределах своих возможностей. И самое главное, воплощение идеи в жизнь достигается не созданием навороченных электронных конструкций, а лишь только, в основном, силой нашей мысли (желаете стать волшебником?).
Наибольшей популярностью у радиолюбителей пользуются два вида микроконтроллеров:
PIC – фирмы Microchip Technology
AVR – фирмы Atmel

Сразу хочу сделать небольшое отступление и пояснить одну свою позицию. Я не собираюсь ни сейчас, ни потом, рассуждать о достоинствах того или иного вида микроконтроллеров, того или иного программного обеспечения, и вообще всего, что связано с микроконтроллерами, что-то советовать, но а тем более – навязывать читателям. Все это дело вкуса, личных предпочтений и поставленных конечных целей в изучении микроконтроллеров. Ну а так как “необъятное – не объять”, все свое дальнейшее повествование я буду вести применительно к микроконтроллерам AVR и, не очень распространенной, но мной любимой, программы “Algorithm Builder”. У разных типов микроконтроллеров, программ, есть, конечно, различия, но многое у них и общее. А познавать мир микроконтроллеров мы будем так, чтобы потом, полученные знания можно было бы без проблем применить и к PICам, и к любому программному обеспечению. И еще раз напомню, данная серия статей – моя попытка помочь тем, кто впервые услышал о существовании микроконтроллеров и желает постичь работу с ними.

Что нужно для того, чтобы научиться работать с микроконтроллерами? Я бы выделил несколько, на мой взгляд, главных условий:
1. Желание и настойчивость .
Тут все очень просто: есть желание – все получится. А желание с настойчивостью – вообще, вещь суперская.
2. Знание устройства микроконтроллера.
Здесь не важны глубокие знания (да может и вообще не нужны), но знать, что имеется “на борту” микроконтроллера необходимо. Только зная из чего состоит микроконтроллер, какие устройства в нем есть, их возможности, как они работают – только тогда мы сможем использовать возможности микроконтроллера на полную катушку.
3. Знание языка программирования и команд управления микроконтроллером.
Как будет работать микроконтроллер, какие задачи вы на него возлагаете и как он будет их выполнять, определяется заложенной в него программой – программой которую для микроконтроллера составляете вы сами. И на этом пункте мы остановимся несколько подробней, чтобы рассмотреть вопросы, которые могут появиться в будущем.

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

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

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

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

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

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

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

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

01000110
10010011
01010010

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

Ну что, я думаю и тут нам все понятно, – язык программирования изучать надо, по-другому – никак.

Команды и инструкции для управления микроконтроллером.
У микроконтроллеров AVR более 130 различных команд, которые позволяют ему реализовать все заложенные в нем возможности. Но сразу скажу – мало кто из любителей знает их все и тем более пользуется всеми. Обычно, в любительской практике хватает знания и половины команд, а то и меньше. Но изучать команды надо. Чем больше команд вы будете знать, тем изощреннее (в хорошем смысле слова) и элегантнее программы будут получаться.

Арифметико-логическое устройство и организация памяти – память программ, память данных, энергонезависимая память


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

Микросхема памяти — это электронный компонент, внутренняя структура которого способна сохранять (запоминать) внесённые программы, какие-либо данные или одновременно то и другое.

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

Следует отметить: чипы памяти всегда являются неотъемлемым дополнением микропроцессоров – управляющих микросхем. В свою очередь микропроцессор является основой электроники любой современной техники.

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

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

Программы или данные хранятся в чипе памяти как ряд чисел — нулей и единиц (биты). Один бит может быть представлен логическими нулем (0) либо единицей (1).

В единичном виде обработка битов видится сложной. Поэтому биты объединяются в группы. Шестнадцать бит составляют группу «слов», восемь бит составляют байт — «часть слова», четыре бита — «кусочек слова».

Программным термином для чипов, что используется чаще других, является байт. Это набор из восьми бит, который может принимать от 2 до 8 числовых вариаций, что в общей сложности даёт 256 различных значений.

Для представления байта используется шестнадцатеричная система счисления, где предусматривается использование 16 значений из двух групп:

  1. Цифровых (от 0 до 9).
  2. Символьных (от А до F).

Поэтому в комбинациях двух знаков шестнадцатеричной системы также укладываются 256 значений (от 00h до FFh). Конечный символ «h» указывает на принадлежность к шестнадцатеричным числам.

Организация микросхем (чипов) памяти

Для 8-битных чипов памяти (наиболее распространенный тип) биты объединяются в байты (8 бит) и сохраняются под определённым «адресом».

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


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

Есть вопросы?

Сообщить об опечатке

Текст, который будет отправлен нашим редакторам: