Код на С (Си) несколько кнопок каждая со своим действием для Atmega88

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

Код на языке СИ с подключение 2-х кнопок (можно подключить хоть сколько), написан в AtmelStudio4 и прошит в Atmega88 с помощью 5 проводков и PonyProg2000:

#include <avr/io.h>

#include "delay.h"
#include "delay.c"

#define F_CPU 16000000UL // 1 MHz clock speed

int main(void)
{
DDRC = 0xFF; //Nakes PORTB as Output
DDRB = 0b0000110;  // Конфигурируем вывод порта PB1 - как вход
PORTB |= ( 1 << 1 ); // Подключаем к PB1 подтягивающий резистор на плюс питания
PORTB |= ( 1 << 2 ); // Подключаем к PB2 подтягивающий резистор на плюс питания
char in = 1;  // Объявляем переменную in и записываем в неё число 1
char ip = 0; // Объявляем переменную in и записываем в неё число 0 - будет показывать какая кнопка включена

while(1) // Бесконечный цикл
{

if (!(PINB & (1<<PINB1)) && in == 1 )    /* если PB1 стал равен нулю и значение in при этом = 1, то мы поймали замыкание кнопки на входе, т. е. перепад из 1 в 0 */
         {
in = 0;    // 1. Стало быть уровень входного сигнала стал равен нулю
ip = 1;    // Первая кнопка нажата
_delay_ms(100);    // 2. Задержка 100мс. Выжидаем окончания дребезга контактов
          }
   // Теперь ждём момента, когда копка будет отпушена:
if (PINB & (1 << PINB1) && in == 0)    /* если PB1 стал равен единице и in = 0,
то мы поймали на входе размыкание кнопки, т. е. перепад из 0 в 1 */
{
in = 1;    // В этот момент уровень входного сигнала стал равен нулю
_delay_ms(100);    /* Задержка 100мс - опять ждём окончания дребезга,
больше ничего в момент размыкания кнопки делать не будем */
}


if (!(PINB & (1<<PINB2)) && in == 1 )    /* если PB2 стал равен нулю и значение in при этом = 1, то мы поймали замыкание кнопки на входе, т. е. перепад из 1 в 0 */
         {
in = 0;    // 1. Стало быть уровень входного сигнала стал равен нулю
ip = 2;    // Вторая кнопка нажата
_delay_ms(100);    // 2. Задержка 100мс. Выжидаем окончания дребезга контактов
          }
   // Теперь ждём момента, когда копка будет отпушена:
if (PINB & (1 << PINB2) && in == 0)    /* если PB1 стал равен единице и in = 0,
то мы поймали на входе размыкание кнопки, т. е. перепад из 0 в 1 */
{
in = 1;    // В этот момент уровень входного сигнала стал равен нулю
_delay_ms(100);    /* Задержка 100мс - опять ждём окончания дребезга,
больше ничего в момент размыкания кнопки делать не будем */
}

if (ip == 1)
{
PORTC = 0b0000010;    // 3. Включаем светодиод на ножке PC1
}

if (ip == 2)
{
PORTC = 0b0000100;    // 3. Включаем светодиод на ножке PC2
}

}
}

Схема соединения:

Примечание:
Скачать черновик на си и hex код:
– в zip архиве.
– в tar.gz архиве.

Примечание:
—————-
Для числа 1 (Dec, в десятичной системе 1) – 00000001 (Bin, в двоичной системе 0b00000001):

1 << 0 = 1 (00000001);
1 << 1 = 2 (00000010);
1 << 2 = 4 (00000100)
1 << 5 = 32 (00100000);
1 >> 2 = 0 (00000000).

Сдвиг влево на один разряд выполняет умножение числа на 2, а сдвиг вправо – деление числа на 2.

————–
Чтобы для данного примера записать “1” в бит с номером 5 и загрузить результирующий байт в регистр порта PORTB (установка высокого уровня для канала PB5) можно использовать любую из следующих, равнозначных по результату конструкций операторов:

PORTB = PORTB | 32;
PORTB = PORTB | (1 << 5);
PORTB = PORTB | (1 << PB5);
PORTB |= (1 << PB5);

Наиболее удобно использовать последний вариант – он краток, в нем используется комбинация из операций логического ИЛИ и присваивания.

Добавить комментарий