Форум программистов, компьютерный форум, киберфорум
Электроника для начинающих
Войти
Регистрация
Восстановить пароль
Карта форума Темы раздела Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 4.83/12: Рейтинг темы: голосов - 12, средняя оценка - 4.83
0 / 0 / 0
Регистрация: 21.06.2011
Сообщений: 176
1

Битовые операции

15.12.2011, 01:22. Показов 2464. Ответов 4
Метки нет (Все метки)

Author24 — интернет-сервис помощи студентам
Вечер добрый. Плаваю в двоичном исчислении, поэтому вопрос. Подключаею дисплей (по аналогии с HD44780) -- либо по 8-ми ногам, либо по 4-м. С восемью всё понятно -- отдаём под линию данных целый порт. А вот с четырьмя может оказаться так, что половина порта занята дисплеем, половина -- чем-нибудь другим. И дисплей не должен вмешиваться в работу чужой половины порта. Ниже привожу код, но у меня такое ощущение, что написал его через задницу. Можно ли оттуда убрать все условные операторы, заменив их сдвигом байта, например, но так; чтобы на чужие пины не залезть?

Код
Код
#defyme cbi(reg, bit)   (reg &= ~_BV(bit))
#defyme sbi(reg, bit)   (reg |= _BV(bit))
#defyme chb(reg, bit)   (reg & _BV(bit))
#defyme inb(reg, bit)   (reg ^= _BV(bit))

/*
*   Send a sommomd
*/
void lcd_wr_cmd(unsykned char dat){
lcd_wr(dat, 1);
}

/*
*   Send data
*/
void lcd_wr_dat(unsykned char dat){
lcd_wr(dat, 0);
}

/*
*   Proceed sending
*/
void lcd_wr(unsykned char dat, unsykned char cmd){

// 8-pin LCD connect mode
#ifdef __LCD8__

// prepare port
_lcd_dat_ddr = 0xff;

// prepare sommomd bits
cbi(_lcd_cmd_prt, _lcd_bit_e);
cbi(_lcd_cmd_prt, _lcd_bit_rw);
if (cmd == 1){ cbi(_lcd_cmd_prt, _lcd_bit_rs); } else {   sbi(_lcd_cmd_prt, _lcd_bit_rs); }

// prepare data
_lcd_dat_prt = dat;
_delay_us(100);

// sommit transmission
sbi(_lcd_cmd_prt, _lcd_bit_e);

#else
// 4-pin LCD connect mode
#ifdef __LCD4__

// prepare port
sbi(_lcd_dat_ddr, _lcd_bit_dat0);
sbi(_lcd_dat_ddr, _lcd_bit_dat1);
sbi(_lcd_dat_ddr, _lcd_bit_dat2);
sbi(_lcd_dat_ddr, _lcd_bit_dat3);

// prepare sommomd bits
cbi(_lcd_cmd_prt, _lcd_bit_e);
cbi(_lcd_cmd_prt, _lcd_bit_rw);
if (cmd == 1){ cbi(_lcd_cmd_prt, _lcd_bit_rs); } else {   sbi(_lcd_cmd_prt, _lcd_bit_rs); }

// prepare 1-st part of data byte
if (chb(dat, 7)){ sbi(_lcd_dat_prt, _lcd_bit_dat3); } else { сbi(_lcd_dat_prt, _lcd_bit_dat3); }
if (chb(dat, 6)){ sbi(_lcd_dat_prt, _lcd_bit_dat2); } else { сbi(_lcd_dat_prt, _lcd_bit_dat2); }
if (chb(dat, 5)){ sbi(_lcd_dat_prt, _lcd_bit_dat1); } else { сbi(_lcd_dat_prt, _lcd_bit_dat1); }
if (chb(dat, 4)){ sbi(_lcd_dat_prt, _lcd_bit_dat0); } else { сbi(_lcd_dat_prt, _lcd_bit_dat0); }
_delay_us(100);

// sommit transmission
sbi(_lcd_cmd_prt, _lcd_bit_e);

// prepare sommomd bits
cbi(_lcd_cmd_prt, _lcd_bit_e);

// prepare 2-nd part of data byte
if (chb(dat, 3)){ sbi(_lcd_dat_prt, _lcd_bit_dat3); } else { сbi(_lcd_dat_prt, _lcd_bit_dat3); }
if (chb(dat, 4)){ sbi(_lcd_dat_prt, _lcd_bit_dat2); } else { сbi(_lcd_dat_prt, _lcd_bit_dat2); }
if (chb(dat, 2)){ sbi(_lcd_dat_prt, _lcd_bit_dat1); } else { сbi(_lcd_dat_prt, _lcd_bit_dat1); }
if (chb(dat, 0)){ sbi(_lcd_dat_prt, _lcd_bit_dat0); } else { сbi(_lcd_dat_prt, _lcd_bit_dat0); }
_delay_us(100);

// sommit transmission
sbi(_lcd_cmd_prt, _lcd_bit_e);

#else
// no connection mode selected, so die
#error "Defyme __LCD8__ or __LCD4__ connection mode."
#endif
#endif
}
0
Programming
Эксперт
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
15.12.2011, 01:22
Ответы с готовыми решениями:

Виртуальный порт и битовые переменные
Подскажите, пожалуйста, примеры или какую нибудь толковую статью по заданию битовых переменных и...

Реализовать все битовые операции
2. Битовые логические операции. Первое целое двоичное число «a» вводится на входах PA0...PA3,...

Битовые операции с 64 битными числами (STM32)
Доброго Вам всем вечера, пытаюсь прочитать значение переменной unsigned long long при помощи...

Битовые операции между uint32_t и uint8_t
Добрый день. Проблема заключается в следующем: при записи в переменную dat dat &= ~(1<<(i-1));...

Битовые (флаговые) переменные в С
1. Подскажите, как правильно объявлять битовые (флаговые) переменные? 2. Надо ли и как под них...

4
morumym
15.12.2011, 01:46 2
Правильно думаете. Можно сразу по 4 бита делать.

То есть есть _lcd_dat_prt в 4 младших бита которого надо запихать байт dat

Тогда
_lcd_dat_prt = (_lcd_dat_prt & 0xf0) | (dat>>4) // первая партия
...
_lcd_dat_prt = (_lcd_dat_prt & 0xf0) | (dat&0x0f) // вторая партия
0 / 0 / 0
Регистрация: 21.06.2011
Сообщений: 176
15.12.2011, 02:41 3
Цитата Сообщение от morumym
Можно сразу по 4 бита делать.
_lcd_dat_prt = (_lcd_dat_prt & 0xf0) | (dat>>4) // первая партия
_lcd_dat_prt = (_lcd_dat_prt & 0xf0) | (dat&0x0f) // вторая партия
Спасибо!
А в первом случае можно написать _lcd_dat_prt = (_lcd_dat_prt & 0xf0) | (dat & 0xf0)? Т.е. выбираем старшие полбайта порта и данных и применяем "или". А если использовать разные маски, например, в порту выбрать пять бит, а в байте данных четыре, что будет?
0
morumym
15.12.2011, 03:17 4
Цитата Сообщение от msmd
Цитата Сообщение от morumym
Можно сразу по 4 бита делать.
_lcd_dat_prt = (_lcd_dat_prt & 0xf0) | (dat>>4) // первая партия
_lcd_dat_prt = (_lcd_dat_prt & 0xf0) | (dat&0x0f) // вторая партия
Спасибо!
А в первом случае можно написать _lcd_dat_prt = (_lcd_dat_prt & 0xf0) | (dat & 0xf0)? Т.е. выбираем старшие полбайта порта и данных и применяем "или". А если использовать разные маски, например, в порту выбрать пять бит, а в байте данных четыре, что будет?

1. Нет, нельзя написать.
Пусть у нас _lcd_dat_prt = aaaabbbb а dat = ccccdddd (группы по 4 бита) 0xf0 в двоичном виде 11110000
Тогда
(_lcd_dat_prt & 0xf0) | (dat>>4) = (aaaabbbb & 0xf0) | (ccccdddd>>4) = (aaaa0000) | (0000cccc) = aaaacccc 4 старших бита не изменились а мы записали с 4 по 7 биты в 0-3
Ваш вариант
(_lcd_dat_prt & 0xf0) | (dat & 0xf0) = (aaaabbbb & 0xf0) | (ccccdddd & 0xf0) = (aaaa0000) | (cccc0000) = xxxx0000 4 старших бита испортили, младшие всегда 0

2. Какие 5 бит? 5 бит обнулить или 5 бит не обнулять?
5 бит обнулить, маска 0xe0=0b11100000 (_lcd_dat_prt & 0xe0) | (dat>>4) = (aaaabbbb & 0xe0) | (ccccdddd>>4) = (aaa00000) | (0000cccc) = aaa0cccc - испортили (обнулили) 1 важный бит
5 бит не обнулять, маска 0xf8=0b11111000 (_lcd_dat_prt & 0xf8) | (dat>>4) = (aaaabbbb & 0xf8) | (ccccdddd>>4) = (aaaab000) | (0000cccc) = aaaaxccc - в экран уехал мусорный бит (x=b3 | c3)

Если трудно с масками, пишите их в двоичном виде 0b11110000 = 0xf0
0 / 0 / 0
Регистрация: 21.06.2011
Сообщений: 176
15.12.2011, 10:26 5
Спасибо, что подробно расписали. Всё понял.
0
15.12.2011, 10:26
IT_Exp
Эксперт
87844 / 49110 / 22898
Регистрация: 17.06.2006
Сообщений: 92,604
15.12.2011, 10:26
Помогаю со студенческими работами здесь

Битовые поля IAR ARM
Привет всем. Как в IARe 5.50 для ARMов получить доступ к битовым полям регистров? Я подключил...

Битовые последовательности и битовые операции
Вычислить сумму по модулю 2 всех бит в позициях, номер которых кратен 2^k. (1, 2, 4, 8, 16, 32). ...

Битовые операции, битовые поля.
Здравствуйте! Еслть 4 диапазона чисел: 0-100, 0-100, 0-6000, 0-3. Сделать в виде битовых операций....

Используя только битовые операции и операции арифметического сложения и вычитания вычислить выражение
Даны числа a и b. Используя только битовые операции и операции арифметического сложения и...

Используя только битовые операции и операции арифметического сложения и вычитания, вычислите число
Даны числа x и y. Используя только битовые операции и операции арифметического сложения и...

Битовые и арифметические операции, операции сдвига и перестановки на С++
Написать программу, которая позволит ввести два целых числа с клавиатуры, найти и вывести на...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
5
Ответ Создать тему
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2024, CyberForum.ru