Управление сдвиговым регистром на мк Atmega8 для C
Иногда необходимо управлять большим количеством выходов. Примером могут служить проекты разных светодиодных табло бегущих огней и тп. Покупать микроконтроллер с большим количеством выводов для такой задачи – нерационально и дорого. Но выход есть либо использовать матрицы либо использовать сдвиговые регистры. В этой статье мы рассмотрим сдвиговые регистры на примере 74HC595.
Взглянем на его внутреннюю структуру:
Видно, что он состоит из 8 триггеров, которые передают данные вперед друг другу с помощью импульса на SHIFT CLOCK. Импульс на выводе LATCH CLOCK выводит записанные данные на выхода, вывод RESET – сбрасывает выхода в нулевое состояние, а вывод OE разрешает вывод данных, если на нем высокий уровень, то на выходах будет Hi-Z состояние, если низкий – то что записано в регистр.
Посмотрим внимательно на HC595:
Выводы VCC и GND – питание, Qa-Qh – выхода (SQh применяется для каскадирования), A – вход данных, SHIFT CLOCK – запись бита на входе, LATCH CLOCK – запись в регистр введенной информации, OUTPUT ENABLE – вывод для разрешения выхода, (если на нем логическая единица, то на выходе будет Hi-Z состояние, если 0 – то то, что записалось), RESET – обнуляет регистр. Теперь словесно опишу работу с данной микросхемой. Выставляем данные на вывод A, далее фронтом импульса на SHIFT CLOCK записываем все 8 бит. Далее даем импульс на вывод LATCH CLOCK чтобы записать введенную информацию. Если вывод OUTPUT ENABLE сидит на земле, то на выходах Qa-Qh можно наблюдать введенные данные. Если вам мало 8 выводов, то сдвиговые регистры можно каскадировать с помощью вывода SQh и получить практически любое конечное количество портов ограниченное только временной задержкой на запись данных в каскад регистров:
Схема включения 4 сдвиговых регистров каскадом на 32 выхода
С увеличением количества сдвиговых регистров увеличиться время, необходимое, чтобы загнать в них цепочку данных. Итак, с помощью 74HC595 и 4-х выводов микроконтроллера можно управлять конечным количеством светодиодов.
Вот сам код программы:
Код для 2х регистров 16бит 16каналов.
Code
#include <avr/io.h>
#define DATA 0 // Подключаем к порту PD0 ножку данных сдвигового регистра
#define CLK 1 // Подключаем к порту PD1 ножку тактовых импульсов сдвигового регистра
#define Latch 2 // Подключаем к порту PD2 ножку защёлки сдвигового регистра
void pause (unsigned int a){
unsigned int i;
for (i=a;i>0;i--)
; // Пустой цикл
}
void send_data (unsigned int data){
unsigned char i;
for (i=0;i<16;i++){
if ((data&0x8000)==0x00) PORTD&=~_BV(DATA); // Выставляем данные на PD0
else PORTD|=_BV(DATA);
asm("nop");
PORTD|=_BV(CLK); // Импульс на CLK
asm("nop");
PORTD&=~_BV(CLK);
asm("nop");
data=(data<<1);
}
PORTD|=_BV(Latch); // Импульс на Latch clock
asm("nop");
PORTD&=~_BV(Latch);
}
int main(void){
unsigned int data=0;
PORTD=0x00; // Первоначально выключаем выхода
DDRD=0x07; // PD0-PD2 как выхода
// data=65530;
data=0x0fff;
while (1){
//send_data(data); // Отправить данные
send_data (0xffff); // Отправить данные
pause(50);
}
return 1;
}
Код для 4х регистров 32бита 32канала.
Code
#include <avr/io.h>
#define DATA 0 // Подключаем к порту PD0 ножку данных сдвигового регистра
#define CLK 1 // Подключаем к порту PD1 ножку тактовых импульсов сдвигового регистра
#define Latch 2 // Подключаем к порту PD2 ножку защёлки сдвигового регистра
void pause (unsigned int a){
unsigned int i;
for (i=a;i>0;i--)
; // Пустой цикл
}
void send_data (long int data){
unsigned char i;
for (i=0;i<32;i++){
if ((data&0x80000000)==0x00) PORTD&=~_BV(DATA); //Выставляем данные на PD0
else PORTD|=_BV(DATA);
asm("nop");
PORTD|=_BV(CLK); //Импульс на CLK
asm("nop");
PORTD&=~_BV(CLK);
asm("nop");
data=(data<<1);
}
PORTD|=_BV(Latch); // Импульс на Latch
asm("nop");
PORTD&=~_BV(Latch);
}
// Использовать вот так: send_data (0x12345678);
int main(void){
unsigned int data=0;
PORTD=0x00; // Первоначально выключаем выхода
DDRD=0x07; // PD0-PD2 как выхода
// data=65530;
data=0x0fff;
while (1){
//send_data(data); // Отправить данные
send_data (0xffffffff); // Отправить данные
pause(50);
}
return 1;
}