Управление сдвиговым регистром
- Войдите на сайт для отправки комментариев
Пнд, 09/06/2014 - 19:34
Здравствуйте! Помоготе разобраться с регистром 74HC595 пожалуйста...
В общем по SPI подключено 2 регистра, один для LCD, другой для индикации(светодиоды).
Начал забрираться как менять значение определенного бита не изменяя существующее значение, нагуглил про оператор сдвига, почитал, вроде всё разжеванно, но всё равно не могу разобраться...
Как считать состояние битов регистра, а затем уже манипулировать "оператором сдвига" для записи нужного значения?
Заранее спасибо!
Как настоящие C-шники:
Arduino - BitwiseAnd
или "Ардуинисто":
Arduino - BitSet
bitWrite
bitRead
bitClear
Спасибо! Почитал по ссылкам, но всё равно не въеду :)
Вот что примерно мне нужно...не очень понимаю как например применить bitRead в моем случае...
Извините за тупости :)
Не очень понятно что-же именно вы хотите. Начните с того что за регистр вы хотите читать (я вообще не понимаю зачем его читать).
Или под "регистром" вы понимаете сам 74HC595?
Один регистр = 8 бит = 1 байт
Тоесть если 2 регистра - значит нужно отправить 2 байта по SPI - и "дернуть" выводом установки состояния - чтобы эти 2 байта оказались на выходах.
Все логично. И правильно. Два регистра - два байта нужно для хранения именно его состояния. С "нужно отправить" - все понятно. Не понятно что вы подразумеваете под " получить текушее состояние регистра", зачем вам bitRead.
Вообщем что и откуда вы хотите прочитать? И зачем?
Я имею ввиду 74HC595...не правильно я изначально выразился :(
По ходу программы у меня будут включаться-отключаться определенные светодиоды подключенные к 74HC595, я хотел узнать как допустим включить определенный байт не задев существующее состояние...
"Не задеть" - не выйдет. В любом случае вы будете каждый раз отсылать новое состояние для каждого выхода. Два байта целиком. Отослать единсвенный бит на регистр - не возможно.
Значит вам нужно, всего-то, завести какую-то переменую. Скажем ту же самую stateRegister (только тип unsigned int был более подходящим). Менять, по потребности в ней биты и каждый раз отсылать ее. Нужно только что-бы переменная не теряла свого значения между проходами loop(). В ней и будет хранится "текущие состояние регистра". Читать ниоткуда не нужно.
Что-бы переменная не "теряла свого значения" - нужно всего-то объявить ее не внутри функции, а вверху скетча (сделать глобальной), либо.... можно и внутри функции, просто дописать, перед ее объявлением ключевое слово static. Тогда ее значение не будет обнулятся между вызовыми функции.
Для того что-бы менять состояние бита в этой переменной, вам не нужны bitRead. Какая разница что в этом бите, если вы хотите установить новое значение? bitWrite именно это и умеет делать. Поменяет один бит в переменной. Остальные не тронет. Потом эту переменную, с обновленным битом, отсылаете на регистр.
Кстати, вы на этом сайте, нашли туториал по 74HC595? Там есть примерчик который на 99% делает то что вам нужно. Если к нему применить рецепт данный выше ("что-бы переменная не теряла свого значения"), то, если я правильно вас понял, он будет на 100% делать то что вам нужно.
Спасибо за подробный ответ!
Если Вы про вот этот http://arduino.ru/Tutorial/registr_74HC595 , то пробегался :)
Спасибо еще раз, теперь все вроде понятно, буду пробовать :)
Нашли туториал для 74HC595? подсказка: идем в шапку сайта, раздел "Программирование" и ищем раздел "Базовые и полезные знания, необходимые для успешного программирования под платформу Arduino..."
И ещё за одно спрошу у гуру :) Если в SPI.transfer() поместить переменную в двоичном виде(int test = B00001111), она переведется в 10 автоматически?
Если Вы про вот этот http://arduino.ru/Tutorial/registr_74HC595 , то пробегался :)
Да, про этот.... запустите у себя самый послединий пример. "Код примера 2.2". Что вы видите на светиках
P.S. Кстати, похоже автор этого примера изначально хотел сделать именно "то что вам нужно", но ошибся... поэтому прийдется чуток поправить его пример :)
Да, про этот.... запустите у себя самый послединий пример. "Код примера 2.2". Что вы видите на светиках?
Попробую как буду дома :)
И ещё за одно спрошу у гуру :) Если в SPI.transfer() поместить переменную в двоичном виде(int test = B00001111), она переведется в 10 автоматически?
1. Не нужен вам трансфер. Он один байт отсылает. А вам нужно два. Смотрите пример, как там отсылка делается.
2. Переменные в памяти всегда хранятся в "двоичном виде". Системы исчисления (десятичная, двоичная, шестнадцатеричная) это чисто "человеческие заморочки". Как вам понятней и удобней писать. Способ записи и не более того. С точки зрения компилятора B00001111 и 0x0F и 15 не отличаются НИЧЕМ. Прошивка, какой-бы вариант вы не написали, не будет отличатся ни на байт. Контроллер никогда не узнает как оно выглядело в вашем исходнике :)
3. "B00001111), она переведется в 10 автоматически" - конечно нет. Так как B00001111, это 15, а не 10-ть.
Кстати, поэтому и вопросы типа "как перевести переменную в 10/16/2-тичное значение" - не имеет смысла. Переменная не имеет "системы исчисления". Она "просто значение". А вот "как ВЫВЕСТИ ее в том или ином ВИДЕ" - уже осмысленно.
Кстати, последний Serial.print будет вам в помощь, когда будете разбиратся какие-же биты, в итоге, вы установили в переменной. Просто Serial.println(stateRegister,BIN) и смотитре в окне сериал монитора :)
Спасибо :) Просто у меня на 1 регистре висит дисплей, чтобы работала его библиотека нужно подключать SPI. А на 2 регистре уже индикация. У меня почему-то не работал shiftOut() при подключенной либе SPI... отключал SPI, shiftOut начинал работать, а вот дисплей уже нет :)
Спасибо :) Просто у меня на 1 регистре висит дисплей, чтобы работала его библиотека нужно подключать SPI.
Тогда все хуже. Вариант "просто не терять значение переменной" - уже не прокатит. Если кто-то кроме вас, меняет биты регистров (библиотека), то вы не знаете "текущие состояние регистра". Следовательно "не зацепить остальные биты" - вы не можете (и соотвествено библиотека ничего не знает про то какие биты вы выставили. причем, скорее всего она вообще будет думать что там один регистр, а второй - просто посылать нафиг).
Тут уж либо хачить библиотеку нужно будет, либо повестить эти регистры на разные выводы и работать с ними обсолютно независимо (благо shiftOut Это программная реализация, поэтому ее можно на любых пинах запустить).
Вот блин...а пинов то свободных уже не осталось :( Но всё равно спасибо за полезную информацию, буду думать как быть!
Вот блин...а пинов то свободных уже не осталось :(
Совсем? Ни одного? Про аналоговые не забыли?
Проверил, остался только D12 и А0 :( На аналоговый можно? :) Что-то я не сообразил :) Придется на плате дорожки резать да проводки кидать, а было всё красиво :)
Ну прежде чем "резать и и кидать", я бы на макетке вначале проверил.
> На аналоговый можно? :)
Да. A0 может спокойно работать как цифровой пин. Даже делать для этого ничего не нужно. Просто усилием воли говорите себе "это цифровой пин" и все :) digitalRead(A0)/digitalWrite(A0) сразу начинает работать ;)
Щас 100% не скажу (нет времени вникнуть/подумать), но мне есть ощущение, что можно обойтись одним дополнительным пином. Разделить у них только latch/ss пины. И включать их по очереди.... погуглите в сторону arduino spi slave, и статейка по основам SPI SPI (программный). Память Atmel DataFlash AT45DB081D. / Блог им. Frankie / Сообщество EasyElectronics.ru может помочь.
Ну в общем повесил я второй регистр на D12 и A0, теперь shiftOut с SPI нормально работает :)