Программирование микроконтроллеров. Часть 2-1
Доброе утро! Сегодня суббота, а значит никуда не надо торопиться и это свободное время можно потратить с пользой. Выпив чашечку утреннего кофе, я решил написать второй урок по программированию микроконтроллеров.
Этот урок будет в двух частях. Сегодня я покажу вам как подключить кнопу и управлять светодиодом. В первой части мы рассмотрим какими способами можно подключить кнопку, а во второй части поговорим о неприятном явлении – дребезге контактов и как с ним бороться программным способом.
Кнопку к микроконтроллеру можно подключить тремя способами:
Первые два способа идентичны, при нажатии на кнопку на 12 вывод микроконтроллера будет подан логический 0, а при размыкании кнопки логическая 1. В третьем способе при нажатии будет подана логическая 1, а при размыкании логический 0.
А в чем же различие между 1 и вторым способом если они дают одинаковый результат? В первом случае используется внутренний подтягивающий резистор который включается программным способом при помощи команды PORTB |= (1 << PORTB1);
, а во втором внешний на 10к который соединен с положительным выводом питания. Встроенный подтягивающий резистор микроконтроллера всегда одним концом подключен к + питания.
Весь код я взял с предыдущего урока и его модернизировал. Добавил команду DDRB = 0x00;
которой переключил порт B на выход и уже знакомую команду PORTB |= (1 << PORTB1);
для включения встроенного подтягивающего резистора.
В схеме я сделал следующие изменения:
Добавил еще два светодиода с токоограничивающими резисторами, три кнопки и два внешних подтягивающих резистора по 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
}
}
}
Результат работы схемы после компиляции:
Если не использовать подтягивающие резисторы, то на входе могут появиться помехи, что в свою очередь вызовет ошибки в работе готового устройства.
Следующая часть будет посвящена дребезгу контактов и как с ним бороться программным способом.
Если есть вопросы и предложения по этому уроку, пишите комментарии буду рад ответить на ваши вопросы.
Мой блог в ЖЖ: http://evgenij-byvshev.livejournal.com