Файл: 2О19 4удк 53. 06Ббк 39. 5Аэроквантум тулкит. Александр Фоменко. 2е изд., перераб и доп. М. Фонд новых форм развития образования, 2019 154 с. Базовая серия Методический инструментарий наставника.pdf
ВУЗ: Не указан
Категория: Не указан
Дисциплина: Не указана
Добавлен: 09.11.2023
Просмотров: 142
Скачиваний: 2
ВНИМАНИЕ! Если данный файл нарушает Ваши авторские права, то обязательно сообщите нам.
103
Аэроквантум: тулкит достаткам, обладали высоким уровнем шума. Переход от то- чечных транзисторов к плоскостным совпал с переходом от германия к кремнию в 1953 году. Использование кремния уве- личило мощность транзистора. Позднее было налажено груп- повое производство, что сказалось на уменьшении стоимости этих приборов. В 1956 году трем американским ученым — Шок- ли, Бардину и Браттейну – присудили Нобелевскую премию по физике за исследование полупроводников и открытие тран- зисторного эффекта. К этому времени стало ясно, что приме- нение транзисторов сильно потеснит или даже заменит элек- тронную лампу.
Несмотря на то, что транзисторы практически полностью вы- теснили электронные лампы, последние все еще находят при- менение в высокочастотной и высоковольтной мощной тех- нике, например, в мощных радиовещательных передатчиках,
СВЧ-печах, радарах. Их применяют в военной промышленно- сти и космической технике из-за повышенной устойчивости к электромагнитным импульсам, температурным диапазонам и космической радиации. Электронные лампы до сих пор на- ходят применение в звукотехнике — как любительской, так и профессиональной. Конструирование ламповых звукотехни- ческих устройств является одним из направлений современ- ного радиолюбительского движения.
Второй, решающий шаг — появление интегральных схем. Пер- вая схема была изготовлена в 1961 году и представляла собой триггер, состоящий из четырех биполярных транзисторов и двух резисторов. Их быстрому распространению поспособ- ствовала хорошо отработанная технологическая база группо- вого производства транзисторов.
Таким образом, с момента изобретения транзистора до изго- товления первых интегральных схем, поступивших на рынок, прошло чуть более десяти лет. С этого момента началось стре- мительное развитие микроэлектроники. Далеко не все схемы, считавшиеся типичными в дискретной транзисторной элек- тронике, оказались приемлемыми в микроэлектронике. И на- оборот, многие схемы, которые казались экзотическими и не имели широкого распространения, в микроэлектронике оказа- лись приемлемыми и даже оптимальными.
104
В процессе развития микроэлектроники появилось множе- ство специфичных компонентов, которые не имеют аналогов в транзисторной схемотехнике, например, многоэмиттерный транзистор и приборы с зарядовой связью. Схемы с такими элементами не могут быть даже промоделированы на дискрет- ных компонентах.
Все сказанное выше говорит о том, что микроэлектроника как область науки и техники не сводится только к технологии ин- тегральных схем. Она аккумулирует в себе три равнозначных аспекта: физический, технологический и схемотехнический.
Знание этих трех аспектов микроэлектроники позволяет раз- работчику интегральных схем трезво оценивать как новые ва- рианты элементной базы или схемных решений, так и новые варианты технологических процессов.
Микроконтроллеры и их программирование на примере
Arduino
Микроконтроллер — это микросхема, представляющая собой микрокомпьютер для управления электронными устройства- ми.
Мы будем рассматривать программирование микроконтрол- леров на примере платы Arduino и специально написанного под него языка, который основан на С/С++. Мы не станем опи- сывать шаги по настройке и установке — все это вы сможете найти непосредственно на сайте производителя. Сразу обра- тимся непосредственно к программированию.
Для подачи команд и приема показаний с внешних приборов применяются цифровые и аналоговые порты. Цифровой порт может передавать сигнал (HIGH) или его отсутствие (LOW), а также определять наличие этого сигнала, если порт использу- ется как вход.
Аналоговые же входы могут не просто определять наличие сигнала, но и показывать конкретные значения на его основе, например, силу тока в цепи или расстояние до объекта. Если же вы хотите передавать аналоговый сигнал, например, для управ- ления яркостью свечения светодиода, то эту функцию на себя берут специальные цифровые порты, которые могут работать в
105
Аэроквантум: тулкит режиме ШИМ (широтно-импульсной модуляции).
ШИМ — процесс управления мощностью, подводимой к на- грузке, путём изменения скважности импульсов, при постоян- ной частоте.
Выход микроконтроллера переключается между землей и Vcc тысячи раз в секунду. Или, как ещё говорят, имеет частоту в ты- сячи герц. Глаз не замечает мерцания более 50 Гц, поэтому нам кажется, что светодиод не мерцает, а горит вполсилы.
Аналогично разогнанный мотор не может остановить вал за миллисекунды, поэтому ШИМ-сигнал заставит вращаться его в неполную силу.
Скважность — это отношение периода следования импульсов к длительности импульса.
50% — эквивалент 2,5 В
106
10% — эквивалент 0,5 В
90% — эквивалент 4,5 В
Перейдем к основам программирования. Мы должны узнать, что такое переменные и как их объявлять, для чего нужны функ- ции, а также запомнить наиболее часто используемые из них.
Переменные
Переменная — это место хранения данных. Она имеет имя, зна- чение и тип. Например, данное объявление (называется декла- рацией):
int pin = 13;
создает переменную с именем pin, значением 13 и типом int.
Затем в программе имеется возможность обратиться к данной
107
Аэроквантум: тулкит переменной через имя с целью работы с ее значением.
Например, в утверждении:
pinMode(pin, OUTPUT);
имеется значение вывода (13), которое будет передаваться в функцию pinMode(). В данном случае нет необходимости ис- пользовать переменную. Утверждение может работать и в та- ком виде:
pinMode(13, OUTPUT);
Преимущество переменной заключается в том, что необходи- мо определить значение вывода однажды и потом использо- вать его многократно. Впоследствии при изменении вывода
13 на 12 достаточно будет поменять только одну строку в про- граммном коде. Также можно использовать специальные имена для подчеркивания значения переменной (напр., программа, управляющая светодиодом RGB, может содержать переменные redPin, greenPin и bluePin).
Переменные имеют другие преимущества перед такими зна- чениями, как число. Есть возможность изменить значение пе- ременной, используя присвоение. Например, pin = 12; изменит значение переменной на число 12. В данном приме- ре не определяется тип переменной, так как он не меняется операцией присвоения. Имя переменной постоянно связано с типом, меняется только значение. Перед присвоением зна- чения необходимо декларировать переменную. Присвоение значения переменной без ее декларации вызовет следующее сообщение: «Error: pin was not declared in this scope».
При присвоении одной переменной другой происходит копи- рование значения первой переменной во вторую. Изменение значения одной переменной не влияет на другую.
108
Например, после записи:
int pin = 13;
int pin2 = pin;
pin = 12;
только pin имеет значение 12, а pin2 еще равен 13.
Что означает слово scope в сообщении об ошибке, приведен- ной выше? Оно относится к части программы, в которой пере- менная может использоваться — области видимости, которая определяется местом ее декларации. Например, имеется воз- можность использовать переменную во всей программе, если задекларировать ее в начале программного кода. Такие пере- менные называются глобальными. Например,
int pin = 13;
void setup()
{
pinMode(pin, OUTPUT);
}
void loop()
{
digitalWrite(pin, HIGH);
}
Из примера видно, что pin используется в обеих функциях setup() и loop(). Обе функции ссылаются на одну переменную, таким образом, изменение ее значения в одной функции по- влияет на значение в другой: int pin = 13;
void setup()
{
pin = 12;
pinMode(pin, OUTPUT);
}
void loop()
{
digitalWrite(pin, HIGH);
}
Функции digitalWrite(), вызываемой из loop(), будет передано
109
Аэроквантум: тулкит значение 12, т.к. оно было присвоено переменной в функции setup().
Если переменная используется только один раз в функции, то ее декларируют в данной части программного кода, ограничен- ной скобками функции. Например,
void setup()
{
int pin = 13;
pinMode(pin, OUTPUT);
digitalWrite(pin, HIGH);
}
В данном примере переменная может использоваться только внутри функции setup(). При написании данного кода:
void loop()
{
digitalWrite(pin, LOW); // wrong: pin is not in scope here.
}
будет выведено сообщение: «Error: pin was not declared in this scope». Данное сообщение будет выводиться, даже если вы за- декларировали переменную где-то в программе, но пытаетесь ее использовать вне области видимости.
Почему не сделать все переменные глобальными? Если неиз- вестно, где будет еще использоваться переменная, то почему ее надо ограничивать одной функцией? Когда переменная ограничена, легче найти источник ее изменения. Если пере- менная глобальная, то ее значение может быть изменено в любом месте программного кода, что означает необходимость проследить ее изменение по всей программе. Например, когда переменная имеет некорректное значение, то гораздо легче найти причину, если область видимости ограничена.
Функции
Разбиение на сегменты кода функциями позволяет создавать части кода, которые выполняют определенные задания. После выполнения происходит возврат в место, откуда была вызва- на функция. Причиной создания функции является необходи- мость выполнять одинаковое действие несколько раз.
110
Разделение кода на функции имеет ряд преимуществ:
• Функции позволяют организовать программу. Очень часто помогают заранее составить концепцию программы.
• Функции кодируют одно действие в одном месте программы.
Далее необходимо только отладить код функции.
• Функции сокращают шансы на появление ошибки при необ- ходимости изменения кода.
• Функции сокращают текст программы и делают его компакт- ным, так как некоторые секции используются много раз.
• Функции облегчают использование кода в других програм- мах, делая его модульным. В этом случае функции обладают еще одним небольшим преимуществом — делают код про- граммы легким для чтения.
Существуют две обязательные функции в программах для
Arduino: setup() и loop(). Другие функции должны создаваться за скобками этих функций. В следующем примере будет созда- на простая функция умножения двух чисел.
1 2 3 4 5 6 7 8 9
Пример
Для вызова функции умножения ей передаются параметры данных:
void loop(){
int i = 2;
int j = 3;
int k;
k = myMultiplyFunction(i, j); // k содержит 6
}
111
Аэроквантум: тулкит
Созданную функцию необходимо задекларировать вне скобок любой другой функции, таким образом «myMultiplyFunction()» может стоять выше или ниже функции «loop()». Весь скетч бу- дет выглядеть следующим образом:
void setup(){
Serial.begin(9600);
}
void loop(){
int i = 2;
int j = 3;
int k;
k = myMultiplyFunction(i, j); // k содержит 6
Serial.println(k);
delay(500);
}
int myMultiplyFunction(int x, int y){
int result;
result = x * y;
return result;
}
Еще один пример
Следующая функция будет считывать данные с датчика функ- цией analogRead() и затем рассчитывать среднее арифметиче- ское. Затем созданная функция будет масштабировать данные по 8 битам (0–255) и инвертировать их. // датчик подключен к выводу 0
int ReadSens_and_Condition(){
int i;
int sval;
for (i = 0; i < 5; i++){
sval = sval + analogRead(0); // сенсор на аналоговом входе 0
}
sval = sval / 5; // среднее sval = sval / 4; // масштабирование по 8 битам (0–255)
sval = 255 - sval; // инвертирование выходного значения return sval;
}
Вызов функции осуществляется присвоением ее переменной.
112
int sens;
sens = ReadSens_and_Condition();
Остановимся на нескольких основных функциях:
Функция setup()
Функция setup() вызывается, когда стартует скетч. Использу- ется для инициализации переменных, определения режимов работы выводов, запуска используемых библиотек и т.д. Функ- ция setup запускается только один раз, после каждой подачи питания или сброса платы Arduino.
Пример int buttonPin = 3;
void setup()
{
Serial.begin(9600);
pinMode(buttonPin, INPUT);
}
void loop()
{
// ...
}
Функция loop()
После вызова функции setup(), которая инициализирует и устанавливает первоначальные значения, функция loop() дела- ет точь-в-точь то, что означает её название, и крутится в цикле, позволяя вашей программе совершать вычисления и реагиро- вать на них. Используйте её для активного управления платой
Arduino.
Пример
int buttonPin = 3;
// setup инициализирует последовательный порт и кнопку void setup()
{
beginSerial(9600);
pinMode(buttonPin, INPUT);
}
113
Аэроквантум: тулкит
// в цикле проверяется состояние кнопки,
// и на последовательный порт будет отправлено сообщение, если она нажата void loop()
{
if (digitalRead(buttonPin) == HIGH)
serialWrite(‘H’);
else serialWrite(‘L’);
delay(1000);
}
Функция pinMode()
Описание
Устанавливает режим работы заданного вход/выхода(pin) как входа или как выхода.
Синтаксис
pinMode(pin, mode)
Параметры
• pin: номер вход/выхода(pin), который вы хотите установить;
• mode: режим одного из двух значений — INPUT или OUTPUT
— устанавливает на вход или выход соответственно.
Возвращаемое значение:
нет.
Пример
int ledPin = 13; // Светодиод, подключенный к вход/выходу 13
void setup()
{
pinMode(ledPin, OUTPUT); // устанавливает режим работы
- выход
}
void loop()
{
digitalWrite(ledPin, HIGH); // включает светодиод
114
delay(1000); // ждет секунду digitalWrite(ledPin, LOW); // выключает светодиод delay(1000); // ждет секунду
}
Примечание
Аналоговые входы (analog pins) могут быть использованы как цифровые вход/выходы (digital pins). Обращение к ним идет по номерам от 14 (для аналогового входа 0) до 19 (для аналогового входа 5).
Функция analogRead()
Функция считывает значение с указанного аналогового входа.
Большинство плат Arduino имеют 6 каналов (8 каналов у платы
Mini и Nano, 16 у Mega) c 10-битным аналого-цифровым пре- образователем (АЦП). Напряжение, поданное на аналоговый вход, обычно от 0 до 5 Вольт будет преобразовано в значение от 0 до 1023, это 1024 шага с разрешением 0.0049 Вольт.
Разброс напряжения и шаг можно изменить функцией analogReference().
Считывание значения с аналогового входа занимает примерно
100 микросекунд (0.0001 сек), т.е. максимальная частота считы- вания приблизительно 10,000 раз в секунду.
Синтаксис
analogRead(pin)
Параметры
pin: номер порта аналогового входа, с которого будет произ- водиться считывание (0..5 для большинства плат, 0..7 для Mini и Nano и 0..15 для Mega).
Возвращаемое значение
int (0 to 1023)
Замечание
Если аналоговый вход не подключен, то значения, возвращае- мые функцией analogRead(), могут принимать случайные зна- чения.
115
Аэроквантум: тулкит
Пример
int analogPin = 3; // номер порта, к которому подключен потен- циометр int val = 0; // переменная для хранения считываемого значения void setup()
{
Serial.begin(9600); // установка связи по serial
}
void loop()
{
val = analogRead(analogPin); // считываем значение
Serial.println(val); // выводим полученное значение
}
Функция analogWrite()
Описание
Выдает аналоговую величину (ШИМ-волну) на порт вход/вы- хода. Функция может быть полезна для управления яркостью подключенного светодиода или скоростью электродвигателя.
После вызова analogWrite() на выходе будет генерировать- ся постоянная прямоугольная волна с заданной шириной импульса до следующего вызова analogWrite (или вызова digitalWrite или digitalRead на том же порту вход/выхода). Ча- стота ШИМ-сигнала приблизительно 490 Hz.
На большинстве плат Arduino (на базе микроконтроллера
ATmega168 или ATmega328) ШИМ поддерживают порты 3, 5, 6,
9, 10 и 11, на плате Arduino Mega — порты со 2 по 13. На более ранних версиях плат Arduino analogWrite() работал только на портах 9, 10 и 11.
Для вызова analogWrite() нет необходимости устанавливать тип вход/выхода функцией pinMode().
Функция analogWrite никак не связана с аналоговыми входами и с функцией analogRead.
Синтаксис
analogWrite(pin, value)
116
Параметры
• pin: порт вход/выхода, на который подаем ШИМ-сигнал.
• value: период рабочего цикла — значение между 0 (полно- стью выключено) и 255 (сигнал подан постоянно).
Возвращаемое значение:
нет.
Замечание
Период ШИМ-сигнала на портах вход/выхода 5 и 6 будет не- сколько длиннее. Это связано с тем, что таймер для данных выходов также задействован функциями millis() и delay(). Дан- ный эффект более заметен при установке коротких периодов
ШИМ-сигнала (0–10).
Пример
Задание яркости светодиода пропорционально значению, снимаемому с потенциометра.
int ledPin = 9; // светодиод подключен к выходу 9
int analogPin = 3; // потенциометр подключен к выходу 3
int val = 0; // переменная для хранения значения void setup()
{
pinMode(ledPin, OUTPUT); // установка порта на выход
}
void loop()
{
val = analogRead(analogPin); // считываем значение с порта, подключенного к потенциометру analogWrite(ledPin, val / 4); // analogRead возвращает значения от 0 до 1023, analogWrite должно быть в диапазоне от 0 до 255
}
Функция digitalWrite()
Описание
Подает HIGH или LOW значение на цифровой вход/выход
(pin).
Если вход/выход (pin) был установлен в режим выход (OUTPUT)