Коль поможете мне разобраться в библиотеке ShiftRegister75HC595
- Войдите на сайт для отправки комментариев
Доброго времени суток уважаемые.
Строю я "хитроумный" девайс для промышленных задач. Да что там хитрого, тайминги и куча релюшек с индиккацией. Все как полагается на сдвиговых регистрах.
Библиотека любезно предоставлена забугоным парнем отсюда http://shiftregister.simsso.de/
Собственно начав ей пользоваться я получил то что мне нужно. Указываешь пин например 35-й и тебе на 35-м выводе синал (3-й пин пятого регистра если считать от 1)
Но при использовании библиотеки напоролся на проблему когда включая первый вывод я вижу что он третий, а после вовсе непонятно где. А выводов не мало - 60.
На подключение пока не грешу. Все пины включаются и выключаются разом прекрасно что видно из куска кода библиотеки. А вот по отдельности мне не понятно совбственно функция:
void ShiftRegister74HC595::set(int pin, uint8_t value) { if (value == 1) _digitalValues[pin / 8] |= 1 << (pin % 8); else _digitalValues[pin / 8] &= ~(1 << (pin % 8)); setAll(_digitalValues); }
Она так и называется sr.set(pin, value);
Я хочу разобраться в этом чтобы иметь полное до костей представление о работе библиотеки. По сути можно и свою накатать. Сделать несколько массивов и сливать в регистры определяя число и запоминая прошлые значения пересдвигая данные. Ведь нам нужно сохранить состояния на других выводах их значения.
Тут у нас массив. Адрес ячейки который непонятно зачем делиться на 8. Понятно что вычисляется ячейка в массиве этим делением но зачем именно делить я не понял. А вы? Дальше то что определяется равно значение единице или нет понятно. а вот символ символы |= и << я не понял. И информации как таковой не нашел. А вот с кусочком (pin % 8) мне все понятно. Это модульный делитель и он делит определение конкретного пина микросхемы. Но как он ее находит. Микросхему эту. Второй это или третий сдвиговик мне не ясно.
Все косточки здесь : https://github.com/Simsso/Shift-Register-74HC595-Arduino-Library/blob/master/ShiftRegister74HC595.cpp
Кто что подскжет?
сбросить или установить пин - вычисляем ( по номеру пина ) какой это номер регистра
- вычисляем ( по номеру пина ) какой это пин в регистре
- сбрасываем или устанавливаем пин , перезаписываем все регистры
Адрес ячейки который непонятно зачем делиться на 8.
- это определение номера регистра , в котором сидит нужный пин
А вот с кусочком (pin % 8) мне все понятно. Это модульный делитель и он делит определение конкретного пина микросхемы. Но как он ее находит.
- это определение номера в рамках вычисленного регистра
|= 1 << (pin % 8);
- установка пина в 1
&= ~(1 << (pin % 8));
- сброс пина в 0
три регистра по 8 пинов , всего = 24
нужно изменить состояние пина 19....
19 / 8 = 2 , второй регистр
19 % 8 = 3 , третий пин второго регистра
в
ShiftRegister74HC595::ShiftRegister74HC595(int numberOfShiftRegisters, int serialDataPin, int clockPin, int latchPin)
правильно задал значение
int numberOfShiftRegisters
?
Благодарю за ответ. Стало понятно что деля на 8 он считает номер регистра с 0. Т.е. 1-й это нулевой регистр. Ответ напросился сам.
Меня ввели в заблуждение неизвестные мне операнды |= и &= (или равно, и равно...) а еще этот << как бы добавление \ замещение. Запутался. Но то что нужно было понять, я понял.
У меня физически их 8, я там и указал 8.
_digitalValues[pin / 8] |= 1 << (pin % 8);
в байте номер "pin / 8" пин "pin % 8" установить в 1
....... |= 1 << (pin % 8); - это прелести С++
_digitalValues[pin / 8] |= 1 << (pin % 8);
это >>>>>>>>>>>>
_digitalValues[pin / 8] = _digitalValues[pin / 8] | ( 1 << (pin % 8) );
|= , &= - это тоже прелести С++
Похоже на двухстороннюю функцию. Автор так все исскусно сократил.
Теперь все понятно. Еще раз спасибо!
UserDead, спасибо за ссылку, 3 дня голову ломаю как лучше это сделать и либу не мог найти, дома проверю :)
Нет.
Засылаете все байты (меняя нужные биты) и выводите их.
И так каждое изменение.
Ага я понял по коду либы, что она ни чего не делает того чего я хочу.
Подскажите тогда, я так понимаю лучше будет иметь масив данных где будут хранится состояния выходов 595, для изменения какого то выхода изменять его значение в масиве, а потом этот масив загружать в 595. Так?
Будет так работать 595?
1.
устанавливаем синхронизацию "защелки" на LOW
2. Циклом For загоняем по очереди 8 значений масива в 595
shiftOut(dataPin, clockPin, MSBFIRST, arr[i]);
3.
"защелкиваем" регистр, тем самым устанавливая значения на выходах
Интересно стало что вам нужно от бибилиотеки. Я вот запутался в свой задаче что полез в реализацию библиотеки. Разобрался и пришел к выводу что все таки косяк был в железе и чуток в софте. Если бы она работала не так как нужно мне пришлось бы переписывать на свою функцию. Я примерно имею представление но до этого не дошло.
Сэкономню я ка немного нервишек и дальше юзаю библиотеку.
Не сильно много кода повторять ShoftOut?!
Ну кому как. Я думаю реализация в библитеке вполне таки практичная. А ненужные функции (если действительно не нужные типа sr.setAllHIGH(); sr.getState(pin); ) То и вырезать можно из CPP файла и место тем самым сЭкономить))
что то не работает эта либа у меня или я что то не понимаю. У меня двое последовательных 595. ВОт код:
я так понимаю этот код должен мигать всеми выходами через пол секунды. Но что то ноль реакции, что может быть не так? распиновка 100% правильная.
определи пины 8 , 12 , 13 как выходы ( по умолчанию все пины - входы )
либа всё делает за нас :)
а если уйти от 13-го пина ? на 11-ый , например....
Я осмелюсь взять на себя отвественность запросить фото разводной части вашей платы с двух сторон. Ну не может быть такого что распиновка вернаи и не работает. Сам вчера мучался и понял что последние три микры неправильно подключены. Хотя тоже был на 100 уверен. Или перепроверьте сами. ST и SH на всех микрах запаралелены. DS и Q7' легче наизусть выучить по расположению. А для надежности каждую микру можно прозвонить по паралельности ST и SH цепей. Я вообще мучался так: Находил DS а SH и ST тыком искал меняя значения переменных, но знал что они на конкретных пинах запаяны лично мной.
Оно без разницы на каких пинах У меня 4 3 2 пины который 4 - DS. Работает.
Еще нюанс Есть же еще выводы MR и OE с ними тоже надо быть внимательнее. Один знаю питается на Vcc другой на Gnd .
Он: http://arduino.ru/Tutorial/registr_74HC595
10 и 13-й пины. Безних не работает. Мб похожая ситуация?! А как насчет кондера в цепи. для стабилизации вроде.
Помните, TTL логика. Питание не просаживается ниже логического? Мб из-за этого например на выводе MR он в постоянно сброшенном виде. Было и такое.
ни чего не даёт.
кондёр стоит. всё на месте и всё хорошо работает этим кодом так что микрухи работают 100 % и подключено тоже всё правильно, а либа где то тупит...
Включите подробный вывод при компиляции в настройках. Мб ошибки есть.
(Файл, Настройки, Показать подробный вывод две галочки)
UserDead, смотрю я на код либы и не до конца понимаю что она делает...
Она может устанавливать значение отдельных выходов на 595? если да, то не пойму где она формирует значения всех регистров.
Допустим сейчас на выходах есть значения 00110101 и я хочу 4 значение перевести из 1 в 0. Остальные значения должна остаться на месте. Она это умеет и где она это делает в либе?
Да. Именно так. Она запоминает значения состояния других выводов и меняет те что вы указываете в переменной pin. Я прямо сейчас работаю с устройством с этой библиотекой. Хранит она все в массиве digitalValues
Вот исполняемый кусочек
Вкратце ответ. Да, и да.
Спасибо за разъяснение моя ошибка крылась в том, что я думал что _numberOfShiftRegisters это количество микросхем :) а не физических выводов :) И ставя 2 я использовал только первые два регистра :)
всё равно что то не так!!!
Вот код который работает
а вот этот не работает
что я делаю не так?
точно ShiftRegister74HC595 sr (16, 8, 12, 11); 16 регистров подключено ?
может быть 2 регистра и пинов управляемых от них = 16 ?
SU-27-16, я теперь опять начинаю путаться :)
подключенно по этой схеме
так тоже не работает
ShiftRegister74HC595 sr (2, 8, 12, 11);
В первой переменной указывается количество регитсров. Кол-во выводов он и так знает на основе количества регистров. Если регистра 2 то указать надо 2. Включите вывод логов. Мб Что-то не так. Ну не может быть на ровном месте не работать на таком простом примере.
Количество пинов НЕ указывается в инициализации.
Методом тыка не пробовали ради прикола поменять местами ST и SH хоть что-то есть на выходах?
orcsin , какой регистр второму передаёт сдвиг информации - не перепутал ?
выводы DS и Q7'.......
фантастика....
сделай на одном регистре... для проверки....
я выше показывал код простой, и все диоды на обоих 595 работают
два раза шифтаут делаю что бы прошло 8+8 значений. и всё работает
померяйся пипис.... , ой , библиотеками с UserDead - откуда он скачал...
может быть у тибя глЮчьная библа ? ( бывает )
Мде. Я качал с gitHub так что ему тоже советую. На оф сайте есть ссылка на него. Мне кажется он где-то косячит. ВОт нИверю я в его избранность. У меня работает (и как понимаю у большинства) у него нет.
щас попробую в протеусе повторить
проэмулировал в Протеусе. Не заработало :(
по схеме поставил кондёр 1 mF, удалил его - заработало, поставил 1nF тоже работает.
Есть у меня большое подозрение что я не тот кондёр поставил :) Протеус при кондёре выше 100nF перестаёт работать, видимо что то знает :) завтра выпаяю его и посмотрю.
дык , блииин !!!!!!
1 mF - валит фронты сигнала .....
убрал кондёр, теперь начало хоть как то работать, то есть мигать, НО что то не понятно. Использую вот этот код
Но поотдельности пины работать не хотят :(
А так не работает, хотя по сути это же одно и тоже. Что не так?
дык , блииин !!!!!!
1 mF - валит фронты сигнала .....
А кондёр на латч зачем?
Не знаю уже, вник всё что можно было, но эта либа не работает у меня как должна, но при этом код 2.2. от сюда работает отлично
http://arduino.ru/Tutorial/registr_74HC595. В принципе из 2.2 можно сделать нужную функцию или вобще сделать либу, хотя и та очень хорошо написана, но где подводный камень найти не могу :(
Если не ошибаюсь. Я в своем проекте использую счет от 1 до 8. Если мне надо включить Q0 я пишу 1.
Нет не ошибаюсь, проверил.
А так не работает, хотя по сути это же одно и тоже. Что не так?
Шифт регистр- жто микросхема памяти с последовательным входом и параллельным выходом.
Регистр имеет ёмкость 1 байт то есть 8 бит.
Вы пытаетесь подключить 15 регистров, 15 микросхем, 120 разрядов.
Впечатление что в библиотеке есть ограничение на их количество.
Вы путаете количество регистров с их суммарной разрядностью.
Поставьте вместо 15-ти двойку.
И действительно. Я что-то не заметил. Блин ну так сложно перевести строки в коммертаниях. Так я переведу:
//создание объекта сдвигового регистра (кол-во сдвиговых регистров, пин данных, пин синхронизации, пин защелки)
Типичное недопонимание функций. Так зачем было при выставлении sr.set менять количество сдвиговиков ошибочно принимая их за выводы. написано number of shift registers. Блин
Что-то сомневаюсь на ограничение по количеству регистров. Какая разница сколько их, все сидят на цепочке, только время задвигания данных сыграет роль. Ну и да, память переменной в которой храниться значения состояний. А он в uint8_t. Сколько там ограничение?! 32767
Пробовал я и 2 и 16 писать, ну не хочет.
Вобщем я использовал код 2.2 из http://arduino.ru/Tutorial/registr_74HC595
Работает как часики и меня устраивает.