|
Как из Байта получить восемь значений 0 и 1, CodeVision AVR |
|
|
3 страниц
1 2 3 >
|
 |
Ответов
(1 - 14)
|
Dec 23 2008, 17:40
|

Местный
  
Группа: Свой
Сообщений: 211
Регистрация: 6-08-07
Из: Приднестровье, Тирасполь
Пользователь №: 29 581

|
Цитата(Vny4ek @ Dec 23 2008, 16:27)  Есть байт... но мне нужно записать в битовый масив на 8 ячеек что бы там было 0 или 1 А цель? В каком-то смысле байт и есть битовый массив  ... Если нужно по отдельности использовать биты, то проще маски трудно что-то придумать... Цитата Ага! В Keil массив бит сделать не получается. Так что, только массив байтов, принимающих значение 0 или 1. В используемом автором CAVR можно, но компилятор оперирует битовым массивом (равно как и битовыми переменными) в char-овом представлении, потребляя в 8-мь раз больше памяти. По сути там bit bit_array[]==uchar bit_array[] ...
--------------------
Любой, заслуживающий внимания, опыт приобретается себе в убыток...
|
|
|
|
|
Dec 24 2008, 06:51
|

Гуру
     
Группа: Свой
Сообщений: 2 399
Регистрация: 10-05-06
Из: г. Новочеркасск
Пользователь №: 16 954

|
Цитата(Vny4ek @ Dec 24 2008, 09:21)  ...вот и я не знаю как из байта сделать восемь по порядку битов Наложением на байт маски: (Byte & (1 << i)) Это выражение будет принимать значение ноль, если i-ый бит байта Byte имеет нулевое значение, и - не ноль, если i-ый бит байта - единица. Это выражение можно использовать в качестве условия в операторе if, или в условном операторе, например так: Out= (Byte & (1 << i)) ? 1 : 0; Можно хранить биты для выдачи в специально отведённой переменной: Код unsigned char T; T= Byte; ............. // Вывод очередного бита Out= T & 0x01; T>>= 1; ............
|
|
|
|
|
Dec 24 2008, 07:31
|

Местный
  
Группа: Свой
Сообщений: 211
Регистрация: 6-08-07
Из: Приднестровье, Тирасполь
Пользователь №: 29 581

|
Цитата(Vny4ek @ Dec 24 2008, 10:21)  цель такая:.. CAVR позволит сделать так: Код for (i=0;i<8;++i) { PORTW.Y=byte&(1<<i); //W-порт, Y-номер пина delay_ms(x); //x-нужная задержка }; Но дабы не переписывать код при переходе на другой компилятор, лучше сделать как-то так: Код #define BIT 1 /* задаем нужный номер пина (0...7) */ for (i=0;i<8;++i) { (byte&(1<<i))? PORTW|=(1<<BIT):PORTW&=~(1<<BIT); delay_ms(x); };
Сообщение отредактировал Goodefine - Dec 24 2008, 07:52
--------------------
Любой, заслуживающий внимания, опыт приобретается себе в убыток...
|
|
|
|
|
Dec 24 2008, 10:55
|

Чайник, 1 литр
   
Группа: Свой
Сообщений: 655
Регистрация: 17-05-06
Из: Moscow
Пользователь №: 17 168

|
Цитата(Goodefine @ Dec 24 2008, 10:31)  Код for (i=0;i<8;++i) { (byte&(1<<i))? //.. } Ну зачем так криво-то Правильнее сделать маску неизменной, а само значение сдвигать. Примерно так: Код // value - значение
unsigned char i = 8;
do {
// if(value & 1) PORTW |= (1<<BIT); // LSB first // else PORTW &= ~(1<<BIT); // LSB first // value >>= 1; // LSB first
if(value & 0x80) PORTW |= (1<<BIT); // MSB first else PORTW &= ~(1<<BIT); // MSB first value <<= 1; // MSB first
} while(--i);
|
|
|
|
|
Dec 24 2008, 11:07
|

Местный
  
Группа: Свой
Сообщений: 211
Регистрация: 6-08-07
Из: Приднестровье, Тирасполь
Пользователь №: 29 581

|
Цитата(SysRq @ Dec 24 2008, 14:55)  Правильнее сделать маску неизменной, а само значение сдвигать... Ну, если для вас ровнее и правильнее убить в цикле значение переменной, то тогда, конечно, так...
--------------------
Любой, заслуживающий внимания, опыт приобретается себе в убыток...
|
|
|
|
|
Dec 24 2008, 12:01
|

Местный
  
Группа: Свой
Сообщений: 211
Регистрация: 6-08-07
Из: Приднестровье, Тирасполь
Пользователь №: 29 581

|
Цитата(Палыч @ Dec 24 2008, 15:51)  ...Перед выдачей битов байта в переменную value нужно занести значение байта... Плодить временные переменные на ровном месте это более правильный подход? С таким успехом можно и масочную переменную двигать...
--------------------
Любой, заслуживающий внимания, опыт приобретается себе в убыток...
|
|
|
|
|
Dec 24 2008, 12:19
|

Участник

Группа: Свой
Сообщений: 68
Регистрация: 11-12-08
Из: Республика Беларусь, г.Минск
Пользователь №: 42 380

|
Цитата(Goodefine @ Dec 24 2008, 14:07)  Ну, если для вас ровнее и правильнее убить в цикле значение переменной, то тогда, конечно, так... Обычно (насколько я понимаю) у вас кусочек программы, похожей на RS232 передачу (разница в том, что обычно для 232 не хватает еще 2-х бит:Start и Stop) Дело не в том, убивать ли значение переменной или нет, дело в оптимальности далее полученного кода. А переменную можно и сохранить/восстановить. А можно и отдельную функцию сделать, которой сообщается эти 8 бит(байт) и может быть абсолютно всё равно, какие данные перед выходом из функции в этой переменной. Если не менять переменную, может быть и так: for (i=0;i<8;i++) { if (InByte&(1<<i)) {PortX.Y=1;} else {PortX.Y=0;} delay_ms(x); } Тут переменная не меняется. Но код по времени не будет точен(сдвигов 1<<i будет от 0 до 7) и между 1-м выводом в порт и 8-м будет разное время. Системы, чувствительные к длине периода могут дать ошибку. Хотя всё относительно... Если импульс идёт раз в секунду, то лишние 100 тактов наплевать. А если раз в 20-30 тактов-то можно сказать что это мёртвая затея. Там пройдёт только предыдущая затея (счётчик>вывод>сдвиг на 1>задержка) Но решать по какому пути идти-Вам. Это далеко не все.
|
|
|
|
|
Dec 24 2008, 13:22
|

Местный
  
Группа: Свой
Сообщений: 211
Регистрация: 6-08-07
Из: Приднестровье, Тирасполь
Пользователь №: 29 581

|
Цитата(DenisIV @ Dec 24 2008, 16:19)  Обычно (насколько я понимаю) у вас кусочек программы похожей на RS232 передачу... Без понятия, зачем это понадобилось... Цитата(DenisIV @ Dec 24 2008, 16:19)  ...Но код по времени не будет точен(сдвигов 1<<i будет от 0 до 7) и между 1-м выводом в порт и 8-м будет разное время. Системы, чувствительные к длине периода могут дать ошибку. ... Это, извините, и коню понятно  Автор топика где-то озвучил, что у него "система, чувствительная к длине периода" тактов, этак, на 8-10? Цитата(DenisIV @ Dec 24 2008, 16:19)  ...А если раз в 20-30 тактов-то можно сказать что это мёртвая затея... Если так, то асм спасет отца русской демократии... Компилятор (CAVR тем паче) такое может при любом раскладе накомпилить... Цитата(DenisIV @ Dec 24 2008, 16:19)  ...Но решать по какому пути идти-Вам. Это далеко не все... Не мне, но автору. Далеко не это все...
--------------------
Любой, заслуживающий внимания, опыт приобретается себе в убыток...
|
|
|
|
|
Dec 25 2008, 13:15
|

Участник

Группа: Свой
Сообщений: 68
Регистрация: 11-12-08
Из: Республика Беларусь, г.Минск
Пользователь №: 42 380

|
Цитата(SysRq @ Dec 25 2008, 15:50)  Вполне. Но делать один сдвиг за итерацию цикла, ОДИН! Все остальные варианты - бред. Есть правда в словах... А если сделать вращение (что бы сохранить значение переменной), автор, я думаю, будет доволен... Код for(i=0;i<8;i++) { if (InByte & 0x01) {PortX.Y=1;InByte=((InByte>>1) | 0x80);} else {PortX.Y=0;InByte=((InByte>>1) & 0x7F);} delay_ms(x); } // сдвиг вправо
for(i=0;i<8;i++) { if (InByte & 0x80) {PortX.Y=1;InByte=((InByte<<1) | 0x01);} else {PortX.Y=0;InByte=((InByte<<1) & 0xFE);} delay_ms(x); } // сдвиг влево Я возможно сделал чуть неоптимально, но на скорость и сохранность переменной это повлияет в лучшую сторону. Поправьте прогу чуть для своего удобства и вуаля! От модератора. Учитесь самостоятельно оформлять сообщения с помощью тэгов. Для оформления исходников служат тэги code (кнопка в редакторе сообщений) для небольших фрагментов и codebox (для бОльших текстов исходников).
|
|
|
|
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0
|
|
|