Код на языке С, при котором нажимая на одну кнопку выполняется только одно действие, нажимая на другую кнопку – другое.
Для примера, создадим код на Си, при котором на каждой кнопке будет гореть свой светодиод или несколько светодиодов.
Код на языке СИ с подключение 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);
Наиболее удобно использовать последний вариант – он краток, в нем используется комбинация из операций логического ИЛИ и присваивания.



