реклама на сайте
подробности

 
 
3 страниц V   1 2 3 >  
Reply to this topicStart new topic
> Как из Байта получить восемь значений 0 и 1, CodeVision AVR
Vny4ek
сообщение Dec 23 2008, 13:27
Сообщение #1


Частый гость
**

Группа: Участник
Сообщений: 145
Регистрация: 11-01-08
Пользователь №: 34 001



Есть байт который я могу вывести на дисплей в виде FF или 02 но мне нужно записать в битовый масив на 8 ячеек что бы там было 0 или 1
Go to the top of the page
 
+Quote Post
Палыч
сообщение Dec 23 2008, 13:31
Сообщение #2


Гуру
******

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



Используем цикл
Код
unsigned char Byte, i, Bit[8];
for(i=0; i< 8; ++i)
  Bit[i]= (Byte >> i) & 0x01;

P.S. Не заметил, что нужен битовый массив... Это для какого микроконтроллера? Если для мк51, то массив Bit[8] должет иметь тип bit.
P.P.S. Ага! В Keil массив бит сделать не получается. Так что, только массив байтов, принимающих значение 0 или 1.
Go to the top of the page
 
+Quote Post
SysRq
сообщение Dec 23 2008, 16:39
Сообщение #3


Чайник, 1 литр
****

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



А цель-то какая сего действа? Как "битовый массив" размером 8 (именуемый байтом :) ) использовать в дальнейшем планируется?
Go to the top of the page
 
+Quote Post
Goodefine
сообщение Dec 23 2008, 17:40
Сообщение #4


Местный
***

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



Цитата(Vny4ek @ Dec 23 2008, 16:27) *
Есть байт... но мне нужно записать в битовый масив на 8 ячеек что бы там было 0 или 1

А цель? В каком-то смысле байт и есть битовый массив smile.gif ... Если нужно по отдельности использовать биты, то проще маски трудно что-то придумать...
Цитата
Ага! В Keil массив бит сделать не получается. Так что, только массив байтов, принимающих значение 0 или 1.

В используемом автором CAVR можно, но компилятор оперирует битовым массивом (равно как и битовыми переменными) в char-овом представлении, потребляя в 8-мь раз больше памяти. По сути там
bit bit_array[]==uchar bit_array[] ...


--------------------
Любой, заслуживающий внимания, опыт приобретается себе в убыток...
Go to the top of the page
 
+Quote Post
Vny4ek
сообщение Dec 24 2008, 06:21
Сообщение #5


Частый гость
**

Группа: Участник
Сообщений: 145
Регистрация: 11-01-08
Пользователь №: 34 001



цель такая: нужно сделать передачу информации, в виде нулей и единиц, просто в нужное время и нужной длительностью на ножку МК отправлять сигнал. а для этого ведь нужно задать значение либо 0 либо 1, вот и я не знаю как из байта сделать восемь по порядку битов

Сообщение отредактировал Vny4ek - Dec 24 2008, 06:30
Go to the top of the page
 
+Quote Post
Палыч
сообщение Dec 24 2008, 06:51
Сообщение #6


Гуру
******

Группа: Свой
Сообщений: 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;
............
Go to the top of the page
 
+Quote Post
Goodefine
сообщение Dec 24 2008, 07:31
Сообщение #7


Местный
***

Группа: Свой
Сообщений: 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


--------------------
Любой, заслуживающий внимания, опыт приобретается себе в убыток...
Go to the top of the page
 
+Quote Post
SysRq
сообщение Dec 24 2008, 10:55
Сообщение #8


Чайник, 1 литр
****

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



Цитата(Goodefine @ Dec 24 2008, 10:31) *
Код
for (i=0;i<8;++i)
{
     (byte&(1<<i))? //..
}
Ну зачем так криво-то sad.gif
Правильнее сделать маску неизменной, а само значение сдвигать. Примерно так:
Код
// 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);
Go to the top of the page
 
+Quote Post
Goodefine
сообщение Dec 24 2008, 11:07
Сообщение #9


Местный
***

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



Цитата(SysRq @ Dec 24 2008, 14:55) *
Правильнее сделать маску неизменной, а само значение сдвигать...

Ну, если для вас ровнее и правильнее убить в цикле значение переменной, то тогда, конечно, так...


--------------------
Любой, заслуживающий внимания, опыт приобретается себе в убыток...
Go to the top of the page
 
+Quote Post
Палыч
сообщение Dec 24 2008, 11:51
Сообщение #10


Гуру
******

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



Цитата(Goodefine @ Dec 24 2008, 14:07) *
Ну, если для вас ровнее и правильнее убить в цикле значение переменной, то тогда, конечно, так...
Ну, зачем же - убить. Перед выдачей битов байта в переменную value нужно занести значение байта: испортится лишь временная переменная, а переменная - выдаваемый байт останется неизменной.
Go to the top of the page
 
+Quote Post
Goodefine
сообщение Dec 24 2008, 12:01
Сообщение #11


Местный
***

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



Цитата(Палыч @ Dec 24 2008, 15:51) *
...Перед выдачей битов байта в переменную value нужно занести значение байта...

Плодить временные переменные на ровном месте это более правильный подход? С таким успехом можно и масочную переменную двигать...


--------------------
Любой, заслуживающий внимания, опыт приобретается себе в убыток...
Go to the top of the page
 
+Quote Post
DenisIV
сообщение Dec 24 2008, 12:19
Сообщение #12


Участник
*

Группа: Свой
Сообщений: 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>задержка)
Но решать по какому пути идти-Вам. Это далеко не все.
Go to the top of the page
 
+Quote Post
Goodefine
сообщение Dec 24 2008, 13:22
Сообщение #13


Местный
***

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



Цитата(DenisIV @ Dec 24 2008, 16:19) *
Обычно (насколько я понимаю) у вас кусочек программы похожей на RS232 передачу...

Без понятия, зачем это понадобилось... smile.gif
Цитата(DenisIV @ Dec 24 2008, 16:19) *
...Но код по времени не будет точен(сдвигов 1<<i будет от 0 до 7) и между 1-м выводом в порт и 8-м будет разное время. Системы, чувствительные к длине периода могут дать ошибку. ...

Это, извините, и коню понятно smile.gif Автор топика где-то озвучил, что у него "система, чувствительная к длине периода" тактов, этак, на 8-10?
Цитата(DenisIV @ Dec 24 2008, 16:19) *
...А если раз в 20-30 тактов-то можно сказать что это мёртвая затея...

Если так, то асм спасет отца русской демократии... Компилятор (CAVR тем паче) такое может при любом раскладе накомпилить...
Цитата(DenisIV @ Dec 24 2008, 16:19) *
...Но решать по какому пути идти-Вам. Это далеко не все...

Не мне, но автору. Далеко не это все...


--------------------
Любой, заслуживающий внимания, опыт приобретается себе в убыток...
Go to the top of the page
 
+Quote Post
SysRq
сообщение Dec 25 2008, 12:50
Сообщение #14


Чайник, 1 литр
****

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



Цитата(Goodefine @ Dec 24 2008, 15:01) *
С таким успехом можно и масочную переменную двигать...

Вполне. Но делать один сдвиг за итерацию цикла, ОДИН! Все остальные варианты - бред.
Go to the top of the page
 
+Quote Post
DenisIV
сообщение Dec 25 2008, 13:15
Сообщение #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 (для бОльших текстов исходников).
Go to the top of the page
 
+Quote Post

3 страниц V   1 2 3 >
Reply to this topicStart new topic
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0

 


RSS Текстовая версия Сейчас: 19th July 2025 - 12:58
Рейтинг@Mail.ru


Страница сгенерированна за 0.01489 секунд с 7
ELECTRONIX ©2004-2016