Вы находитесь на странице: 1из 8

Лекция 2.

I.3. Подключение кнопки

Соберём следующую схему, см. рис.7. На нем изображено подключение кнопки без фиксации
к пину D3 с подтягивающим резистором 10 килоом к
плюсу питания. Из схемы подключения видно, что на
пине D3 находится логическая единица если кнопка не
нажата, и – логический ноль если нажата. Напишем
программу считывающую нажатие кнопки и
включающую или выключающую светодиод на
встроенном пине D13. Определимся с
микроконтроллером. Пусть это будет ATmega328p, тогда
D13 соответствует PB5, а D3 – PD3. Таким образом нам
нужно настроить пятый бит порта B на ВЫХОД и третий
бит порта D на вход. У микроконтроллеров ATmega328p
и ATmega2560 порты B, C, D и соответствующие им
имена регистров и бит совпадают. Поэтому
воспользуемся рисунком 4. Команда
DDRB  |= (1<<DDB5);
Рис.7. Подключение кнопки с установит PB5 как ВЫХОД.
подтягивающим резистором Команда
к +5В. DDRD &= ~(1<<DDD3);
установит PD3 как ВХОД. Для считывания состояния
пина PD3 нужно использовать регистр (см. рис. 4) PIND, а вернее его третий бит PIND3.
Команда
PIND&(1<<PIND3)
позволит понять, какой уровень сигнала (высокий или низкий) находится на пине PD3.
Разберем ее подробно. Операция 1<<PIND3 сдвинет единицу на третью позицию (считая от
нуля) и мы получим следующее двоичное число 0b00001000, затем применим побитовую
операцию логического И с восьмибитным регистром PIND
0b----x---
& 0b00001000
0b0000x000
Нас интересует состояние только третьего бита регистра PIND, которое мы обозначили как
x, значения всех остальных бит нам неважно (поэтому стоят прочерки). После применения
побитового & в ответе получим двоичное число либо 1000 либо 0 (нули на старших разрядах
опущены). Таким образом если на пине присутствует логический ноль, то мы получим число
0, если – логическая единица, то получаем некоторое число больше нуля. Слово некоторое
означает, что если бы мы считывали второй бит, то получили бы 100, если бы пятый, то –
10000 и тому подобные числа. В языке С++ число 0 определяется как логическое FALSE, а
любое другое число не равное нулю как TRUE. Поэтому справедлива следующая
конструкция

if (PIND&(1<<PIND3)){      
     //кнопка не нажата
   }
   else{
     //кнопка нажата
   }

Так получается потому что при нажатии на кнопку мы устанавливаем логический ноль на
пине D3. Окончательно имеем следующую программу

prog5

1 #define F_CPU 16000000UL    // Частота - 16MHz


2 #include <avr/io.h>         // Библиотека ввода/вывода
3 int main(void) {
4  DDRB  |= (1<<DDB5);    // Выставляем PB5 на ВЫХОД
5  PORTB &= ~(1<<PORTB5); // Выставляем лог 0 на PB5
6  DDRD &= ~(1<<DDD3);    // пин PD3 как ВХОД (сюда подключается кнопка)
7   while(1) {
8    if (PIND&(1<<PIND3)){ //считываем состояние пина PD3
9      PORTB |= (1<<PORTB5);  // Устанавливаем лог.1 на пине PВ5   
10    }
11    else{
12      PORTB &= ~(1<<PORTB5);  // Устанавливаем лог.0 на пине PВ5
13    }
14  }
15 }

После загрузки программы в микроконтроллер ATmega328p встроенный светодиод светится


пока кнопка не нажата, как только нажимаем на кнопку
светодиод выключается. Как сделать так чтобы
программа работала наоборот, т.е. при нажатии на
кнопку светодиод включался, а при отпускании –
выключался? Есть несколько способов решения данной
задачи. Например, можно поменять строки 9 и 12
местами.
Можно изменить строку 8 на
if (~PIND&(1<<PIND3)){

Укажем еще один способ каким можно решить данную


проблему, это так называемый хардверный способ, т.е.
нужно изменить схему подключения на следующую (см.
рис.8). При таком подключении после загрузки prog5 в
микроконтроллер светодиод будет загораться при
Рис.8. Подключение кнопки с нажатии на кнопку, так как в не нажатом состоянии на
подтягивающим резистором пине D3 находится низкий уровень, а при нажатой
к GND. кнопке – высокий.
Напомним, что вместо оператора
if (условие)){      
     условие истинно
   }
   else{
     условие ложно
   }
можно использовать тернарный оператор
(условие) ?  условие истинно :  условие ложно;
Тогда строки 8 – 13 в можно заменить на следующую

(PIND&(1<<PIND3)) ? PORTB &= ~(1<<PORTB5) : PORTB |= (1<<PORTB5);

Еще одним вариантом подключения кнопки есть способ


использовать внутренний (внутри микроконтроллера)
подтягивающий резистор. Тогда схема подключения
будет следующей (см. рис. 9). На рисунке 9 резистор
является защитным. Он нужен для того чтобы если при
настройке программы пин D3 окажется настроенным
как ВЫХОД и при этом на нем будет логическая
единица, то нажатие на кнопку приведет, как минимум,
к выводу этого пина из рабочего состояния.
Для включения подтягивающего резистора нужно при
настроенном пине как ВХОД установить в
соответствующем бите регистра PORTx логическую
единицу. В нашем случае кнопка подключена на пин
PD3, что означает третий бит порта D. Таким образом
Рис.9. Подключение кнопки с команда подключения подтягивающего резистора будет
внутренним подтягивающим выглядеть как
резистором. PORTD |= (1<<PORTD3);

Окончательно получаем следующую программу

prog6

1 #define F_CPU 16000000UL    // Частота - 16MHz


2 #include <avr/io.h>         // Библиотека ввода/вывода
3 int main(void) {
4  DDRB  |= (1<<DDB5);    // Выставляем PB5 на ВЫХОД
5  PORTB &= ~(1<<PORTB5); // Выставляем лог 0 на PB5
6  DDRD &= ~(1<<DDD3);    // пин PD3 как ВХОД (сюда подключается кнопка)
7 PORTD |= (1<<PORTD3); // к PD3 подключаем подтягивающий резистор
8   while(1) {
9    if (PIND&(1<<PIND3)){ //считываем состояние пина PD3
10      PORTB &= ~(1<<PORTB5);  // Устанавливаем лог.0 на пине PВ5
11    }
12    else{
13      PORTB |= (1<<PORTB5);  // Устанавливаем лог.1 на пине PВ5   
14    }
15  }
16 }

Обратите внимание, что если закомментировать седьмую строчку, то prog6 не будет работать
со схемой, собранной по рисунку 9.
Дребезг кнопки
Для того, чтобы понять, что такое дребезг, соберем очень простую схему с Arduino, кнопкой
и светодиодом. При нажатии на кнопку светодиод должен включаться, если он был
выключен. При следующем нажатии на кнопку светодиод должен гаснуть. Схема
подключения представлена на рис.9.
prog7

1 #define Button 3 //кнопка


2 #define LED 13   //светодиод
3
4 void setup() {
5  pinMode(Button, INPUT_PULLUP);
6  pinMode(LED, OUTPUT);
7 }
8
9 bool flag = LOW;
10 bool currentButton, lastButton = HIGH;
11
12 void loop() {
13  currentButton = digitalRead(Button);   // Считываем состояние кнопки
14  if (lastButton && !currentButton){ //кнопка "нажата" - LOW И
15 //предыдущее HIGH ->
16    flag = !flag;                    // инверсия флага        
17    digitalWrite(LED, flag);                 
18  }
19  lastButton = currentButton;  // Запоминаем текущее состояние кнопки
20 }

В лабораторной работе вам нужно будет написать этот код на СИ.

Программное устранение дребезга.


Для программного устранения дребезга, достаточно после первого изменения состояния
кнопки, установить паузу в несколько миллисекунд, для того чтобы контакт
стабилизировался и дребезг был проигнорирован. Для этого дополним код
функцией debounce():

prog8

1 #define Button 3 //кнопка


2 #define LED 13   //светодиод
3
4 void setup() {
5  pinMode(Button, INPUT_PULLUP);
6  pinMode(LED, OUTPUT);
7 }
8
9 bool flag = LOW;
10 bool currentButton, lastButton = HIGH;
11
12 bool debounce() {
13  bool current = digitalRead(Button);
14  if (current != lastButton){ // Старое значение отличается от нового
15    delay(10);                // Ждем стабилизации - игнорируем дребезг
16    current = digitalRead(Button); //Считываем устойчивое значение
17  }
18  return current;
19 }
20
21 void loop() {
22  currentButton = debounce();   // Считываем значение состояние кнопки
23  if (lastButton && !currentButton){ //кнопка "нажата" - LOW И
24 //предыдущее HIGH -> инверсия флага
25    flag = !flag;                            
26    digitalWrite(LED, flag);                 
27  }
28  lastButton = currentButton;    // Запоминаем текущее состояние кнопки
29 }

В лабораторной работе вам нужно будет написать этот код на СИ.

Маркировка резисторов. Мощность.


Сопротивление резистора - его основная характеристика. Основной
единицей электрического сопротивления является ом (Ом). Чтобы не путать
ноль и букву "О", "Ом" часто заменяют греческой буквой "омега" Ω.
Обычно на схемах резистор обозначается большой латинской буквой R и
прямоугольником. Иногда в иностранных (американский стандарт) схемах
встречается изображение резистора в виде «пилы».

На прошлых занятиях мы с вами уже использовали резистор на 220 Ом.


Однако его номинал (220 Ом) был просто озвучен, а почему именно данный
резистор имеет такую характеристику, было нам не известно. Сегодня мы
разберемся с тем, как определять сопротивление любого резистора, и чем они
отличаются кроме сопротивления.
Для определения номинала необходимо посмотреть на цветные полоски,
нанесенные на резистор и воспользоваться следующей таблицей:
Находим золотую полоску (на резисторе), и располагаем его так, чтобы
она находилась справа.

Видим, что кроме золотой полоски еще имеется три (возможный вариант -
четыре). Последовательность трех полос слева направо следующая:
красная, красная, коричневая.
Смотрим в таблицу: первая красная полоска соответствует цифре «2»,
вторая – цифре «2», а третья, коричневая, множителю «10».
Таким образом имеем следующую комбинацию:
2210,
которая соответствует значению 220 Ом.
Золотая полоска означает точность изготовления резистора, т.е. 5%. Это
соответствует 2200,05=11 Ом, т.е. наш резистор может быть в пределах от 220-
11 до 220+11 Ом, другими словами, сопротивление резистора лежит от 209 до
231 Ома.
Если бы у нас был резистор с четырьмя полосками, то третья полоса
соответствовала бы цифре, а не множителю. В частности, иногда используется
следующий резистор

Который согласно таблице цветовой маркировки, имеет четыре линии


определяющих его номинал: красная, красная, черная, черная. И одна линия,
соответствующая точности: коричневая.
Т.е. получаем следующие цифры: «2», «2», «0», «1».
Окончательно имеем 2201=220 Ом.
Точность 1%, т.е. сопротивление резистора находится в пределах от 217,8 до
222,2 Ома.

Задание.
Рассчитать номинал следующего
резистора

Коричневая линия – цифра «1», черная – цифра «0», оранжевая – множитель


«1000» итого получаем
101000=10000 Ом= 10кОм.
Точность 5%, т.е. 500 Ом. Окончательно имеем резистор сопротивлением от
9500 Ом до 10500 Ом или от 9,5 кОм до 10,5 кОм.

Следующая очень важная характеристика мощность резистора.


Мощность измеряется в ваттах и рассчитывается по одной из формул:
2U2
P=U⋅I =I ⋅R=
R .
Давайте рассчитаем рассеиваемую мощность резистора из предыдущего
занятия. Нам известно, что падение напряжения на резисторе равно 2,8 В, сила
тока через резистор составляет 20 мА и сопротивление резистора есть 140 Ом.
Расчет по любой из трех приведенных формул дает следующий результат
2 2,82
P=2,8⋅0 , 02=0 , 02 ⋅140= =0 , 056 Вт=56 мВт
140 .
Используемый нами резистор рассчитан на мощность до 250 мВт, т.е. он
нас полностью устраивает, так как всегда нужно выбирать резистор по
мощности больше, чем ему придется рассеивать. Неправильно подобранный
резистор по мощности может быть причиной пожара. На принципиальных
электрических схемах мощность резисторов указывает специальный значок.

Чем большую рассеиваемую мощность имеет резистор, тем он больше по


размерам (габаритам).

Вам также может понравиться