Найти тему
Евгений Бывшев

Программирование микроконтроллеров. Часть 2-1

Здравствуйте!

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

Кнопку к микроконтроллеру можно подключить тремя способами:

-2

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

А в чем же различие между 1 и вторым способом если они дают одинаковый результат? В первом случае используется внутренний подтягивающий резисторкоторый включается программным способом при помощи команды PORTB |= (1 << PORTB1); , а во втором внешний на 10к который соединен с положительным выводом питания. Встроенный подтягивающий резистор микроконтроллера всегда одним концом подключен к + питания.

Весь код я взял с предыдущего урока и его модернизировал. Добавил команду DDRB = 0x00; которой переключил порт B на выход и уже знакомую командуPORTB |= (1 << PORTB1); для включения встроенного подтягивающего резистора.

В схеме я сделал следующие изменения:

-3

Добавил еще два светодиода с токоограничивающими резисторами, три кнопки и два внешних подтягивающих резистора по 10к.

Запишем основной цикл программы. Здесь мы будем использовать условный оператор if else. Этот оператор выполняет различные операции в зависимости от некоторого условия и записывается так:

If (условие)
{набор операторов A;}
else
{набор операторов B;}

Условие — это любое логическое выражение. Если результат этого выражения истина, то выполняется «набор операторов А», в противном случае выполняется «набор операторов В»

В программе это будет выглядеть так:

//Проверям состояние кнопки 1
if ((PINB&(1 << PORTB0)) == 0)
{
PORTD |= (1<<PORTD0); //Если кнопка нажата - зажигаем светодиод D1
}
else
{
PORTD &= ~(1<<PORTD0); //Если кнопка отжата - гасим светодиод D1
}

Точно такой же код будет и для второй кнопки только нужно будет изменить порты с PORTD0 на PORTD1. Для третьей кнопки нужно поменять код зажигания и гашения светодиодами местами т.к. у при замыкании кнопки на вход порта D2 подается логическая 1, а не логический 0 как в первом случае.

Весь код программы будет выглядеть следующим образом:

#define F_CPU 8000000UL //Рабочая частота МК (8МГц)
#include <avr/io.h>
#include <util/delay.h> //для _delay_ms()

int main(void)
{
DDRD = 0xff; //Переключаем порт D на выход
DDRB = 0x00; //Переключаем порт B на вход
PORTD = 0x00; //устанавливаем все выходы порта в логический 0
PORTB |= (1 << PORTB1); //Подключаем встроенный подтягивающий резистор

while (1)
{
//Проверям состояние кнопки 1
if ((PINB&(1 << PORTB0)) == 0)
{
PORTD |= (1<<PORTD0); //Если кнопка нажата - зажигаем светодиод D1
}
else
{
PORTD &= ~(1<<PORTD0); //Если кнопка отжата - гасим светодиод D1
}

//Проверям состояние кнопки 2
if ((PINB&(1 << PORTB1)) == 0)
{
PORTD |= (1<<PORTD1); //Если кнопка нажата - зажигаем светодиод D2
}
else
{
PORTD &= ~(1<<PORTD1); //Если кнопка отжата - гасим светодиод D2
}

//Проверям состояние кнопки 3
if ((PINB&(1 << PORTB2)) == 0)
{
PORTD &= ~(1<<PORTD2); //Если кнопка отжата - гасим светодиод D3
}
else
{
PORTD |= (1<<PORTD2); //Если кнопка нажата - зажигаем светодиод D3
}
}
}

Результат работы схемы после компиляции:

-4

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

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

Часть 1.