THE BELL

Есть те, кто прочитали эту новость раньше вас.
Подпишитесь, чтобы получать статьи свежими.
Email
Имя
Фамилия
Как вы хотите читать The Bell
Без спама

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

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

Подключение кнопки к микроконтроллеру

Если мы подключим один из контактов, например, к общему проводу («земле»), а второй к выбранному выводу микроконтроллера, переключенного в режим входа, то выяснится, что такой метод не работает. При нажатии кнопки вывод микроконтроллера соединяется с землей, и программа будет считывать (с помощью функции digitalRead) логический 0 с этого вывода, но при отпущенной кнопке вывод микроконтроллера не будет соединен ни с какой линией, что часто называют «висит в воздухе». В таком режиме программа будет считать с вывода и 0 и 1 совершенно случайным образом.

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

Первый вариант предпочтительнее, поскольку подтягивающие к +5В резисторы уже есть внутри микроконтроллера – их нужно только программно включить. Кнопка будет либо соединять вывод микроконтроллера с землей, либо разъединять, и тогда он "притянется" резистором к +5В.

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

Пример программы, зажигающей светодиод на 13 выводе при нажатии кнопки на 2 выводе будет выглядеть примерно так:

Обращаем внимание на то, что значение, прочитанное с 2 вывода, инвертируется с помощью оператора «!», поскольку при нажатии на кнопку будет считываться «0», а при ее отпускании «1».

Дребезг контактов

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

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

Существует специальная библиотека Bounce, упрощающая борьбу с дребезгом контактов, и имеющая дополнительные возможности:

Как и в большинстве случаев, установка библиотеки сводится к распаковке архива в подпапку \hardware\libraries\ папки с ПО Arduino.

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

Bounce – конструктор объекта

Bounce имя_объекта = Bounce(вывод, интервал);

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

Метод Bounce::update

имя_объекта.update()

Возвращает значение типа int – истину, если состояние вывода изменилось, ложь, если нет.

Метод Bounce::read

имя_объекта.read()

Возвращает значение типа int – состояние вывода.

Метод Bounce::rebounce

имя_объекта.rebounce(время_повтора)

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

Рассмотрим исходный код программы, посылающей в последовательный порт сообщение «pressed» при нажатии кнопки, сообщение «released» при ее отпускании, и повторяющей сообщение «pressed» каждые пол секунды при удержании кнопки.

#include

Bounce bouncer = Bounce(2 , 40 ) ; //создаем экземпляр класса Bounce для 2 вывода

void setup()
{
pinMode(2 , INPUT) ; //переключаем 2 вывод в режим входа
digitalWrite(2 , 1 ) ; //включаем на нем подтягивающий резистор
Serial.begin (9600 ) ; //установка порта на скорость 9600 бит/сек
}

void loop()
{
if (bouncer.update () ) { //если произошло событие
if (bouncer.read () == 0 ) { //если кнопка нажата
Serial.println ("pressed" ) ; //вывод сообщения о нажатии
bouncer.rebounce (500 ) ; //повторить событие через 500мс
} else {
Serial.println ("released" ) ; //вывод сообщения об отпускании
}
}
}

Сегодня мы расширим свой кругозор по изучению работы портов микроконтроллера и изучим второе назначение порта — работу на вход. И для изучения работы на вход мы применим обычную тактовую кнопку.

Как всегда, создадим проект в Atmel Studio, выберем Atmega8A, назовем проект Test04 и код также в main.c, как обычно, скопируем с проекта предыдущего урока.

В качестве подопытного порта давайте возьмём порт B. Можно с успехом использовать любой порт. И в качестве ножки возьмем нулевую ножку. Итак у нас ножка B0.

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

Добавим кнопку в протеусе, для этого в поиске компонентов найдём Button

Затем подключим нашу кнопку вот таким вот образом к ножке B0 контроллера

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

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

DDRD = 0xFF;

DDRB = 0x00;

В случае, когда мы работали с портом D на выход, биты регистра PORTD отвечали за уровень на соответствующих ножках. А в случае, когда порт инициализирован на вход, как наш порт B, то биты регистра PORTB будут уже отвечать за подтягивание к соответствующим ножкам порта резисторов на шину питания. Если будет логическая единица, то регистр будет подтягиваться, а если логический ноль — то не будет. Поэтому мы в 0 бите регистра установим 1

PORTD = 0b00000001;

PORTB = 0b00000001;

Соберём код и запустим его в протеусе. Мы видим, что на ножке B0 у нас установилась логическая 1 , а если мы нажмём кнопку, то увидим, что на ней будет логический 0 , о чём свидетельствует синий цвет квадратиков на ножке и на кнопке.

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

// for(i=0;i<=7;i++)

// {

// PORTD = (1<

// _delay_ms(500);

// }

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

Чтобы нам следить за каким-либо действием или состоянием, нам необходимо будет обработать условие.

Условие в языке C добавляется с помощью команды if .

И в качестве условия мы возьмём состояние ножки 0 порта B или состояние бита 0 регистра PINB .

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

Можно пойти на хитрость и применить вот такую конструкцию PINB &0b00000001 .

Данная конструкция нам и проверит нулевой бит. То есть если в регистре PINB также будет 1 в нулевом его бите, то независимо от состояния остальных битов в данном регистре мы получим ненулевой результат, что также является истиной. То есть если ни с чем не сравнивать в условии результат, то условие эквивалентно сравниванием с нулём, только наоборот. Для истинности результат должен быть ненулевым — (результат!=0 ).

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

while (1)

if (!( PINB &0b00000001))

{

}

else

{

}

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

DDRB =0x00;

PORTD =0b00000000 ;

PORTB =0b00000001;

while (1)

If (!(PINB &0b00000001))

PORTD =0b00000001;

Else

PORTD =0b00000000;

Теперь давайте пересоберём проект и пойдём в протеус смотреть, удалось ли нам что-то.

Чтобы у нас при сборке не было даже предупреждений, уберём объявление переменной i, так как она в коде не используется

int main ( void )

// unsigned char i;

Unsigned char butcount =0;

Запустим проект в протеусе и увидим, что при нажатии на кнопку у нас начинает светиться самый верхний светодиод

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

И чтобы это как-то отследить и определить, что это было именно нажатие, а не дребезг, то мы будим отслеживать нажатие некоторое время, ну или некоторое количество тактов или циклов. Для этого в начале функции main() до бесконечного цикла мы добавим другую переменную (i нам ещё пригодится и мы её портить не будем). Назовём мы переменную butcount , так как имя переменной должно как-то само за себя говорить и тем самым достигается ещё большая читабельность кода

// unsigned char i;

unsigned char butcount =0;

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

if (!( PINB &0b00000001))

if ( butcount < 5)

{

butcount ++;

}

А когда значение данной переменной достигнет значения 5, то мы уже в данный цикл не попадём, а попадём мы в тело оператора else , который мы сейчас и добавим и в его теле напишем следующий код

Butcount ++;

else

PORTD =0b00000001;

То есть мы как раз после достижения пятёрки и будем обрабатывать нажатие кнопки и включать на нулевой ножке порта D высокое состояние.

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

else

if (butcount >0)

{

butcount —;

}

else

{

PORTD =0b00000000;

}

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

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

Смотреть ВИДЕОУРОК

Post Views: 13 083

Научимся искать информацию по разным моделям AVR микроконтроллеров, разберемся c чтением PDF документов в операционной системе Linux. Узнаем как подключить микроконтроллер к программатору используя интерфейс ISP при помощи нескольких проводников.

Чтобы правильно подключить микросхему-микроконтроллер к программатору нужно разобраться где у него и какие выводы. Для получения исчерпывающей информации о интересующем нас микроконтроллере качаем на официальном сайте даташит (datasheet ) на интересующий нас чип - Даташиты по микроконтроллерам ATMEL .

На первой страничке даташита приводится подробное описание возможностей микроконтроллера, а далее приведена распиновка микросхем под каждый из типов корпусов. Каждый даташит по AVR чипу содержит массу подробной информации на английском языке, к примеру даташит на микроконтроллер ATmega8 содержит 326 страниц!

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

Чтение PDF документов в Linux

Как правило, все даташиты на микросхемы поставляются в формате PDF (Portable Document Format) - формат электронных документов для использования на разных платформах, разработан фирмой Adobe Systems.

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

  • Okular - универсальная и мощная программа для просмотра документов, входит в окружение рабочего стола KDE;
  • Qpdfview - простая и легковесная программа для просмотра документов в формате PDF, DjVu и PS;
  • Evince (Document Viewer) - очень быстрый и легковесный просмотрщик документов PostScript (PS), EPS, DJVU, DVI, PDF;
  • Xpdf - высокопроизводительный просмотрщик PDF-файлов.

Какую программу выбрать для просмотра PDF под Linux? - очень хорошо справляются со своими задачами программы Okular и Evince.

Если у вас установлена рабочая среда KDE то скорее всего что программа Okular уже присутствует в системе. Если Okular не установлен то исправить это можно командой:

Sudo apt-get install okular okular-extra-backends

Если же у вас рабочая среда отличная от KDE - GNOME, XFCE, UNITY то более экономичным решением будет установить Evince, поскольку установка в данных средах программы Okular потребует некоторые компоненты от рабочей среды KDE.

Рис. 1. Универсальный просмотрщик документов Evince под Linux - средство для листания PDF документов по микроконтроллерам.

Просмотрщик документов Evince очень хорошо открывает огромные документы и справляется иногда с такими что не под силу прочитать для Okular. Установка Evince в Linux:

Sudo apt-get install evince

Думаю что у вас теперь не возникнет проблем с чтением документов в формате PDF под ОС GNU Linux .

Подключение AVR микроконтроллера к программатору

Выше было рассказано что для подключения микроконтроллера к программатору нужно соединить выводы ISP: VCC, GND, MISO, MOSI, SCK, RST. Выводы с данными названиями присутствуют у всех микроконтроллеров, так что даташит нам в помощь.

Рис. 2. Распиновка микроконтроллера ATmega8 и подключение его к ISP (USB ASP).

У программатора USB ASP на коннекторе ISP предусмотрено напряжение +5В (VCC), так что для программирования чипа можно воспользоваться питанием от программатора, а вернее от USB порта к которому он подключен.

В рассмотреных раньше программаторах , что используют COM и LPT порты, нет вывода VCC, а это значит что с использованием этих программаторов на выводы GND (-) и VCC (+) микроконтроллера нужно подать напряжение питания 5В от внешнего источника.

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

Рис. 3. Подключение к ISP коннектору программатора USB ASP на беспаечной макетной панели.

В следующих статьях будут устройства, которые должны управлять внешней нагрузкой. Под внешней нагрузкой я понимаю все, что прицеплено к ножкам микроконтроллера – светодиоды, лампочки, реле, двигатели, исполнительные устройства … ну Вы поняли. И как бы не была заезжена данная тема, но, чтобы избежать повторений в следующих статьях, я все-же рискну быть не оригинальным — Вы уж меня простите:). Я кратенько, в рекомендательной форме, покажу наиболее распространенные способы подключения нагрузки (если Вы что-то захотите добавить – буду только рад).
Сразу договоримся, что речь идет о цифровом сигнале (микроконтроллер все-таки цифровое устройство) и не будем отходить от общей логики: 1 -включено, 0 -выключено. Начнем.

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

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

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

Rгасящий = (5v / 0.02A) – Rн = 250 – Rн

Как видно, даже в самом худшем случае, когда сопротивление нагрузки равно нулю достаточно 250 Ом для того, что бы ток не превысил 20мА. А значит, если неохота чего-то там считать — ставьте 300 Ом и Вы защитите порт от перегрузки. Достоинство способа очевидно – простота.

1.2 Подключение нагрузки при помощи биполярного транзистора.
Если так случилась, что Ваша нагрузка потребляет более 20мА, то, ясное дело, резистор тут не поможет. Нужно как-то увеличить (читай усилить) ток. Что применяют для усиления сигнала? Правильно. Транзистор!

Для усиления удобней применять n-p-n транзистор, включенный по схеме ОЭ . При таком способе можно подключать нагрузку с большим напряжением питания, чем питание микроконтроллера. Резистор на базе – ограничительный. Может варьироваться в широких пределах (1-10 кОм), в любом случае транзистор будет работать в режиме насыщения. Транзистор может быть любой n-p-n транзистор. Коэффициент усиления, практически не имеет значения. Выбирается транзистор по току коллектора (нужный нам ток) и напряжению коллектор-эмиттер (напряжение которым запитывается нагрузка). Еще имеет значение рассеиваемая мощность — чтоб не перегрелся.

Из распространенных и легко доступных можно заюзать BC546, BC547, BC548, BC549 с любыми буквами (100мА), да и тот-же КТ315 сойдет (это у кого со старых запасов остались).
- Даташит на биполярный транзистор BC547

1.3 Подключение нагрузки при помощи полевого транзистора.
Ну а если ток нашей нагрузки лежит в пределах десятка ампер? Биполярный транзистор применить не получиться, так как токи управления таким транзистором велики и скорей всего превысят 20мА. Выходом может служить или составной транзистор (читать ниже) или полевой транзистор (он же МОП, он же MOSFET). Полевой транзистор просто замечательная штука, так как он управляется не током, а потенциалом на затворе. Это делает возможным микроскопическим током на затворе управлять большими токами нагрузки.

Для нас подойдет любой n-канальный полевой транзистор. Выбираем, как и биполярный, по току, напряжению и рассеиваемой мощности.

При включении полевого транзистора нужно учесть ряд моментов:
— так как затвор, фактически, является конденсатором, то в моменты переключения транзистора через него текут большие токи (кратковременно). Для того чтобы ограничить эти токи в затвор ставиться ограничивающий резистор.
— транзистор управляется малыми токами и если выход микроконтроллера, к которому подключен затвор, окажется в высокоимпедансном Z-состоянии полевик начнет открываться-закрываться непредсказуемо, вылавливая помехи. Для устранения такого поведения ножку микроконтроллера нужно «прижать» к земле резистором порядка 10кОм.
У полевого транзистора на фоне всех его положительных качеств есть недостаток. Платой за управление малым током является медлительность транзистора. ШИМ, конечно, он потянет, но на превышение допустимой частоты он Вам ответит перегревом.

1.4 Подключение нагрузки при помощи составного транзистора Дарлингтона.
Альтернативой применения полевого транзистора при сильноточной нагрузке является применение составного транзистора Дарлингтона. Внешне это такой-же транзистор, как скажем, биполярный, но внутри для управления мощным выходным транзистором используется предварительная усилительная схема. Это позволяет малыми токами управлять мощной нагрузкой. Применение транзистора Дарлингтона не так интересно, как применение сборки таких транзисторов. Есть такая замечательная микросхема как ULN2003. В ее составе аж 7 транзисторов Дарлингтона, причем каждый можно нагрузить током до 500мА, причем их можно включать параллельно для увеличения тока.

Микросхема очень легко подключается к микроконтроллеру (просто ножка к ножке) имеет удобную разводку (вход напротив выхода) и не требует дополнительной обвязки. В результате такой удачной конструкции ULN2003 широко используется в радиолюбительской практике. Соответственно достать ее не составит труда.
- Даташит на сборку Дарлингтонов ULN2003

Если Вам нужно управлять устройствами переменного тока (чаще всего 220v), то тут все сложней, но не на много.

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

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

2.2 Подключение нагрузки при помощи симистора (триака).
Если нужно управлять мощной нагрузкой переменного тока а особенно если нужно управлять мощностью выдаваемой на нагрузку (димеры), то Вам просто не обойтись без применения симистора (или триака). Симистор открывается коротким импульсом тока через управляющий электрод (причем как для отрицательной, так и для положительной полуволны напряжения). Закрывается симистор сам, в момент отсутствия напряжения на нем (при переходе напряжения через ноль). Вот тут начинаются сложности. Микроконтроллер должен контролировать момент перехода через ноль напряжения и в точно определенный момент подавать импульс для открытия симистора — это постоянная занятость контроллера. Еще одна сложность это отсутствие гальванической развязки у симистора. Приходится ее делать на отдельных элементах усложняя схему.


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

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

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

THE BELL

Есть те, кто прочитали эту новость раньше вас.
Подпишитесь, чтобы получать статьи свежими.
Email
Имя
Фамилия
Как вы хотите читать The Bell
Без спама