Управління 595 зсувовими регістрами за допомогою AVR по SPI
Насправді керувати зсувними регістрами за допомогою AVR мікроконтролера досить просто. Більшість мікроконтролерів мають SPI (послідовний периферійний інтерфейс). Зсувний регістр є периферійним пристроєм, що підключається через послідовний порт. Все, що нам потрібно зробити, це підключити до мікроконтролера зсувний регістр і написати досить просту програму. Про зсувні регістри та принципи їх роботи можна прочитати тут.
Вітчизняним аналогом популярної мікросхеми 74HC595 є вітчизняна КР1564ІР52 (правда першу знайти буває простіше у нас).
В підключенні контактів Clear і Enable до мікроконтролера потреби немає. Якщо використовується мало зсувних регістрів, можна подати на них нулі, закривши їх. Я просто підключив вивід SCLR до VCC і вивід Enable до GND.
Після цього у нас залишилося три виводи: SI, SCK і RCK. Можна подавати сигнал на виводи SCK і RCK по одному проводу, але це вже інша тема. Я підключив ці контакти до ATmega168. Зверніть увагу, що виводи SCK і RCK для обох зсувних регістрів пов'язані між собою. Вивід SI першого чипа підключений до мікроконтролера. Вивід QH першого зсувного регістра підключений до виводу SI другого чипа.
Робота з SPI
Робота з SPI досить проста. Необхідно зробити кілька речей для роботи з ним:
1. Налаштуйте використовувані контакти як вихід.
2. Увімкніть SPI в режимі Master
3. Подайте низький рівень на SS
4. Передайте команди в SPDR, він автоматично підготує і передасть їх зсувному регістру.
5. Дайте команду зсувному регістру для виконання отриманих команд.
В якості SPI виводів можна використовувати тільки заздалегідь визначені виводи, які можна дізнатися в документації.
#define SHIFT_REGISTER DDRB #define SHIFT_PORT PORTB #define DATA (1<< PB3) //MOSI (SI) #define LATCH (1<< PB2) //SS (RCK) #define CLOCK (1<< PB5) //SCK (SCK) SHIFT_REGISTER |= (DATA | LATCH | CLOCK); //Встановити контрольні виводи як виходи SHIFT_PORT &= ~(DATA | LATCH | CLOCK); //Встановити контрольні виводи в нуль
SPI увімкнеться в режимі Master однією рядком:
SPCR = (1 << SPE) | (1 << MSTR); //Запустити SPI як Master
На пін SS необхідно подати низький рівень. У документації на мікроконтролер написано: "Коли SPI увімкнено в режимі Master, SS не контролюється автоматично. Це повинно бути зроблено користувачем". Це робиться так:
//Витягнути LATCH вниз (Важливо: це необхідно, щоб почати передачу SPI!) SHIFT_PORT &= ~LATCH;
Зараз ми пишемо наші команди для регістра зсуву:
//Зсунути деякі дані SPDR = 0b01010101; //Це має запалити чергуючі світлодіоди //Чекати, поки процес SPI не закінчиться while(!(SPSR & (1<< SPIF)));
Поки дані зберігаються в регістрі зсуву світлодіоди не загоряться:
//Переключити затвор, щоб скопіювати дані в регістр зберігання SHIFT_PORT |= LATCH; SHIFT_PORT &= ~LATCH;
Готова програма:
#include "avr/io.h" #define SHIFT_REGISTER DDRB #define SHIFT_PORT PORTB #define DATA (1<< PB3) //MOSI (SI) #define LATCH (1<< PB2) //SS (RCK) #define CLOCK (1<< PB5) //SCK (SCK) int main(void) { //Налаштування IO SHIFT_REGISTER |= (DATA | LATCH | CLOCK); //Встановити контрольні виводи як виходи SHIFT_PORT &= ~(DATA | LATCH | CLOCK); //Встановити контрольні виводи в нуль //Налаштування SPI SPCR = (1<< SPE) | (1<< MSTR); //Запустити SPI як Master //Витягнути LATCH вниз (Важливо: це необхідно, щоб почати передачу SPI!) SHIFT_PORT &= ~LATCH; //Зсунути деякі дані SPDR = 0b01010101; //Це має запалити чергуючі світлодіоди //Чекати, поки процес SPI не закінчиться while(!(SPSR & (1<< SPIF))); //Зсунути ще деякі дані, оскільки у мене підключені два зсувних регістри SPDR = 0b01010101; //Це має запалити чергуючі світлодіоди //Чекати, поки процес SPI не закінчиться while(!(SPSR & (1<< SPIF))); //Переключити затвор, щоб скопіювати дані в регістр зберігання SHIFT_PORT |= LATCH; SHIFT_PORT &= ~LATCH; while(1) { //Цикл вічно } }
Список радіоелементів
Обозначення | Тип | Номінал | Кількість | Примітка |
---|---|---|---|---|
IC | МК AVR 8-біт |
ATmega8
|
1 | |
U, U | Зсувний регістр |
CD74HC595
|
2 | |
R | Резистор | 16 | Номінал вибирається під тип світлодіода | |
LED | Світлодіод | 16 |