Странно но во многих радиомагазинах отсутствуют логические микросхемы – скорее всего в современной микроэлектронике их заменили обычные многофункциональные микроконтроллеры, например Atmega и PIC и др. Возможно я ошибаюсь…
Но давайте создадим, наприме, логическую микросхему К155ЛА3 (И-НЕ) на Atmega88 (на любом другом микроконтроллере всё будет абсолютно аналогично!).
Всё логика похожа на простую схему с кнопками и светодиодами!
Входы – это кнопки. Светодиод – выход!
Недавно я писал запись – “gameforstreet.ru/kod-na-c-neskolko-knopok-atmega88/” (Код на С (Си) несколько кнопок каждая со своим действием для Atmega88) – вот на основе неё и создадим логический элемент И-НЕ.
Микросхема К155ЛА3 (И-НЕ) работает:
Изначально на её выводах стоит напряжение в 3 В, а на выходе 0 В.
Таблица истинности элемента И-НЕ:
То есть по умолчанию (без какого-либо воздействия, начальное состояние) микросхема К155ЛА3 (И-НЕ) работает как – на обоих входах логическая единица, а на выходах логический ноль.
То есть К155ЛА3 (И-НЕ) регулируется – 0 (логическим нолём) – если на один из выходов подать 0, то выход измениться на 5 В (логическая единица). Также если на оба выхода подать 0 В – будет 5 В на выходе.
Вот видео теста К155ЛА3 (И-НЕ):
“rutube.ru/video/c2bc9ad09c0588855301feb30fda4e1d/”
Давайте создадим данный элемент И-НЕ с помощью двух кнопок (два входа) и светодиода (выход).
Схема будет следующая:
Если подумать, то логика для логических элементов должна быть следующая:
state1 = digitalRead(switch1);
state2 = digitalRead(switch2);
if (state1 ==1 && state2 ==1){outcome = 1;} // Логический элемент И
else {outcome = 0;}
if (state1 ==1 || state2 == 1){ outcome = 1;} // Логический элемент ИЛИ
else {outcome = 0;}
if (state1 ==1 && state2 ==1)(outcome = 0;} // Логический элемент И-НЕ
else {outcome = 1;}
if (state1 == 0 || state2 == 0){outcome = 0;} // Логический элемент ИЛИ-НЕ
else {outcome = 1;}
Таблица истинности для проверки:
—————————————————————
Теперь перейдем к программированию микросхемы Atmega88, я буду программировать в Linux Rosa FResh R12 Plasma, программу буду использовать AVR Burn-O-Mat, фьюзы будут стандартные (на PonyProg2000 будут аналогичными):
Как скачать и настроить AVR Burn-O-Mat, но можете выбрать PonyProg2000 или другую прогу для прошивки: “https://gameforstreet.ru/linux-rosa-fresh-r11-avrdude-programmiruem-atmega88-i-dr/”
Писать код на Си (С) буду в MPLAB X IDE v5.35 – как установить на Linux читайте здесь: “gameforstreet.ru/proshivaem-pic-na-linux-video/”
—————————–
Один элемент И-НЕ на Atmega88
—————————–
Вход PB1 и PB2, выход PC1
Тогда код на Си (С) для элемента И-НЕ следующий (компилировал код в MPLAB X IDE v5.35 – где скачать и как установить здесь “gameforstreet.ru/proshivaem-pic-na-linux-video/”):
#include <xc.h>
#define F_CPU 16000000UL // 1 MHz clock speed
int main(void)
{
DDRC = 0xFF; //PORTС как выводы
DDRB = 0b0000110; // Конфигурируем вывод порта PB1 и PB2 - как вход
PORTB |= ( 1 << 1 ); // Подключаем к PB1 подтягивающий резистор на плюс питания
PORTB |= ( 1 << 2 ); // Подключаем к PB2 подтягивающий резистор на плюс питания
while(1)
{
if ((PINB & (1<<PINB1)) && (PINB & (1<<PINB2)) )
{
PORTC = 0b0000000;
}
else
{
PORTC = 0b0000010;
}
}
}
Скачать файл hex и с для логического элемента И-НЕ:
– скачать в формате tar.gz
– скачать в формате zip
—————————–
Два элемента И-НЕ на Atmega88
—————————–
Вход PB1 и PB2, выход PC1
Вход PB3 и PB4, выход PC2
#include <xc.h>
#define F_CPU 16000000UL // 1 MHz clock speed
int main(void)
{
DDRC = 0xFF;
DDRB = 0b0011110;
PORTB |= ( 1 << 1 );
PORTB |= ( 1 << 2 );
PORTB |= ( 1 << 3 );
PORTB |= ( 1 << 4 );
while(1)
{
if ((PINB & (1<<PINB1)) && (PINB & (1<<PINB2)) )
{
//PORTC = 0b0000000;
PORTC &= ~(1 << PC1);
}
else
{
//PORTC = 0b0000010;
PORTC |= (1 << PC1);
}
if ((PINB & (1<<PINB3)) && (PINB & (1<<PINB4)) )
{
//PORTC = 0b0000000;
PORTC &= ~(1 << PC2);
}
else
{
//PORTC = 0b0000100;
PORTC |= (1 << PC2);
}
}
}
Скачать файл hex и с для двух логических элементов И-НЕ на одной Atmega88:
– скачать в формате tar.gz
– скачать в формате zip
—————————–
Три элемента И-НЕ на Atmega88
—————————–
Вход PB1 и PB2, выход PC1
Вход PB3 и PB4, выход PC2
Вход PB0 и PB5, выход PC3
#include <xc.h>
#define F_CPU 16000000UL // 1 MHz clock speed
int main(void)
{
DDRC = 0xFF;
DDRB = 0b0111111;
PORTB |= ( 1 << 0 );
PORTB |= ( 1 << 1 );
PORTB |= ( 1 << 2 );
PORTB |= ( 1 << 3 );
PORTB |= ( 1 << 4 );
PORTB |= ( 1 << 5 );
while(1)
{
if ((PINB & (1<<PINB1)) && (PINB & (1<<PINB2)) )
{
//PORTC = 0b0000000;
PORTC &= ~(1 << PC1);
}
else
{
//PORTC = 0b0000010;
PORTC |= (1 << PC1);
}
if ((PINB & (1<<PINB3)) && (PINB & (1<<PINB4)) )
{
//PORTC = 0b0000000;
PORTC &= ~(1 << PC2);
}
else
{
//PORTC = 0b0000100;
PORTC |= (1 << PC2);
}
if ((PINB & (1<<PINB0)) && (PINB & (1<<PINB5)) )
{
//PORTC = 0b0000000;
PORTC &= ~(1 << PC3);
}
else
{
//PORTC = 0b0001000;
PORTC |= (1 << PC3);
}
}
}
Скачать файл hex и с для двух логических элементов И-НЕ на одной Atmega88:
– скачать в формате tar.gz
– скачать в формате zip
Примечание 1:
При создании светофора:
Заменил логические элементы микросхемой Atmega88 (можно любой другой, не важно, так как работу микросхема будет выполнять минимальную – заменять логику).
Для светофора нужна 2 входа – это 0 и 1 – и 4 выхода, то есть для 4-ёх состояний светофора нам понадобится счётный триггер с двумя триггерами:
01 – горит зелёный сигнал.
10 – горит жёлтый сигнал вместе с зелёным (или можно заменить мигающим зелёным.
11 – горит красный сигнал.
00 – горит жёлтый сигнал.
Код программировал на языке С в программе MPLAB X IDE 5.35 (как установить на Linux Rosa Fresh 12 или 13 читайте здесь: “gameforstreet.ru/mplab-na-linux-rosa-fresh/” и “gameforstreet.ru/mplab-na-linux-rosa-fresh-12-plasma/”).
Код на С получился следующий:
#include <xc.h>
#define F_CPU 16000000UL // 1 MHz clock speed
int main(void)
{
DDRC = 0xFF; //PORTC выходы
DDRB = 0b0000110; // PB1 и PB2 - входы
//PORTB |= ( 1 << 1 ); // не использовал, но можно включить подтягивающий резистор на PB1, тогда вход будет регулироваться минусом, в примере ниже регулируется плюсом.
//PORTB |= ( 1 << 2 ); // не использовал, но можно включить подтягивающий резистор на PB2, тогда вход будет регулироваться минусом, в примере ниже регулируется плюсом.
while(1)
{
if ((PINB & (1<<PINB1)) && (PINB & (1<<PINB2)) ) //когда на входах PB1 и PB2 значение 1, то есть "+" напряжение
{
PORTC = 0b0000000;
}
if (!(PINB & (1<<PINB1)) && (PINB & (1<<PINB2)) ) //когда на входе PB1 "-", а на PB2 находится "+" напряжение
{
PORTC = 0b0000010;
}
if ((PINB & (1<<PINB1)) && !(PINB & (1<<PINB2)) ) //когда на входе PB1 "+", а на PB2 находится "-" напряжение
{
PORTC = 0b000100;
}
if (!(PINB & (1<<PINB1)) && !(PINB & (1<<PINB2)) ) //когда на входах PB1 и PB2 значение 0, то есть "-" напряжение
{
PORTC = 0b001000;
}
}
}
Скачать hex файл и файл на С можно – здесь – скачать:
– в формате tar.gz
– в формате zip
Схема подключения получилась следующая:
Для подачи сигнала от счётного триггера к микросхеме пришлось использовать реле на 5 В:
Здесь пришлось использовать два источника питания (И1 и И2) на схеме. И1 – это пауербанк, а И2 – блок аккумуляторных батареек. Из-за того, что схема потребляет много силы тока (скорее всего из-за двух реле).
На схеме мультивибратор питается от блока батареек на 5 В, а вся остальная схема от пауербанка на 5 В – между собой они объединены общим минусовым проводом (если хотите использовать в схемах несколько источников питания – объединяйте их минуса).
Паувербанк можно также заменить на блок батареек.











