Бывают случаи когда портов AVR не хватает, а тратить деньги на более мощный мк не хочется — тут нам поможет микросхема 74HC165.
Даташит на микросхему 74HC165 Скачали раз
Микросхема 74HC165 — сдвиговый регистр, преобразующий параллельный входной сигнал в последовательный выходной. Она позволяет увеличивать количество цифровых входов микроконтроллера.
Назначение выводов:
- Vcc — питание
- GND — земля
- PL— защёлка
- CP— тактовый вход
- D0-D7— входы, состояние которых считывается в регистр
- Q7— последовательный вывод
- Q7— инверсный вывод, на нём идут биты с Q7, но инвертированные
- DS— последовательный ввод; к нему можно подсоединить вывод QH второго регистра, получив каскадное подключение
- CE— Clock Inhibit, или инвертированный Clock Enable; когда на нём 1, тактирование выключено
Чип преобразовывает входящий параллельный сигнал на 8 пинах (Dx) в выходной последовательный сигнал на 1 пине (Q7). Передача синхронна: для такта используется дополнительный пин (CP). Также отдельным пином управляется регистр данных (PL), что позволяет «загружать» параллельный сигнал для последовательного считывания с 8 выходов единовременно.
Алгоритм работы с данной микросхемой очень прост:
1 — Вход SH/LD (сдвиг/загрузка) управляет занесением состояний входов в триггеры — подаём минус на вход — данные загрузятся.
— затем снова установить SH/LD в 1.
2 — Читаем данные с выхода SO.(это будет 8 бит)
3 — Вход CLK прижымаем к земле, задержка, и поотом снова подаём плюс.
4 — возращаемся к 2 пункту и повторяем всё заново — это будет уже 7 бит.
И так далее до последнего бита…
Для примера в Proteus накидал схемку.
На схеме у нас два таких регистра , внимательно посмотрите схему.
Код для работы в CVAVR будет выглядеть следущим образом:
#include
#include
#define CLK PORTB.0 // строб - сдвиг данных
#define SHLD PORTB.1 //защёлкивание входов
#define BIT_IN PINB.2 //вход данных
#define BIT 16 //количество входов-бит ...1 регистр 8 входов
unsigned char data[BIT]; //здесь будем хранить данные
void data_in() //функция чтения данных 74HC165
{
unsigned int i=0;
SHLD=0; //защёлкиваем входные данные
delay_us(300);
SHLD=1;
for( i=0; i<BIT; i++ ) //цикл побитного чтения данных
{
delay_us(100);
data[ i ]=BIT_IN;
CLK=0; //сдвигаем данные
delay_us(100);
CLK=1;
}
}
void programm()
{
data_in();
//выводим данные в порт
PORTB.7 = data[15];
PORTB.6 = data[14];
PORTB.5 = data[13];
PORTB.4 = data[12];
PORTB.3 = data[11];
PORTA.0 = data[10];
PORTA.1 = data[9];
PORTD.0 = data[8];
PORTD.1 = data[7];
PORTD.2 = data[6];
PORTD.3 = data[5];
PORTD.4 = data[4];
PORTD.5 = data[3];
PORTD.6 = data[2];
delay_ms(10);
}
void main(void)
{
// Crystal Oscillator division factor: 1
#pragma optsize-
CLKPR=0x80;
CLKPR=0x00;
#ifdef _OPTIMIZE_SIZE_
#pragma optsize+
#endif
PORTA=0b100;
DDRA= 0b011;
PORTB=0b00000011;
DDRB= 0b11111011;
PORTD=0x00;
DDRD=0xFF;
while (1)
{
programm();
}
}
Как видите нет ничего сложного! Одна функция и все данные с регистров будут занесены в массив. Но не забывайте что чем больше вы подключаете регистров тем медленней опрос!
Результат выполнения симуляции в Proteus.
Готовый пример проекта можно скачать по ссылке ниже.
Скачать проект — расширяем порты AVR или как подключить 74HC165 к AVR Скачали раз


В заголовке сказано про расширение портов, а по факту увеличивается только кол-во выходов. А как быть с входами? Если уже и говорить про расширение портов, то следует рассматривать что-то вроде MCP23S17 или MCP2OS17
*MCP23O17
Обозначение SH/LD возникает «из ниоткуда». Видимо даже ребенок знает что это PL
Первая же картинка, а передней описание выводов!!!
Описание выводов было для схемы) — переписал под даташит, чтоб было понятнее…
Я может чего недопонял, но картинка совершенно не соответствует описанию в теме именования выводов. Логически оно понятно, но какая-то каша.
А к тому же употребление слова «прижЫмаем «… Ну вы поняли — граммар наци негодует.
Все скриншоты и картинки имеют отношение к статье. Какая картинка Вам непонятна?
жи, ши пишем с ‘и’ — вот, что не понятно