Уважаемые пользователи Голос!
Сайт доступен в режиме «чтение» до сентября 2020 года. Операции с токенами Golos, Cyber можно проводить, используя альтернативные клиенты или через эксплорер Cyberway. Подробности здесь: https://golos.io/@goloscore/operacii-s-tokenami-golos-cyber-1594822432061
С уважением, команда “Голос”
GOLOS
RU
EN
UA
evgenij-byvshev
7 лет назад

Программирование микроконтроллеров. Часть 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
        }
    }
}

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

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

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

Если есть вопросы и предложения по этому уроку, пишите комментарии буду рад ответить на ваши вопросы.

Часть 1

Мой блог в ЖЖ: http://evgenij-byvshev.livejournal.com

17
307.075 GOLOS
На Golos с February 2017
Комментарии (10)
Сортировать по:
Сначала старые