Введение
В одной из предыдущих статей, посвященных изучению микроконтроллеров AVR, на примере проекта частотомера мы рассмотрели использование 16-ти разрядного таймера/счетчика Т1 и прерывания по событию захват. В качестве дополнения к этому материалу, предлагаю улучшенную версию частотомера. В этом проекте тоже используется блок захвата и дополнительно еще задействован тактовый вход 8-ми разрядного таймера.
Недостатки старого проекта заключались в маленьком диапазоне измеряемых частот (~сотни киллогерц), что было связано со способом измерения периода сигнала.
Вы, наверное, помните, что в прерывании по событию захват счетный регистр 16-ти разрядного таймера обнулялся, а захваченное значение, соответствующее количеству импульсов тактового генератора микроконтроллера, укладывающихся в один период входного сигнала, сохранялось в переменной. На основе этого значения и выполнялись расчеты.
При повышении частоты входного сигнала микроконтроллер не успевал обрабатывать прерывания, пропускал их, и показания частотомера начинали резко расходиться с действительностью.
В новом проекте вычисление частоты выполняется по нескольким периодам входного сигнала и без постоянного использования прерывания по событию захват. Это уменьшает накладные расходы микроконтроллера и позволяет измерять значительно большие частоты — в идеале до 1/2 Fcpu (частоты тактирования микроконтроллера).
Итак, перейдем к описанию нового проекта частотомера.
Схема
Входной сигнал подается на вход схемы захвата таймера Т1 и счетный вход таймера Т0. Для того чтобы таймер Т0 тактировался от внешнего сигнала, он должен быть соответствующим образом настроен.
Структура проекта
Проект состоит из 4-ех программных модулей.
bcd.c – содержит функцию для вывода двоичных чисел на дисплей
timer.c – содержит функцию инициализации таймеров T0 и Т1, обработчики прерываний, функцию захвата значений счетных регистров таймеров и программных счетчиков и, наконец, функцию вычисления частоты.
lcd_lib.c – это библиотека для работы с символьным дисплеем.
main.c — основная программа.
Метод измерения частоты
Частота входного сигнала измеряется методом временных ворот. Суть метода заключается в подсчете количества импульсов измеряемого и опорного сигналов за определенный промежуток времени.
Для подсчета количества импульсов измеряемого сигнала используется счетный вход аппаратного таймера. В качестве опорного сигнала используется тактовый сигнал микроконтроллера.
Интервал времени, в течение которого выполняются подсчеты импульсов, отмеряется с помощью схемы захвата аппаратного таймера Т1 и программной задержки.
Формула для расчета частоты по методу временных ворот такая:
Fx = Fo * (M/N),
где Fx – частота входного сигнала, Fo – частота опорного сигнала, M – количество импульсов входного сигнала за время измерения, N – количество импульсов опорного сигнала за время измерения.
Алгоритм программы
В проекте используются два таймера — 8-ми разрядный таймер/счетчик Т0 и 16-ти разрядный Т1. Таймер T1 подсчитывает количество тактовых импульсов микроконтроллера (baseImp), укладывающихся в определенный временной интервал, а таймер Т0 считает импульсы измеряемого сигнала (mesurImp).
Временной интервал, в течение которого выполняются подсчеты импульсов, порядка одной секунды. Поскольку за это время оба таймера успевают много раз переполнится, в программе используются дополнительные программные счетчики (timer0, timer1). Это 16-ти разрядные переменные, которые инкрементируются в прерываниях таймеров Т0 и Т1.
Общий вид циклограммы работы таймеров представлен на рисунке ниже.
Алгоритм программы выглядит следующим образом.
1. Выполняется инициализация таймеров и дисплея
2. Микроконтроллер ожидает установки флага схемы захвата таймера Т1, или, выражаясь простым языком, ловит передний фронт измеряемого сигнала.
3. Дождавшись установки флага (момент Capture1 на рисунке), микроконтроллер сохраняет значения счетных регистров таймеров Т0 и Т1, а также значения программных счетчиков.
4. Вызывается программная задержка длительностью в одну секунду. Оба таймера продолжают работать.
5. По окончанию задержки микроконтроллер ожидает установки флага схемы захвата
6. Дождавшись установки флага (момент Capture2 на рисунке), микроконтроллер сохраняет значения счетных регистров Т0 и Т1 и значения программных счетчиков.
Измерение частоты сигнала с помощью микроконтроллеров AVR. Простой частотомер.
Существует много схемных решений и способов измерения частоты сигнала, в том числе и при помощи микроконтроллеров. В этой статье разберем пример самого простого частотомера построенного на контроллере Atmega8. Схема частотомера показана на рисунке 1. Для обеспечения хорошей точности измерения микроконтроллер тактируется от генератора с внешним кварцем частотой 8MHz. Измеренные показания выводятся на LCD 1602 с контроллером HD44780. VD1 стабилитрон ограничивает амплитуду входного сигнала, R2 токоограничительный резистор.
Рисунок 1.
Чтобы измерить частоту сигнала необходимо подсчитать количество импульсов, поступающих на вход микроконтроллера, за единицу времени. Для этого в нашей программе используем два типа перерывания: прерывание по переполнению таймера T0 и внешнее прерывание по изменению сигнала на входе INT0. Количество поступающих на вход сигналов будем подсчитывать за время — 1 секунда. Восьмибитный таймер T0 будет работать с частотой 1MHz, для этого включим предделитель на 8. Обработчик прерывания по переполнению таймера вызывается 4000 раз в секунду, при этом переменная counter увеличивает свое значение на единицу. Как только эта переменная станет равна 4000, т.е. пройдет 1 секунда, на дисплей уйдет информация о переменной edgecounter, затем обе переменные обнуляются. Все это происходит уже в главном цикле. Переменная edgecounter увеличивает свое значение на единицу каждый раз когда на входе INT0 происходит смена фронта сигнала, т.е. поступает 1 импульс.
Исходный код программы с подробными комментариями показан ниже:
// Измерение частоты сигнала с помощью микроконтроллеров AVR. Простой частотомер. #include #include #include volatile unsigned int edgecounter = 0, counter = 0; // Обработчик прерывания по переполнению Т0, вызывается 4000 раз в секунду ISR(TIMER0_OVF_vect) < TCNT0 = 6; // Счетчик Т0 начинает считать с 6, т.к. 1MHz/(256-6) = 4000Hz counter++; >// Обработчик внешнего прерывания ISR(INT0_vect) < edgecounter++; >// Функции работы с LCD #define RS PD0 #define EN PD1 // Функция передачи команды void lcd_com(unsigned char p) < PORTD &= ~(1 // Функция передачи данных void lcd_data(unsigned char p) < PORTD |= (1 // Функция вывода строки на LCD void lcd_string(unsigned char command, char *string) < lcd_com(0x0C); lcd_com(command); while(*string != '\0') < lcd_data(*string); string++; >> // Функция вывода переменной void lcd_num_to_str(unsigned int value, unsigned char nDigit) < switch(nDigit) < case 4: lcd_data((value/1000)+'0'); case 3: lcd_data(((value/100)%10)+'0'); case 2: lcd_data(((value/10)%10)+'0'); case 1: lcd_data((value%10)+'0'); >> // Функция инициализации LCD void lcd_init(void) < _delay_ms(50); // Ожидание готовности ЖК-модуля // Конфигурирование четырехразрядного режима PORTD |= (1 int main(void) < // Настройка портов ввода/вывода DDRD = 0b11110011; PORTD = 0x00; // Настройка таймера T0 TCCR0 |= (1 > >
Микроконтроллеры
Данная статья является обзорной, более подробную информацию по всем разделам можно найти в datasheet на конкретный микроконтроллер (далее МК). Основная цель этой статьи дать общее представление об основных модулях микроконтроллера, ответить на вопрос «Какие параметры МК являются ключевыми при выборе МК под проект?».
Мы будем осваивать все возможности МК сразу на приборах, начиная с простых и постепенно переходя к более сложным схемам. В каждом приборе мы будем подробно разбирать программу, и вы научитесь работать с МК на практике, сразу наблюдая результат своей работы. Также во всех приборах оставлено место для самостоятельной работы. Такой подход более продуктивный и интересный, чем работать с отладочной платой (например, Arduino или STM Discovery board). В этой статье мы не будем подробно рассматривать программирование МК (программированию посвящена отдельная статья Приемы программирования микроконтроллеров). Вам важно только запомнить название и назначение каждого модуля, его возможности и основные параметры. Статья является общей для всех видов МК, и не нацелена на какого то одного производителя.
Что такое микроконтроллер
Вы скорее всего хорошо представляете как устроен персональный компьютер. Рассмотрим его основные компоненты:
Микропроцессор (в англоязычной литературе MPU — Micro Processor Unit) содержит функционал компьютерного центрального процессора, или ЦП (CPU — Central Processing Unit) на одном полупроводниковом кристалле (ИМС — интегральная микросхема или на западный манер — Integrated Circuit). Он обрабатывает данные, поступающие с входных периферийных устройств и передаёт обработанные данные на выходные периферийные устройства.
В этой системе микропроцессор имеет множество вспомогательных устройств , таких как постоянное запоминающее устройство, оперативная память, последовательный интерфейс, таймер, порты ввода/вывода и т.д. Все эти устройства обмениваются командами и данными с микропроцессором через системную шину. Все вспомогательные устройства в микропроцессорной системе являются внешними. Системная шина, в свою очередь, состоит из адресной шины, шины данных и шины управления.
Разработать и сделать какое-либо устройство на современном микропроцессоре довольно сложно. В домашних условиях нереально. Шина данных, адресная шина требует много выводов. Их количество у микропроцессора в настоящее время доходит до 1000 выводов. Чтобы развести такое количество ножек нужна как минимум 6-ти слойная плата, а также необходимо использовать микропереходные отверстия — диаметром 0.1 мм. Ну и конечно такая система будет стоить не дёшево.
Микроконтроллер был специально изобретён, чтобы иметь возможность использоваться в самых маленьких устройствах. Это было сделано за счёт объединения в одной микросхеме всех элементов компьютера. Рассмотрим это на схеме:
Все вспомогательные устройства, такие как постоянное запоминающее устройство, оперативная память, таймер, последовательный интерфейс, порты ввода/вывода являются встроенными. Поэтому не возникает необходимости создавать интерфейсы с этими вспомогательными устройствами, и это экономит много времени для разработчика системы.
На текущий момент выпущено очень много различных микроконтроллеров — нижняя граница стоимости начинается с 20 рублей за штуку! Чтобы использовать микроконтроллер практически не нужны дополнительные компоненты (несколько конденсаторов, и если необходимо кварц). Подал питание — и все работает.
Как устроен любой микроконтроллер, основные модули
Практически все микроконтроллеры имеют следующие основные модули:
- CORE (ядро) — основной вычислительный модуль
- Memory (память)
- Flash memory (ПЗУ) — память для хранения программы
- RAM (ОЗУ) — оперативная память для проведения вычислений
- EEPROM (ПЗУ) — память для хранения данных
- UART
- SPI
- I2C
- CAN
- USB
Рассмотрим более подробно зачем нужен каждый модуль и какими возможностями он обладает.
Core and memory
Процессорное ядро — это основной модуль любого микроконтроллера (далее МК). Ядро определяет производительность процессора, разрядность регистров, управляет различными режимами работы МК.
Мы планируем программировать обычные микроконтроллеры (не DSP) на высокоуровневом языке программировать СИ, и в связи с этим, нам не важно какое ядро мы имеем, как оно работает внутри. Всю работу с ядром за нас делаем компилятор СИ. Именно он преобразует наши команды на языке программирования в машинный код. Какие же параметры ядра являются ключевыми для выбора микроконтроллера, и как они могут влиять на его работу?
Максимальная частота работы ядра
Для работы любого процессора необходима задающая частота — сигнал, который меняет напряжение с 0 (0 вольт) на логическую 1 (рабочее напряжение ядра). Именно в момент смены напряжения и происходят все вычисления. Момент изменения сигнала называется такт работы ядра МК, а количество тактов в секунду и есть частота работы ядра (измеряется в герцах). Можно грубо сказать, что данная частота определяет сколько простейших однотактных инструкций может выполнить микроконтроллер за 1 секунду. Например, 24Мгц — 24 миллиона инструкций в секунду. Здесь важно понимать, что речь идёт не об одной строчке кода на языке Си или операции деления, а об одной машинной операции. Все микроконтроллеры и микропроцессоры, в очень упрощённом варианте, работают примерно одинаково:
- ядро имеет набор регистров — очень быстрых ячеек памяти определённой разрядности в битах — например, 8бит, 16бит, 32бит
- любая программа — это последовательный набор машинных команд, которые записаны и хранятся в определённой области памяти МК (обычно FLASH памяти)
- в процессе работы, МК загружает машинные команды из памяти на конвейер (более быстрая память) и выполняет их последовательно
- каждая машинная команда в качестве операндов берет данные из внутренних регистров, то есть, чтобы сложить 2 числа, надо сначала их записать в разные регистры, а потом выполнить команду сложения (ADD).
Из этого описания становится понятно, что для того чтобы выполнить реальную строчку кода на СИ бывает необходимо выполнить несколько сотен машинных команд. В datasheet на МК обычно есть отдельный раздел посвящённый описанию сколько тактов занимает выполнение команд на Ассемблере, на СИ обычно эти данные не приводятся, так как очень сильно зависят от компилятора. Несмотря на такую сложность, максимальную частоту ядра все же можно считать некоторым показателем производительности ядра (Более общепризнанная единица производительности процессоров — MIPS, однако она тоже не является реальной мерой производительности). На текущий момент есть микроконтроллеры работающие на частоте 200МГц, в простых же задачах хватает и 1 МГц.
Как выбирать частоту микроконтроллера под проект? Самый простой ответ — чем больше тем лучше, однако с частотой растёт цена и энергопотребление процессора. Основной критерий выбора частоты — это необходимая частота обработки данных и сложность алгоритма их обработки. Например, если мы строим метеостанцию и будем опрашивать датчик раз в секунду, то скорее всего нам хватит 1МГц. А вот если мы делаем квадр о коптер и пересчитываем все его параметры по очень сложным алгоритмам 1000 раз в секунду, то необходимо около 100Мгц и более. Для обработки видео HD качества нужен уже процессор с частотой 1Ггц (микроконтроллер с этим не справится). Обычно этот параметр устанавливается опытным путём и берётся с запасом, чтобы была возможность поменять частоту в процессе работы и подобрать оптимальный режим загрузки МК и энергопотребления. Частоту можно программно сделать меньше максимальной. Для почти всех наших проектов частоты в 16Мгц более чем достаточно. На текущий момент практически все МК могут работать на такой частоте.
Разрядность регистров
Вы, наверное, уже слышали или читали, что например STM8 — 8-ми битный МК, а вот STM32 — 32-х битный МК. Тут как раз и идёт речь о разрядности центральных регистров МК. Разрядность регистров определяет сколько бит в одном регистре, а это в свою очередь говорит о том, сколько данных за один такт может участвовать в машинной команде. Чем больше разрядность МК, тем быстрее выполняется код для больших чисел, но тем меньше плотность машинного кода самой программы во Flash памяти МК. Что это значит?
Представим себе простую задачу, надо сложить два числа 10 и 5. Если перевести их в двоичную систему, то это будет 0b1010 и 0b101, то есть 4-х битное число и 3-х битное — результат будет не больше 5 бит. Соответственно, если у нас МК 8-ми битный, то все операнды помещаются в 8-ми битный регистр, и для сложения таких чисел будет одинаково затрачено тактов на любом МК с разрядностью больше 8-ми бит. Но вот если нам надо сложить два больших числа, например, 10 000 и 10, это уже займёт 14 бит, и на МК с разрядностью 8 бит будет выполняться за большее число тактов, будет необходим целый алгоритм (чтобы привести каждое число к 8-ми битам), а на 32-битном МК — за то же самое число тактов. Вы можете самостоятельно это все увидеть в любой среде программирования, которая показывает итоговый код на ассемблере. Таким образом, чем больше разрядность — тем быстрее можно оперировать большими числами. Однако, есть и обратная сторона медали, плотность кода. Для самой простой программы, записать 0 во внутренний регистр, надо потратить 2-е команды (2 байта) на 8‑ми битном МК и 2-е команды (8 байт) на 32-ух битном, так как все команды данные и команды имеют разрядность 32бита. Конечно, производители МК с этим борются, вводят дополнительные наборы команд меньшей разрядности и т. д.
Таким образом, разрядность показатель производительности и стоимости МК. Чем она выше, чем больше памяти имеет МК, тем больше возможностей у вас будет, но тем он и дороже. Для простых проектов более чем достаточно 8-битных МК (хотя по цене сейчас разрыв существенно снизился). Также, восьми битные микроконтроллеры имеют много других преимуществ — энергопотребление, более быстрая обработка прерываний, широкий набор периферии, очень большой выбор корпусов и самих микроконтроллеров. Все это надо учитывать при выборе МК под проект.
Архитектура ядра ARM
Когда появились первые микроконтроллеры, каждая компания изобретала свой МК, со своими протоколами отладки и ядром. Но эта ситуация в корне изменилась с приходом на рынок компании ARM Limited. Данная компания осуществила переворот в мире микроконтроллеров. Бизнесом компании ARM всегда была продажа лицензий на производство ядер и сопутствующих элементов полупроводниковым компаниям, которые уже в свою очередь создавали микропроцессоры и микроконтроллеры на их основе. То есть, сама ARM не делала микроконтроллеры, но она разрабатывала ядра для них! В итоге, на текущий момент, очень большое количество разнообразных 32-х и 64-х битных микроконтроллеров, различных производителей работают на одном ядре — ARM!
Общее ядро даёт общие механизмы работы с памятью, отладкой, программированием, механизмом прерываний и другим свойствами ядра. Производители микроконтроллеров сосредоточились на периферийных модулях. Равные конкурентные возможности сказались не цене микроконтроллеров. В настоящее время, нижние ряды 32-х битных микроконтроллеров ARM по стоимости почти равны нижнему ряду восьми битных микроконтроллеров. Также, это позволяет, например, использовать программатор ST-Link, или другие универсальные программаторы, для программирования большинства микроконтроллеров ARM, что расширяет круг выбора процессоров для проекта. Результатом работы ARM можно считать и наличие единых сред разработки для ARM микроконтроллеров — IAR, KEIL, Mbed, Eclipse и другие.
Оперативная память
Это самая быстрая память, кроме регистров, которая есть у МК. Все данные переменных хранятся в ней, правда только когда у МК есть питание. И чем больше у нас в программе переменных, массивов данных, которые нуждаются в обработке, тем больше оперативной памяти нам необходимо. Во всех МК в качестве оперативной памяти используется SRAM память, а она очень недешево стоит. Поэтому, чем больше памяти у МК, тем он дороже. Сколько памяти необходимо под проект? На этот вопрос очень трудно ответить, основной расход памяти это массивы и глобальные переменные. Любой компилятор СИ при сборке программы показывает затраченный объем памяти, поэтому программа написана, то можно посмотреть сколько необходимо памяти, но если её нет, то остаётся примерно прикинуть. Чем меньше разрядность МК, тем меньшее её обычно нужно. Например на 8-ми битных МК можно встретить 1кбайт оперативной памяти, и его хватает для простых программ. На 32битных бывает 196кбайт ОЗУ и на сложный проект её может не хватить.
Ответ все тот же — чем больше памяти у нас есть — тем дороже МК. Для простых проектов нужен минимальный объем. Чем больше у вас массивов, различных буферов под данные, тем больше нужно памяти. Работа со строками, тоже предполагает увеличенный размер памяти.
Flash память
Это специальная область памяти, которая является энергонезависимой. То есть, она сохраняется при отключении питания МК. Обычно в ней хранится программа или данные программы, которые меняются редко. Ресурс её перезаписи обычно ограничен, хоть и измеряется тысячами раз. Чем больше у нас этого вида памяти, тем более объёмную программу можно использовать в проекте. Это ваш жёсткий диск. Но опять же ограничение — это цена. При переходе на более высокую разрядность опять же объем доступной Flash растёт, но обычно та же самая программа занимает уже больше места. Например 8-ми битные МК имеют 8кб памяти, и это очень много. А 32-ух битные начинаются, как правило, с 32кб, и это не так уж много для них. На первых проектах нам будет хватать 8-ми битных МК с 8 кб на борту.
EEPROM — память данных
Это специальная область памяти, которая так же как и FLASH является энергонезависимой. Но обычно, она имеет гораздо больший ресурс перезаписи — сотни тысяч раз, она служит для хранения настроек программы, важных данных, и может перезаписываться в процессе работы программы.
Если вам нечего хранить, то можно об этом виде памяти не беспокоится. Если вы планируете хранить много данных в этом виде памяти, то её объем важен. Если данных совсем много, то необходимо использовать внешнюю память, в МК обычно этого вида памяти немного — до 10кб.
На этом мы закончим обзор параметров ядра и перейдём к другим модулям.
Как ядро взаимодействует с другими модулями
Мы познакомились с ядром микроконтроллера, кроме ядра, у МК много других модулей. Основная «сила» МК именно в широком наборе разнообразных модулей. Как же МК общается с ними? Ответ очень простой — через шину данных, ячейки памяти. Существует специальная область памяти в адресном пространстве МК, отвечающая за периферию и другие модули. Она точно так же состоит из регистров, но в данном случае — это внешние регистры, просто ячейки памяти по определенным адресам. Вот через них и производится работа с модулями.
Например, чтобы послать 1 байт данных по SPI интерфейсу необходимо записать этот байт в специальную ячейку памяти по определённому адресу, в регистр данных SPI. После этого, необходимо в другом регистре SPI установить определённый бит в 1, чтобы началась передача данных. Точно также работают все другие модули. С точки зрения нас, как разработчиков, необходимо записывать в определённый адрес памяти данные или менять биты, или считывать бит. Так, через память, производится работа с прочими модулями МК. В дальнейшем, мы будем работать с каждым модулем в реальных проектах, и подробно их изучим. Если вы собрались программировать МК, то вам просто необходимо подтянуть работу на СИ с битовыми операциями. Для экономии памяти, производители плотно набивают регистры, используя каждый бит.
Clock and power management
Это очень важный модуль. Он отвечает за энергопотребление МК и рабочую частоту ядра. В зависимости от модели МК, данный модуль может позволять менять частоту ядра прямо в процессе работы (например, МК от STM так умеют). Он позволяет задавать различные параметры спящего режима, отключать и включать ту или иную периферию для экономии энергии. Этот же модуль отвечает за работу МК от внешнего генератора частоты или внутреннего кварца. Модуль очень специфический для каждого МК, и все его параметры необходимо изучать в datasheet.
GPIO
Один из самых важных модулей МК. Остановимся на нем поподробнее.
GPIO — general port input output — порты ввода-вывода. Эта периферия отвечает за работу выводов микроконтроллера. Все выводы МК, кроме специальных (питание, GND), сгруппированы в ПОРТЫ, нумеруемые по буквам латинского алфавита PORT A PORT B PORT C. В зависимости от разрядности МК, может быть 8 выводов в одном порту, 16 или 32. За каждый порт отвечает соответствующий регистр, так, что каждый бит этого регистра отвечает за физический вывод МК. Структура регистров может отличаться у разных МК, но общее схематичное устройство выводов совпадает. Рассмотрим как оно выглядит на примере выдержки из datasheet на STM8. Вот схема одного вывода МК.
Разберём эту схему для понимания методики работы с выводами микроконтроллера. Во первых, обратим внимание на защитные диоды, как правило они есть у всех (но их может не быть). Их задача защитить вывод от отрицательного напряжения, превышения напряжения, статического напряжения и других неприятностей. К сожалению, микроконтроллеры очень маленькие, и всё внутри рассчитано на очень небольшие токи. Вы должны сразу запомнить, что выводы МК выдерживают токи не более 30 мА (точные данные смотри в datasheet) , а в случае превышения напряжения больше рабочего — ещё меньше — 2 мА . Во вторых, мы видим два транзистора, которые работают в ключевом режиме, и открыт может быть только один из них. Если открыт нижний транзистор, то вывод подключается к GND, и на нем мы наблюдаем логический 0. Если открыт верхний транзистор — то к VDD, и на выводе логическая 1.
Отдельно есть транзистор, который подключает вывод к VDD через резистор (около 50кОм). Такая схема подключения называется PULL-UP. Бывает такой же вариант, но с подключением резистора к GND, тогда это называется PULL-DOWN. При тако м подключении, мы имеем на выводе логическую 1, с малым током через резистор PULL-UP, пока закрыт нижний транзистор. Если же его открыть, то на выходе будет логический 0, потому что соединение к GND будет через меньшее сопротивление транзистора . Данная схема очень часто используется в схемах получения данных на выводе с кнопок или других датчиков.
Сам вывод может быть подключён к линии Analog Input — эта линия используется модулем ADC. Также, вы видите Триггер Шмитта на входе вывода. Он необходимо для того, чтобы можно было считать состояние вывода в логическом формате — 0 или 1.
Подведём итоги. Что можно получить с одного вывода МК?
- МК может выдать (режим OUTPUT) на выводе 0 или 1, если они идут через транзисторы — то это STRONG (сильные) 0 или 1
- МК может выдать 0 или 1 через резисторы PULL-UP-DOWN, в этом случае они называются WEAK (слабые) 0 или 1
- МК, через триггер Шмитта, может считать (режим INPUT) логическое состояние вывода — 0 там или 1
- МК может иметь на выводе неопределённое состояние (HIGH IMPENDANCE — Z), см. Three-state logic , когда ни один транзистор не включен.
- В ывод может быть подключен к системе прерываний, которая позволяет геренировать прерывание при смене состояния на входе данного вывода.
Также можно заметить, что выводом можно управлять напрямую, через регистр PORTx, или выводом может управлять периферийный модуль. Например, если на вывод подключён модуль UART RX, то вывод может работать как обычный вывод или как UART RX. Это называется альтернативная функция вывода. Производители МК стараются сделать работу выводов с альтернативными функциями как можно более гибкой. Например в STM32 есть возможность подключать UART и другие модули на несколько разных выводов, что упрощает разводку плат. Для того, чтобы не запутаться с выбором альтернативных выводов, производители выпускают специальные визуальные конструкторы, где можно назначить выводы в графической среде.
Для управления выводом обычно МК имеет следующие регистры (на примере STM8):
- ODR — output data registr — управление состояние вывода — 0 или 1 имеем на выводе
- DDR — direction data registr — направление вывода — вход или выход.
- CR1 CR2 — конфигурационные регистры, различные параметры выхода, PULL-UP резисторы и т.д.
- IDR — input data registr — считывание данных состояния вывода в цифровом формате 0 или 1
Стоит отметить, что в некоторых МК, если вывод находится в OUTPUT режиме, то все равно можно считать данные на нем через IDR регистр. Это можно использовать например для общения по протоколу 1-Wire.
Что можно делать с логическим 0 или 1 на выводе? Зачем это нужно? Самое простое, что приходит в голову — можно светить светодиодом. Если собрать такую схему:
То если подать на вывод 0 — светодиод не горит, 1 — горит. Дальше мы найдём более широкое применение выводам МК.
ADC и DAC
Аналого-цифровой преобразователь АЦП, англ. Analog-to-digital converter, ADC — устройство, преобразующее входной аналоговый сигнал в дискретный код (цифровой сигнал). Обратное преобразование осуществляется при помощи цифро-аналогового преобразователя (ЦАП, DAC). Если вы знакомы с Arduino, то как раз функция AnalogRead и работает через ADC.
Основные параметры ADC
ADC очень важный периферийный модуль в МК. По своей сути, он превращает МК в цифровой вольтметр, и позволяет измерить сколько вольт у нас находится в данный момент времени на определённом выводе МК. Как правило, в МК один модуль ADC имеет несколько каналов (10-16), которые распределены по разным выводам МК, они обозначаются ADC1 ADC2 … ADC10. Также, МК может иметь несколько независимых модулей ADC (в том время как каналы являются зависимыми, сам модуль один, просто на входе стоит мультиплексор, который подключает нужный канал к модулю). Что выдаёт нам этот модуль на выходе? Как по этому значению определить сколько вольт мы имеем на выводе МК? Зачем нам надо знать сколько у нас вольт, какая от этого польза?
ADC измеряет напряжение в диапазоне от 0В до напряжения питания МК или до напряжения на специальном выводе МК — AREF — analog reference. Одним из основных параметром ADC является его разрядность, то есть максимальное количество дискретных значений, которое он может выдать на всем диапазоне входного аналогового сигнала.
Например, если разрядность ADC равна 10, напряжение питания МК равно 3В, то ADC может выдать числа от 0 до 9. Все ADC являются линейными, то есть выходное число линейно зависит от напряжения. Это значит, что одно выдаваемое деление будет соответствовать 3В/10, что составляет 0.3В. В данном примере 0.3В называется Разрешением ADC (минимальное изменение величины аналогового сигнала, которое может быть преобразовано данным ADC).
Разрядность обычно является степенью числа 2, и о разрядности принято говорить как о количестве бит в числе представленном степенью числа 2. Например, 3-х битный ADC имеет разрядность = 8. К сожалению, все ADC имеют погрешность, и это необходимо учитывать при построении программы и выборе нужного модуля по параметрам.
Ещё одним важным параметром ADC является скорость одного измерения. Чем выше разрядность, тем ниже скорость. Обычно скорость одного измерения составляет несколько микросекунд. Как мы уже сказали выше, каналы в ADC, как правило, не являются независимыми. Это все создаёт свои проблемы при проектировании схем для работы с этим модулем. Сейчас мы не будем подробно рассматривать эти сложности. Мы вернёмся к ним, когда будет делать соответствующие приборы.
Как можно использовать ADС
Основное назначение этого модуля — преобразование сигналов с аналоговых датчиков в цифровой формат. Рассмотрим простую схему.
В данной схеме мы имеем NTC-термистр R2, который подключён к выводу МК. Вместе с резистором R1 он составляет делитель напряжения. В зависимости от изменения температуры, будет меняться его сопротивление и на выводе МК будет меняться напряжение, согласно схеме делителя. Измерив получившееся напряжение с помощью ADC, можно рассчитать сопротивление резистора R2 и по нему температуру. Таким образом, мы можем узнать температуру в градусах и оперировать ей в нашей программе. Еще одно применение ADC — считать состояние переменного резистора. Он тоже является делителем напряжения. В данном случае считанное значение позволит определить сопротивление резистора, а значит, положение его ручки. Так можно использовать резистор в приборе — регулировать громкость, скорость вращения и другие параметры в нашей программе.
К сожалению, ADC встроенные в МК обладают низким разрешением (10-16 бит) и невысокой точностью. Но даже таких ADC хватает для большого количества задач связанных с получением информации с датчиков. Когда нужно более точное измерение, используется внешний ADC. Например, для измерения температуры термопары мы будем использовать очень точный внешний 24-х битный сигма-дельта ADC.
Выбирая МК в проект, надо внимательно смотреть на параметры ADC. Сейчас есть МК и с сигма-дельта ADC на борту, правда стоят они дорого.
Назначение модуля DAC
Данный модуль встречается в МК не так часто как ADC. Основное его назначение — это генерация аналогового сигнала на выходе МК, например звука. Аналоговый сигнал можно использовать для управления другими аналоговыми участками схемы. Он обладает такими же основными параметрами — разрядность и разрешение, только все работает наоборот. Мы записываем нужную цифру в регистр DAC в программе МК, а на выводе устанавливается соответствующее этой цифре напряжение.
Timers
Без всякой скромности можно сказать, что это главный модуль МК (после ядра конечно). Таймер — это что-то связанное со временем, подумаете вы. И будете почти правы. В любой программе на МК все привязано к временным интервалам, и умение измерять время просто необходимо. С точки зрения устройства, таймер — это простой счётчик, который с каждым тактом МК (или выделенной для таймера частоты) может или расти на 1 или уменьшаться на 1. Зачем нужен этот счётчик, как этим всем воспользоваться?
Допустим частота работы МК 8МГц, значит 1 такт длится 125 наносекунд (1/8 000 000). Если в начале запуска счётчика его значение было равно 0, то когда там будет 8 000 000, то пройдёт ровно 1 секунда. Так микроконтроллер может измерять время. Таймер — это один из самых сложных модулей по возможностям настройки. Сейчас мы познакомимся лишь с общими принципами работы этого модуля.
Первый параметр таймера — это разрядность, максимальное число до которого может считать счётчик. Оно также обозначается количеством бит, которое выделено под ячейку памяти счётчика. Например, 8-ми битный таймер может считать от 0 до 256, 16-ти битный от 0 до 65536. В основном в МК вы встретите 8, 16, 32 битные таймеры. Для большей гибкости при работе с таймером производители добавили второй регистр, который называется Предделитель. Предделитель считает от заданного числа до 0, и когда достигает 0, то на 1 изменяется основное значение таймера. То есть он как бы делит частоту таймера. Таким образом, использование предделителя позволяет расширить диапазон счётчика таймера до значения РазрядностьТаймера * Предделитель. В предыдущем примере, чтобы считать секунды можно задать предделитель 8000, и тогда 1 значение счётчика таймера будет равно 1 миллисекунде, а 1000 в нашем счётчике наступит когда пройдёт 1 секунда.
Основные события при работе таймера
При работе с таймерами обычно используются прерывания. Прерывания возникают по определенным событиям. Рассмотрим какие события могут возникать при работе с таймерами.
- Обновление таймера, переполнение таймера
- Сравнение таймера с определенным числом
- Входящее событие — таймер может использоваться для анализа входящего сигнала, в этом случае считается время между изменениями сигнала на выводе с 0 на 1 или наоборот.
Самый просто вариант таймера — считающий вниз таймер. Работает он так. В специальный регистр настройки ARR (auto-reload-registr — регистр автообновления) записывается значение счётчика, с которого начинается таймер. По достижению счётчиком 0, срабатывает прерывание ОбновлениеТаймера, в счётчик опять записывается значение из ARR, и все продолжается дальше.
Точно также работает считающий вверх таймер, от 0 до ARR, потом срабатывает прерывание Переполнения и счётчик обнуляется.
Ещё один вариант таймера с использованием регистра ARR — выровненный по центру таймер, счётчик вверх и в низ.
Второй регистр настройки таймера CRR (capture compare registr — регистр захвата и сравнения), позволяет сформировать прерывание по сравнению значения таймера со значением регистра CRR. Используется обычный таймер считающий вверх, просто при достижении значения CCR срабатывает дополнительное прерывание.
При работе со входными событиями, при изменении состояния входа, срабатывает прерывание, и в число из регистра CRR будет соответствовать времени прошедшему от начала таймера.
Самое главное, что этот модуль никак не «загружает» ядро. После старта, таймер работает параллельно ядру, сам по себе, и только генерирует нужные прерывания, а также меняет значения регистров.
Примеры использования таймеров
В любом МК, как правило, очень много таймеров. Например, в старших моделях их число доходит до 20 и более. Также у каждого таймера есть независимые каналы, которые по сути имеют свои значения счётчиков и всех настроек. Они все необходимы, так как в большой сложной программе, очень много процессов отмеряется временными интервалами. Рассмотрим, что можно делать с помощью таймеров.
- Организовать счётчик точных временных интервалов. Например мы можем завести переменную miliss, в которой будет храниться количество миллисекунд, прошедшее с включения МК. Запускаем самый просто таймер и так задаём ARR и предделитель, чтобы прерывание срабатывало 1 раз в миллисекунду. В теле прерывания добавляем 1 к переменной miliss. Теперь у нас есть счётчик миллисекунд, и мы можем мигать с нужной частотой светодиодом, и обрабатывать как нам необходимо миллисекундные интервалы.
- Декодировать входные сигналы с датчиков, измеряя длину импульсов. С помощью входящего таймера можно измерять время между импульсами с нужной точностью.
- По событиям таймера, через определённые настройки, МК может менять состояние выводов с 0 на 1. Таким образом, можно без всяких прерываний и программ можно мигать светодиодом с нужной частотой — 1 раз в секунду.
- Таймеры можно связывать в цепочки. Событие одного таймера стартует другой таймер. Это позволяет делать сложные замеры времени между разными входными сигналами на разных выводах МК.
- Таймеры могут инициализировать работу другой периферии. Например по событию таймеру можно проводить замер напряжения модулем ADC. Так мы получим измерения напряжения через равные интервалы времени или в нужные моменты времени.
- С помощью таймеров можно синхронизировать разные события. После нажатия кнопки, через 3сек зажечь светодиод.
- Используя регистр CRR можно с помощью таймера генерировать PWM (ШИМ — широтно импульсная модуляция) сигнал. Делается это очень просто. При обнулении таймера, мы на выводе устанавливаем 1, при сравнении 0. Получается такой сигнал. (Он очень важен, и позволяет получить некий аналог DAC на выводе, что в свою очередь позволяет управлять яркостью светодиода, скорость мотора, через специальный драйвер)
Таймер и кварцевый резонатор
В качестве генератора частоты работы МК может использоваться внутренняя RC цепочка или внешний кварцевый резонатор или кварцевый генератор. К сожалению генератор на основе RC цепочки очень неточный, погрешность составляет 10% и более. С изменением температуры она растёт. Если на основе такого генератора делать например часы, то они будут все время убегать вперёд или отставать. Получить точное измерение времени не получится. Использование кварцевого резонатора решает эту проблему. Они имеют очень высокую точность, погрешность измеряется в процентах на 1 000 000 тактов (ppm). Их точность не падает с нагревом или охлаждением.
Вы должны запомнить, что если вам необходимо точное измерение временных интервалов, то использование внешнего кварца или генератора необходимо!
Comunications interfaces
Для того, чтобы соединить вместе различные приборы, модули, микросхемы, было придумано большое количество цифровых (передаётся 0 или 1) интерфейсов, шин данных. Какие-то интерфейсы «умерли», а какие-то живут и широко используются по сей день. Некоторые из них настолько стали популярны, что производители микроконтроллеров стали добавлять их поддержку в виде отдельных периферийных модулей. В данном разделе коротко рассмотрим эти модули, что они могут, что дают, как ими пользоваться.
С точки зрения выбора микроконтроллера, вы должны понимать, что любой интерфейс можно запрограммировать в коде МК, и для этого ненужен отдельный периферийный модуль, достаточно модуля GPIO и таймеров (эта техника называется дрыгать ногами). Однако, безусловно, если вам в проекте необходим обмен по данным интерфейсам, необходимо выбирать МК, который имеет на «борту» поддержку всех необходимых шин данных. В отличие от программы в МК, работа модулей производится независимо от центрального процессора и не загружает процессор, вам остаётся только обрабатывать прерывания и пользоваться готовыми интерфейсами.
Вот самые распространённые интерфейсы, которые встречаются в МК:
- UART — Universal Asynchronous Receiver-Transmitter — Универсальный асинхронный приёмопередатчик
- SPI — Serial Peripheral Interface — последовательный периферийный интерфейс, шина SPI
- I2C — Inter-Integrated Circuit — интегрированная шина
- CAN — Controller Area Network — сеть контроллеров
- USB — Universal Serial Bus — универсальная последовательная шина
Более подробно интерфейсы взаимодействия будут рассмотрены в других статьях. Здесь мы только приведём способы подключения каждого интерфейса и варианты использования.
UART
Это очень широко используемый интерфейс. Родился он от протокола RS-232, но в настоящее время его возможности гораздо шире. Основные линии данных в нем — RX (чтение данных) и TX (передача данных). Общение по этому интерфейсу идёт асинхронно (может и синхронно) — то есть независимо, во время приёма данных, можно их передавать и наоборот. В данном интерфейсе нет задающей линии CLOCK. Все данные передаются на согласованной частоте.
В отсутствие потока данных на линии передаётся логическая 1. Данные передаются пакетами согласованной длины. Стартовый бит всегда является логическим 0. Он обозначает начало передачи пакета данных. Далее передатчик передаёт данные через равные промежутки времени. В конце посылки может передаваться контрольный бит чётности, для проверки корректности посылки. К сожалению, временные интервалы на разных сторонах могут оказаться разными. Важно, чтобы они не разошлись сильно хотя бы в рамках одного пакета(обычно 8-9 бит). Это основной минус этого интерфейса — частота должна отличаться не более чем на 3% (а лучше 1,5%). Поэтому, если используете этот интерфейс, то лучше сразу позаботиться о кварцевом резонаторе на обеих сторонах, хотя если вы будете работать с прибором в комнате, будет работать без резонатора (основное изменение внутренней частоты происходит из-за смены внешней температуры). Частоту интерфейса принято обозначать в виде скорости отправленных байт, например 9600 байт в секунду. Плюсом интерфейса являются только 2 задействованные сигнальные линии.
Данный интерфейс часто используется для:
- передачи данных между компьютером (например прибор USB\UART)
- общения с GPS, GSM модулями
- загрузки прошивки в МК через bootloader
- отладки работы программы
С точки зрения программирования МК, для обмена по этому интерфейсу, все очень просто. Необходимо настроить интерфейс на нужную скорость, определить прочие параметры. А дальше, записываете байт в специальный регистр и включаете передачу, периферия сама сформирует пакет битов, добавит бит чётности и т. д. Точно также при получении данных. Включаете режим получения, периферия получит байт, проверит чётность и поместит его в специальный регистр, останется в МК прочитать его. В СИ есть функция для форматирования строк Printf, очень часто она используются вместе с этим интерфейсом. Таким образом, МК может передавать текст на компьютер, и общаться с вами в специальной программе «Терминал».
SPI
Последовательный интерфейс с поддержкой очень высоких скоростей передачи данных — до 30Мгц. Отметим также, что этот интерфейс прост в использовании. Он имеет 3 сигнальные линии:
- Clock — тактовая частота — по этой линии передаётся тактовый сигнал, clock обеспечивает master, главный
- MISO — master input slave output — вход главного модуля
- MOSI — master output slave input — выход главного модуля
По данному интерфейсу обмен может проводится с несколькими устройствами, достигается это за счёт дополнительных выводов CS (chip select) на каждый модуль. Низкий уровень сигнала на выводе CS, означает начало работы с данным модулем. Если у нас, например, на шине SPI три устройства, то надо будет три вывода CS — по одному на устройство. Если у нас одно устройство, то вывод CS все равно нужен, так как он определяет начало и конец обмена данными, сэкономить тут не получится.
Получение данных возможно одновременно с передачей.
Большой плюс данного интерфейса — устойчивость к изменению частоты, она может меняться даже в процессе работы, и вообще может быть любой, важно только не превышать максимальные скорости обозначенные в datasheet.
Если вы выбираете какой-то датчик для проекта, то лучше выбирать датчик на шине SPI. На этой шине работает очень много датчиков, LCD экраны, микросхемы памяти.
I2C
Очень интересная шина данных. Ее преимущество в том, что используется всего 2 провода. При этом на этих двух проводах может быть подключено много устройств.
Интересно то, что каждое устройство может стать мастером в любой момент времени (но это редко используется из-за сложности алгоритма интерфейса). Для построения шины используют 2 вывода — SDA (данные) и SCL (тактовая частота). Частота может быть выбрана из предопределённых — 100 кГц, 400 кГц, 3мГц (не все устройства поддерживают эту частоту). Использовать меньшую частоту можно, превышать не рекомендуется. Данный интерфейс очень сложный с точки зрения программы в МК. Даже имея готовый модуль периферии I2С, разработчики часто сталкиваются с конфликтными ситуациями при работе с этой шиной. Основной причиной этого является очень сложный алгоритм работы шины, который в идеале имеет большое количество исключений. Не все модули полностью обрабатывают нештатные ситуации, и это приводит к конфликтным ситуациям на шине.
В datasheet на МК обычно подробно описан механизм работы с шиной в режиме прерываний или при работе в основном цикле программы. Стоит отметить, что работа через прерывания гораздо проще, но требует довольно высокого приоритета прерываний на эту шину. Работа в основном цикле сложна и требует перебора различных ситуаций при получении данных.
Каждое устройство на шине должно иметь уникальный адрес. Для различных датчиков, обычно он программируется на заводе, и не подлежит изменению — имейте это ввиду, когда покупаете микросхему. Отметим также, что эта шина часто называется по-разному (из-за того, что изначально она лицензировалась компанией Phillips) — TWI, SCCB, SMBus.
Данная шина часто встречается в датчиках, так как это позволяет расширять набор датчиков за счёт одной шины. Также она встречается при работе с памятью (в основном ПЗУ), image sensors (камеры), бывает даже в датчиках GPS (хотя там в основном UART).
CAN
Данная шина была специально разработана для объединения в единую сеть различных датчиков и исполнительных устройств. Она нашла своё применение в системах «умный дом», автомобильной промышленности, в промышленной автоматизации. Передача данных идёт по двум проводам CAN RX и CAN TX.
Для доступа к шине, кроме самого МК необходимы микросхемы драйверы, который переносят логику МК на физический уровень шины (это может быть другое напряжение или специальная технология передачи данных, например оптоволоконная линия).
Протокол обмена по данной шине содержит подробное объёмное описание. Передача данных ведётся кадрами, которые принимают все устройства. Каждый кадр состоит из идентификатора и пакета данных. Идентификатор говорит о содержимом пакета и его приоритете, приоритет используется при разрешении коллизии при одновременной передаче данных разными узлами.
Данную шину рекомендуем использовать только там, где это действительно требуется. Конечная реализация устройства на данной шине будет не дешёвым, за счёт драйверов, их обвязки и т. д. С другой стороны следует отметить, что данная шина на физическом уровне имеет очень высокую помехоустойчивость и ряд других преимуществ:
- Возможность работы в режиме жёсткого реального времени.
- Простота реализации.
- Арбитраж доступа к сети без потерь пропускной способности.
- Надёжный контроль ошибок передачи и приёма.
- Широкий диапазон скоростей работы.
- Большое распространение технологии, наличие широкого ассортимента продуктов от различных поставщиков.
USB
Этот интерфейс настолько распространён, что известен всем. На текущий момент это основной интерфейс подключения периферийных устройств к персональному компьютеру. Если вам необходимо подключать устройство к компьютеру, то вам надо выбирать МК, имеющий данный интерфейс.
Передача данных в USB осуществляется по 2 проводам D+ и D-. Используется дифференциальная сигнальная линия. Шина постоянно разливается, на текущий момент есть стандарт USB 3.0, готовится USB 3.2.
Сам протокол описывать смысла не имеет, спецификация на него очень сложная и многостраничная. Спасает положение дел наличие у производителей МК готовых библиотек для работы по этому протоколу. Как МК может использовать шину USB:
- Для прошивки — DFU (device firmaware update) стандарт прошивки по USB все чаше встречается в МК. Наличие такой возможности у МК сильно упрощает прошивку — подключаете прибор в компьютер и видите внешний диск, просто копируете туда прошивку и все готово.
- Для организации COM порта и передачи любых данных на компьютер.
- Организация устройств ввода — мышка, клавиатура, джойстик, какие-то новые устройства ввода.
- USB audio устройство — ваше устройство может проигрывать звук с компьютера или получать его.
- Mass storage device — внешний диск — ваше устройство может давать доступ к флеш карте или внутренним данным, сразу представляя их в виде файлов.
- USB OTG — вы можете подключать к вашему устройству флешки и другие накопители, звуковые карты и другие устройства также как к компьютеру.
Безусловно это очень удобный и мощный интерфейс, и самое главное, требующий минимальных внешних компонент. Если у вас планируется тесное взаимодействие с компьютером, то следует выбирать МК, который имеет эту периферию. Единственный минус USB интерфейса — сложность программирования обмена данных по этому протоколу.
DMA
Данная аббревиатура переводится как прямой доступ к памяти. Как мы уже писали выше, любая периферия представлена в МК как ячейка памяти, поэтому в любой программе у вас будет очень много операций копирования информация из одной ячейки в другую. Представим, что нам необходимо получить данные с одного интерфейса, например UART, и отправить их на другой интерфейс, например SPI. Вам придётся прочитать данные из регистра UART и поместить их в регистр SPI, сделать все это в момент получения данных по UART. При этом МК будет занять выполнением этой программы. Вот для того, чтобы разгрузить МК от выполнения таких операций, и была разработана периферия DMA. С помощью этого модуля вы можете настроить копирование области памяти в другую область по событию. Набор событий очень широкий. Таким образом, если за событие взять получение данных по UART, далее настроить копирование данных по адресу UART в адрес SPI, то мы решим данную задачу полностью без участия МК.
Использование данной периферии очень сильно разгружает процессор, особенно при передаче больших массивов данных. Примеры применения DMA:
- Копирование данных полученных, с ADC или другой периферии, сразу в ячейку памяти. Вам остаётся только работать с некоей переменной в Си, там всегда будут свежие данные датчика.
- Копирование буфера в периферию, даже с побайтным разделением. Например необходимо передать 100байт по SPI, это можно сделать с помощью DMA.
- Получение данных с периферии с наполнением кольцевого буфера. Получаем данные с UART и кладем сразу в буфер.
- Передача изображения на экран из буфера.
- Копирование одного массива памяти в другой.
Если вы планируете работать с большими массивами данных, или вам нужна быстрая обработка сигналов без участия прерываний, то наличие DMA необходимо.
Прочая периферия
Микроконтроллеры постоянно развиваются, и их производители добавляют все новые возможности за счёт периферийных модулей. На текущий момент есть МК, которые имею цифровой видео интерфейс HDMI и позволяют подключаться к ТВ и мониторам. Есть периферия для передачи звука по интерфейсу SPDIF, I2S, AC97. Управление TFT матрицами. МК имеют специальный модуль для работы с различной внешней памятью FMC (NAND flash, SDRAM, SRAM). Могут выходить в сеть — Ethernet интерфейс тоже на борту. Перечислять можно долго. Подбор МК под проект становится все более сложной задачей.
Самый простой способ познакомится с новой периферией – посмотреть топовые МК от различных производителей. Как правило, более новые МК содержат всю ту же периферию, что и младшие МК. Так можно быстро познакомиться с новыми возможностями.
Интерфейс программирования
Для разработки программы для МК используется персональный компьютер. Чтобы передать полученную программу (прошивку) на МК необходим специальный прибор — программатор. А для его работы, МК должен иметь специальный интерфейс программирования. Когда вы разрабатываете сложную программу, часто необходимо видеть, что содержится в переменных, как работает программа, какие условия выполняются. Тут на помощь приходит специальный прибор — отладчик и соответственно интерфейс отладки.
Если вы решили работать с определенным видом МК, вы должны будете приобрести или сделать самостоятельно, как минимум программатор, а ещё лучше отладчик. Наличие схем таких приборов или их низкая стоимость, снижает порог вхождения в данную группу МК. Прежде чем приобретать микроконтроллер, вам надо озаботится о том как вы будете его программировать.
Каждый производитель старается сделать самый лучший и удобный интерфейс отладки и программирования, поэтому все они разные. К сожалению на данный момент нет одного универсального отладчика, программатора всех видов МК.
С прошивкой дела обстоят немного проще. Производители стараются сделать процесс загрузки прошивки более универсальным. В микроконтроллеры в специальную область памяти встраиваются мини программы Bootloader, загрузчики прошивки. Они работают по широко распространненым универсальным интерфейсам. Сами используемые это:
- UART — последовательный интерфейс.
- USB.
- CAN шина, есть МК которые можно прошивать по CAN шине, очень удобно для обновления прошивки в машине, в труднодоступных устройствах.
Если у вас есть такая возможность, обязательно надо планировать и использовать возможность загрузки прошивки в ваше устройство по стандартным интерфейсам.
А вот с отладкой все немного хуже. Самые распространённые интерфейсы отладки:
- JTAG — используется 5 сигнальных линий, AVR, многие ARM МК.
- SWIM — используется одна сигнальная линия, только МК STM8, иногда нужен RESET, если планируется программировать МК в спящем режиме.
- SWD — общий протокол для ARM микроконтроллеров, использует 2 линии.
- ICSP для МК PIC — PICKIT — свой протокол, свой прибор. Использует 3 линии.
- ISP — программатор по порту SPI. Используется в AVR. Используется 4 линии.
Здесь перечислены не все интерфейсы, и общее правило простое — под каждый МК нужен свой программатор отладчик.
Все наши проекты, которые мы будем делать, мы будем сопровождать необходимыми программаторами. Их схемы и инструкции по изготовлению смотрите на нашем сайте.
Производители микроконтроллеров и основные классы
Микроконтроллеры производит очень много компаний. Все их перечислять смысла нет, так как не все можно купить на нашем рынке. Перечислим только наиболее распространённые серии МК и их производителей.
- MSP430 — TI
- PIC — Microchip
- AVR — Atmel
- ARM — много производителей
- STM8 STM32 — STMicroelectronics
- C8051Fxx, EFM32xx, Precision32 — Silicon Labs
- LPCxxx ARM — NXP Semiconductors
- NuMicor ARM — NUVOTON
Производителей МК очень много, их параметры сильно отличаются друг от друга. Каждая серия МК имеет свою среду программирования, свои наборы регистров. Можно сказать, что это большой зоопарк. В наших проектах мы специально будем использовать разные МК, которые наиболее распространены на нашем рынке. У нас будут проекты на:
Скорость выполнения цикла исполнения инструкций измеряется в мегагерцах или гигагерцах
Информационные технологии сегодня проникают во все сферы нашей жизни. Продвижение новых компьютерных технологий и постоянное увеличение производительности оборудования вызывают интерес к вопросам измерения времени выполнения операций. Одним из важных параметров процессора является тактовая частота, которая измеряется в герцах (или в ее кратных величинах — мегагерцах и гигагерцах).
Цикл инструкции представляет собой последовательность операций, выполняемых процессором за один такт. Время выполнения цикла инструкции определяется подсчетом количества тактов, затраченных на выполнение всех операций в нем. Измерение времени выполнения цикла инструкции в герцах позволяет оценить производительность процессора.
Измерение времени выполнения цикла инструкции в мегагерцах или гигагерцах является более удобным способом, так как процессоры с высокой тактовой частотой имеют большую производительность. Для этого необходимо знать количеству тактов, затраченных на выполнение цикла инструкции, и делить его на частоту процессора. Например, если цикл инструкции занимает 10 тактов, а частота процессора составляет 2 ГГц, то время выполнения цикла инструкции составит 5 наносекунд.
Измерение времени выполнения цикла инструкции в мегагерцах или гигагерцах имеет большую точность и позволяет проводить сравнение различных процессоров по их производительности. Более высокая тактовая частота позволяет выполнять операции быстрее, что приводит к увеличению общей производительности системы.
Измерение времени выполнения цикла инструкции
Введение
Измерение времени выполнения цикла инструкции является важной задачей для оптимизации программного кода. Это позволяет исследовать производительность программы и определить узкие места, которые могут быть оптимизированы.
Почему измерять время выполнения цикла инструкции?
Измерение времени выполнения цикла инструкции позволяет программисту определить, сколько времени занимает выполнение одной итерации данного цикла. Это особенно полезно при работе с большими объемами данных или при высокоинтенсивных вычислениях.
Как измерить время выполнения цикла инструкции?
Для измерения времени выполнения цикла инструкции можно использовать различные инструменты и методы. Одним из наиболее распространенных является использование функции времени в программном коде. Например, в языке C++ для измерения времени выполнения цикла инструкции можно использовать следующий код:
#include #include int main() < // Инициализация переменных int iterations = 1000000; int sum = 0; // Начало измерения времени auto start = std::chrono::high_resolution_clock::now(); // Цикл инструкции for (int i = 0; i < iterations; i++) < sum += i; >// Конец измерения времени auto end = std::chrono::high_resolution_clock::now(); // Вычисление времени выполнения auto duration = std::chrono::duration_cast(end - start).count(); // Вывод результатов std::cout
Анализ результатов
Полученные результаты позволяют определить сколько времени занимает выполнение цикла инструкции и сравнить его с другими участками кода. Для более точного анализа результатов можно провести несколько измерений и усреднить полученные значения. Также можно использовать специальные профайлеры и отладчики, которые позволяют более подробно исследовать производительность программы.
Вывод
Измерение времени выполнения цикла инструкции является важной задачей для оптимизации программного кода. Это позволяет определить узкие места и улучшить производительность программы. Важно помнить, что результаты измерения могут зависеть от различных факторов, таких как аппаратная архитектура, загруженность системы и оптимизации компилятора.
Методы измерения цикла инструкции
Измерение цикла инструкции – одна из основных задач при анализе производительности процессора или микроконтроллера. В данном контексте под циклом инструкции понимается время, требуемое для выполнения одной инструкции процессором.
Измерение цикла инструкции является сложной задачей, так как для получения достоверных результатов необходимо учесть множество факторов, таких как внутренняя архитектура процессора, режим работы, наличие кэш-памяти и других элементов, влияющих на производительность.
Существуют различные методы измерения цикла инструкции, которые можно разделить на две основные категории:
- Методы анализа кода программы.
- Методы использования аппаратных средств.
Методы анализа кода программы позволяют оценить число циклов инструкции на основе анализа исходного кода программы. Данный метод основан на предположении, что каждая инструкция имеет фиксированное число циклов выполнения. Однако в реальности это не всегда верно, так как современные процессоры часто имеют внутреннюю сложную микроархитектуру, которая может изменять число циклов в зависимости от множества различных факторов.
Методы использования аппаратных средств позволяют измерить фактическое число циклов инструкции на работающем процессоре. Для этого используются специальные устройства, такие как логический анализатор или осциллограф. Данные методы требуют некоторой сложной инструментальной базы и обладают высокой точностью измерений, но их применение может быть затруднено в некоторых случаях, например, при работе с встроенными системами.
В результате измерения цикла инструкции можно получить информацию о производительности процессора и использовать ее при оптимизации кода программ. Данные методы являются важным инструментом для разработчиков программного обеспечения и позволяют повысить эффективность работы на различных аппаратных платформах.
Мегагерцы и гигагерцы в измерении времени
Мегагерцы (МГц) и гигагерцы (ГГц) употребляются для измерения частоты цикла инструкции в секунду. Частота цикла инструкции может быть показателем производительности компьютерной системы или микросхемы.
Мегагерц — это единица измерения, обозначающая миллион циклов инструкции в секунду. Например, компьютер с частотой 2 МГц выполняет 2 миллиона циклов инструкции в секунду.
Гигагерц — это единица измерения, обозначающая миллиард циклов инструкции в секунду. Она используется для измерения более высоких частот. Например, компьютер с частотой 3 ГГц выполняет 3 миллиарда циклов инструкции в секунду.
Информация о частоте цикла инструкции может быть полезна для определения быстродействия компьютера и сравнения его с другими системами. Чем выше частота цикла инструкции, тем быстрее может выполняться обработка данных.
Несмотря на то, что мегагерцы и гигагерцы могут быть полезными для измерения производительности, они не являются единственным фактором, влияющим на скорость работы компьютера. В качестве дополнительных факторов можно учитывать такие параметры, как количество ядер процессора, объем оперативной памяти и скорость шины данных.
При выборе компьютерной системы или микросхемы стоит обратить внимание на частоту цикла инструкции, но также учитывать и другие параметры, чтобы получить максимальную производительность в рамках задач, которые будут выполняться на данной системе.
Влияние цикла инструкции на производительность
Цикл инструкции — это основной блок работы процессора, включающий одну или несколько команд, выполняемых последовательно. Время выполнения цикла инструкции является ключевым показателем производительности процессора и определяет его скорость работы.
Чем меньше время выполнения цикла инструкции, тем быстрее процессор может выполнять задачи и обрабатывать данные. Однако, сокращение времени цикла инструкции не всегда приводит к увеличению производительности в целом.
Одна из основных причин связана с так называемым «конвейерным эффектом». При ускорении выполнения цикла инструкции процессор может начинать выполнять следующую инструкцию до завершения предыдущей. Если выполнение предыдущей инструкции затягивается, то процессор будет простаивать до её завершения. Таким образом, сокращение времени цикла инструкции может привести к увеличению простоев процессора и, как следствие, снижению производительности.
Взаимосвязь между циклом инструкции и производительностью также зависит от архитектуры процессора и оптимизации кода программы. Разные процессоры имеют разный размер цикла инструкции, что влияет на их работу. Так, процессоры с более коротким циклом инструкции могут обрабатывать больше инструкций за определенное время и, следовательно, быть более производительными.
Оптимизация кода программы также влияет на производительность. Использование оптимизированных алгоритмов, избегание излишнего повторения инструкций и другие методы оптимизации помогают сократить время выполнения цикла инструкции и повысить производительность процессора.
В итоге, влияние цикла инструкции на производительность является комплексным и зависит от множества факторов. Уменьшение времени выполнения цикла инструкции положительно сказывается на производительности, однако, необходимо учитывать конвейерный эффект и оптимизацию кода программы.
Особенности измерения времени выполнения в различных архитектурах
Измерение времени выполнения цикла инструкции является важной задачей при оптимизации программного кода и анализе производительности системы. Однако, процессы измерения времени выполнения могут отличаться в различных архитектурах компьютеров, что необходимо учитывать при проведении таких измерений.
В современных компьютерных системах наиболее распространенные способы измерения времени выполнения включают следующие:
- Измерение процессорным таймером. В этом случае используется встроенный процессорный таймер, который предоставляет информацию о прошедшем времени. Для измерения времени выполнения цикла инструкции необходимо записать значение таймера до и после выполнения цикла, а затем вычислить разницу между этими значениями.
- Измерение с помощью специальных инструкций. Некоторые процессоры предоставляют специальные инструкции, которые позволяют измерить время выполнения определенных участков кода. Например, инструкция RDTSC в процессорах Intel позволяет получить значение 64-битного счетчика процессорного времени. Однако, такие инструкции могут быть недоступны на некоторых архитектурах.
Необходимо отметить, что измерение времени выполнения цикла инструкции может быть неточным из-за различных факторов, таких как изменение тактовой частоты процессора во время измерений, кэширование данных или конкуренция за ресурсы процессора со стороны других процессов.
Кроме того, измерение времени выполнения может иметь различную точность в различных архитектурах. Например, процессоры семейства x86 обычно предоставляют достаточно точные счетчики процессорного времени с высоким разрешением, в то время как другие архитектуры, такие как ARM, могут иметь менее точные или менее доступные счетчики времени.
В целом, при измерении времени выполнения цикла инструкции необходимо учитывать особенности конкретной архитектуры компьютера и выбирать подходящий метод измерения с учетом доступных ресурсов и требуемой точности измерений.
Примеры применения измерений цикла инструкции в реальных проектах
Измерение времени выполнения цикла инструкции в мегагерцах или гигагерцах является важным инструментом при разработке и оптимизации программного обеспечения, особенно в области высокопроизводительных вычислений и встроенных систем. Ниже приведены несколько примеров применения измерений цикла инструкции в реальных проектах.
- Оптимизация алгоритмов сортировки: Измерение времени выполнения цикла инструкции позволяет определить эффективность алгоритмов сортировки и выбрать наиболее подходящий для конкретного проекта. Например, можно сравнить производительность различных алгоритмов сортировки, таких как сортировка пузырьком, сортировка вставками и быстрая сортировка, и выбрать наиболее оптимальный для конкретной задачи.
- Оптимизация обработки видео и звука: При разработке программ для обработки видео и звука измерение времени выполнения цикла инструкции может помочь оптимизировать работу алгоритмов компрессии, декомпрессии и обработки данных. Например, при обработке видеоданных можно измерять время выполнения цикла инструкции кодирования и декодирования, чтобы улучшить производительность и качество видео.
- Оптимизация алгоритмов машинного обучения: Измерение времени выполнения цикла инструкции является важным при разработке и оптимизации алгоритмов машинного обучения. Например, можно измерить время выполнения цикла инструкции в алгоритмах глубокого обучения, таких как нейронные сети, и определить узкие места для дальнейшей оптимизации.
- Оптимизация игровых движков: При разработке игровых движков измерение времени выполнения цикла инструкции позволяет оптимизировать процесс отрисовки графики и обработки взаимодействия с пользователем. Например, можно измерять время выполнения цикла инструкции в алгоритмах рендеринга и физической симуляции для улучшения производительности и плавности игрового процесса.