Arduino:Примеры/ShftOut22
Материал из Онлайн справочника
Перейти к навигацииПерейти к поиску
Содержание | Знакомство с Arduino | Продукты | Основы | Справочник языка Arduino | Примеры | Библиотеки | Хакинг | Изменения | Сравнение языков Arduino и Processing |
Перевод: Максим Кузьмин
Проверка/Оформление/Редактирование: Мякишев Е.А.
Поочередное зажигание 16 светодиодов[1]
Это скетч для платы Arduino и двух сдвиговых регистров 74HC595. Он поочередно зажигает два ряда светодиодов – восемь, подключенных к одному регистру, и восемь, подключенных к другому. Переход от одного светодиода к другому осуществляется двумя способами.
Код
//***************************************************************//
// Название : Поочередное зажигание 16 светодиодов //
// Автор : Кэрлин Мо, Том Иго //
// Дата : 25 октября 2006 года //
// Версия : 1.0 //
// Примечания : Код для использования с двумя о сдвиговым //
// : сдвиговыми регистрами 74РС595 //
//***************************************************************//
// Контакт, подключенный к контакту ST_CP на 74HC595:
int latchPin = 8;
// Контакт, подключенный к контакту SH_CP на 74HC595:
int clockPin = 12;
// Контакт, подключенный к контакту DS на 74HC595:
int dataPin = 11;
// для хранения информации, которая будет передана функции,
// отвечающей за перемещение битов:
byte data = 0;
void setup() {
// выставляем latchPin в режим OUTPUT,
// поскольку он будет использоваться в блоке loop():
pinMode(latchPin, OUTPUT);
}
void loop() {
// функция, мигающая всеми светодиодами;
// параметры – количество миганий и пауза между ними:
blinkAll_2Bytes(1,500);
// поочередно зажигаем каждый светодиод с помощью функции A:
for (int j = 0; j < 8; j++) {
// задаем контакту latchPin значение LOW и оставляем так,
// пока все данные не будут переданы:
digitalWrite(latchPin, 0);
// красные светодиоды:
lightShiftPinA(7-j);
// зеленые светодиоды:
lightShiftPinA(j);
// возвращаем latchPin значение HIGH, сообщая чипу,
// что ему больше не нужно прослушивать входящую информацию:
digitalWrite(latchPin, 1);
delay(1000);
}
// поочередно зажигаем каждый светодиод с помощью функции B:
for (int j = 0; j < 8; j++) {
// задаем контакту latchPin значение LOW и оставляем так,
// пока все данные не будут переданы:
digitalWrite(latchPin, 0);
// красные светодиоды:
lightShiftPinB(j);
// зеленые светодиоды:
lightShiftPinB(7-j);
// возвращаем latchPin значение HIGH, сообщая чипу,
// что ему больше не нужно прослушивать входящую информацию:
digitalWrite(latchPin, 1);
delay(1000);
}
}
// чтобы перемещаться по контактам, эта функция
// использует побитовые расчеты:
void lightShiftPinA(int p) {
// задаем локальную переменную:
int pin;
// эта строчка кода использует побитовый оператор;
// перемещение бита влево при помощи «<<» – это то же самое,
// что и умножение десятичного числа на «2»:
pin = 1<< p;
// перемещаем биты:
shiftOut(dataPin, clockPin, pin);
}
// чтобы перемещаться по контактам, эта функция использует тот факт,
// что каждый бит в байте в два раза больше, чем предыдущий:
void lightShiftPinB(int p) {
// задаем локальную переменную:
int pin;
// начинаем с pin = 1; таким образом, если задать этой переменной
// значение «0», это зажжет светодиод номер «0»:
pin = 1;
for (int x = 0; x < p; x++) {
pin = pin * 2;
}
// перемещаем биты:
shiftOut(dataPin, clockPin, pin);
}
// «сердце» программы;
// эта функция передает 8 бит данных (первым идет самый старший бит);
// передача осуществляется на возрастающем фронте тактового сигнала:
void shiftOut(int myDataPin, int myClockPin, byte myDataOut) {
// аналог блока setup(), но внутри функции:
int i=0;
int pinState;
pinMode(myClockPin, OUTPUT);
pinMode(myDataPin, OUTPUT);
// стираем все, чтобы подготовить
// сдвиговый регистр к передаче битов:
digitalWrite(myDataPin, 0);
digitalWrite(myClockPin, 0);
// выполняется для каждого бита в байте myDataOut;
// обратите внимание, что в цикле for() ниже
// СЧЕТ ИДЕТ В ОБРАТНОМ НАПРАВЛЕНИИ, и это значит, что значение
// «%00000001» или «1» будет соответствовать контакту Q0:
for (i=7; i>=0; i--) {
digitalWrite(myClockPin, 0);
// если значение было передано переменной myDataOut и проверка
// битовой маской прошла успешно... то есть если i=6
// и наше значение это «%11010100», код сравнит его с «%01000000»,
// а затем запишет в pinState значение «1»:
if ( myDataOut & (1<<i) ) {
pinState= 1;
}
else {
pinState= 0;
}
// задаем этому контакту HIGH или LOW в зависимости от pinState:
digitalWrite(myDataPin, pinState);
// если тактовый контакт получает значение HIGH,
// сдвиговый регистр перемещает биты:
digitalWrite(myClockPin, 1);
// после перемещения битов задаем контакту для данных
// значение «0», чтобы избежать «просачивания» данных:
digitalWrite(myDataPin, 0);
}
// останавливаем перемещение битов:
digitalWrite(myClockPin, 0);
}
// эта функция мигает всеми светодиодами, подключенными к 2 регистрам;
// переменная «n» – это то, сколько раз нужно мигнуть, а «d» – сколько
// должна длиться пауза между миганиями; запускается с момента,
// когда светодиоды не горят – чтобы визуальный эффект
// от первого мигания был полным:
void blinkAll_2Bytes(int n, int d) {
digitalWrite(latchPin, 0);
shiftOut(dataPin, clockPin, 0);
shiftOut(dataPin, clockPin, 0);
digitalWrite(latchPin, 1);
delay(200);
for (int x = 0; x < n; x++) {
digitalWrite(latchPin, 0);
shiftOut(dataPin, clockPin, 255);
shiftOut(dataPin, clockPin, 255);
digitalWrite(latchPin, 1);
delay(d);
digitalWrite(latchPin, 0);
shiftOut(dataPin, clockPin, 0);
shiftOut(dataPin, clockPin, 0);
digitalWrite(latchPin, 1);
delay(d);
}
}