Побитовый сдвиг
- Войдите на сайт для отправки комментариев
Ср, 01/03/2017 - 15:31
Прошу, не бейте больно. Сломал мозг, но хучу разобраться.
for (int i = 0; i < 8; i++) { Serial.println(!!(0B11100011 & (1 << i)));
Serial выводит следующую последовательность: 1,1,1,0,0,0,1,1. Тут вопросов нет.
Убираю двойное отрицание
for (int i = 0; i < 8; i++) { Serial.println(0B11100011 & (1 << i));
И в Serial вылазят: 1,2,0,0,0,32,64,128
Почему так?
Так и должно быть.
Почему так?
Потому что ! - логическая операция, на выходе её true или false которые соответствуют 1 или 0. Но эффект забавный.
Да, и сдвиг здесь вобще никаким боком.
1,1,1,0,0,0,1,1. Тут вопросов нет.
И в Serial вылазят: 1,2,0,0,0,32,64,128
Наверно потому что bool 0 может быть только 0, а все что не 0 это уже 1 .
1 - это 1 // 2 это 1 // 32 это 1 // и так далее
ТС тут написал, что вопросов нет.
Я думаю, что нет вопросов исключительно потому, что он ничего не понял.
Невозможно понгять 3-ю строчку его сообщения и не понять 7-ю, т.к. 7-я получается из 3-й упрощением.
Идея - не скажу, что совершенно стандартная, но достаточно очевидная - двойное отрицание нужно, чтобы перевести единицу в любом разряде в единицу в нулевом разряде. По уму двигать нужно было число, а не маску, что все нормальные люди и делают, но автор 3-й строки (очевидно, не ТС) решил сделать по-другому. Такое нестандартное решение повлекло за собой другое нестандартное - какой операцией можно превратить любое ненулевое число в 1? Очевидно, двойным отрицанием.
2qwone: в Си нет булевого типа данных, обозначение bool нужно исключительно для программиста, чтобы ему легче было разобраться в коде. А так - это обычное целое со всеми вытекающими отсюда последствиями.
Не буду цитировать каждого, т.к. все мне помогли разобраться. Спасибо вам.
Для управления CD74HC4067 на его "адресные" входа нужно поочередно подавать следующие состояния (от 0 до 15)
Используя регистры:
Чую с регистрами есть вариант проще...(не трогая другие биты порта)
Подскажите)
Попроще это вот так примерно:
А с регистрами - это никогда не "попроще".
<= 0x0f, bool controlPinState много букв)
Вот такой вариант
А если использовать битовые маски
Взяла 4 5 6 7 биты из байта и записала их в порт
Но при этом будут меняться и 0 1 2 3 биты
Неужто нужна скорость?
А если использовать битовые маски
Взяла 4 5 6 7 биты из байта и записала их в порт
Но при этом будут меняться и 0 1 2 3 биты
Меняться - это полбеды. Вот когда нужно будет срочно пин освободить - тогда начнется кама-с-утра.
А избежать изменения можно:
port_protect_mask задается так: B11110000 - если в маске 1, то бит порта не изменяется, если 0 - перезаписывается новым значением.
на его "адресные" входа ...
Мы говорим не "входы". а "входа" -
Слова входят коротки и смачны.
"ПинЫ" - не "пИны" - сводят нас с ума,
Из флэша выкорчёвывая байты.
Почти Высоцкий! ;)))
Я понимаю, что здесь полно грубых мужиков, да еще и без "вышки", да еще из прованса... но тут я никак не ожидал варианта "входа"! Куда мир катиццо? ;))
Осталось измерить напряжение "на пину", и "прошить скейч".
<= 0x0f, bool controlPinState много букв)
<= - верно.
А много букв - для понятности. Компилятору-то пофиг, он читать не умеет. Можно было, конечно, прямо в digitalWrite битшифт заговнокодить ))
Осталось измерить напряжение "на пину", и "прошить скейч".
Сплошь и рядом. "Залить скейч" обычное дело.) Ну ладно дети... Ребёнку постоянно выговариваю.(
Irinka, не страдали бы вы ерундой. Вся эта мнимая скорость никому не нужна. Постоянно вижу как "гонщики" скоростят до светофора.)
А если использовать битовые маски
Взяла 4 5 6 7 биты из байта и записала их в порт
Но при этом будут меняться и 0 1 2 3 биты
идея правильная, чуть-чуть подправить осталось:
Итог - биты с 4 по 7 поменяны в соответсвии со значением port[2], остальные биты порта не затронуты.
Ужос! Вот только зачем, спросит удивлённый читатель?
Так не пойдёт, каждый проход будет сбрасывать 4 адресных входа в ноль.
Так не пойдёт, каждый проход будет сбрасывать 4 адресных входа в ноль.
запишите эти две строки в одну, как Green выше показал
Как эту запись понимать?
Как эту запись понимать?
это тоже самое, как
только записанное в одну строку
В итоге сначала биты с 4 по 7 будут 0, потом будут 1 1 0 0
Так?
В итоге сначала биты с 4 по 7 будут 0, потом будут 1 1 0 0
Так?
все это считается в одно действие, поэтому никакие "сначала" и "потом" на содержимом PORTD не скажутся, результат будет аналогичен единомоментной установке старших четырех бит в значения 1 1 0 0
Классно! Не то что digitalWrite...Код стал красивее, короче!
PORTD & B00001111 это тоже, что и PORTD = B00001111? Но при этом в 0 1 2 3 биты ничего не записывается.
далее | port[0] записываются в порт только 1, 0 не пишутся, т.е. если port[0]=0b10000011
то два младших бита так же запишутся в порт?
Нет, ну это, конечно, годится для тренировки, но. Ардуино - это более высокая абстракция, нежели PORTD и DDRD.
И это удобно. Это специально сделано для вас, блондинок. А тогда заради чего вам спускаться вниз, в эту клоаку?
Иринка, не надо этой кучи банальных вопросов, ответы на которые вы и сами знаете. Не частите, просто посидите и подумайте
Спасибо
Это специально сделано для вас, блондинок...
а что с брюнетками?
Все куда прозаичнее
PORTD=(PIND)&(0xF0|port[0]);
а что с брюнетками?
Это и мужиков касается. Раньше только избранные с МК работали, а сейчас любая блондинка может.
Это и мужиков касается. Раньше только избранные с МК работали, а сейчас любая блондинка может.
Ты сейчас прям меня описал
Кактус, быдлокод детектед. Неверно. Должно быть вы хотели:
PORTD = (PORTD & 0xF0) | port[0];
Однако, даме нужно изменять старший ниббл, поэтому
PORTD = (PORTD & 0x0f) | port[0]<<4;
И никак иначе.
Однако, даме нужно изменять старший ниббл, поэтому
PORTD = (PORTD & 0x0f) | port[0]<<4;
И никак иначе.
у нее в массиве port[] уже подготовленные данные, сдвинутые в старшие биты:
поэтому двигать port[0] уже не нужно
Нет, ну тогда, это уж как ей соизволится.)
Вообще, конечно, не красиво говорить о человеке в третьем лице, но думаю, вы понимаете. У нас тут всё по простому.)
Всё поняла, спасибо)