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

 
 
> Как из Байта получить восемь значений 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
3 страниц V   1 2 3 >  
Start new topic
Ответов (1 - 35)
Палыч
сообщение 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
xemul
сообщение Dec 25 2008, 14:13
Сообщение #16



*****

Группа: Свой
Сообщений: 1 928
Регистрация: 11-07-06
Пользователь №: 18 731



Странно, что еще до интегралов не добрались...
Код
#define BIT 1 /* задаем нужный номер пина (0...7) */
for (unsigned char bitmask = 1; bitmask; bitmask <<= 1)
{
   (byte & bitmask)? PORTW |= (1<<BIT): PORTW &= ~(1<<BIT);
   delay_ms(x);
}
Go to the top of the page
 
+Quote Post
DenisIV
сообщение Dec 25 2008, 17:23
Сообщение #17


Участник
*

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



Цитата(xemul @ Dec 25 2008, 17:13) *
Странно, что еще до интегралов не добрались...
Код
#define BIT 1 /* задаем нужный номер пина (0...7) */
for (unsigned char bitmask = 1; bitmask; bitmask <<= 1)
{
   (byte & bitmask)? PORTW |= (1<<BIT): PORTW &= ~(1<<BIT);
   delay_ms(x);
}

Не знаю, помню когда сдвиг вправо у меня компилёр ошибался
и иногда задвигал в старший бит '1', а влево - всегда '0'
(Или это был кольцевой сдвиг?)
(Или это был глючный компилёр?)
(Или тип переменной был signed?)

Не сталкивались?
Go to the top of the page
 
+Quote Post
rezident
сообщение Dec 25 2008, 17:36
Сообщение #18


Гуру
******

Группа: Свой
Сообщений: 10 920
Регистрация: 5-04-05
Пользователь №: 3 882



Цитата(DenisIV @ Dec 25 2008, 22:23) *
иногда задвигал в старший бит '1', а влево - всегда '0'
(Или это был кольцевой сдвиг?)
Нету такого сдвига в стандарте Си.
Цитата(DenisIV @ Dec 25 2008, 22:23) *
(Или тип переменной был signed?)
Угу, скорее всего именно так. Операция сдвига над переменной типа signed проводилась. Когда у переменной типа signed устанавливают старший бит, то число становится отрицательным. А при операции сдвига знак у такой переменной меняется не должен. Т.е. единичка-то вправо сдвигается, но в старшем бите она все равно остается.
Go to the top of the page
 
+Quote Post
Goodefine
сообщение Dec 25 2008, 18:19
Сообщение #19


Местный
***

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



Цитата(xemul @ Dec 25 2008, 17:13) *
Код
...

Компилятор CAVR (и avr-gcc тоже) не поймет запись
Код
(byte & bitmask)? PORTW |= (1<<BIT): PORTW &= ~(1<<BIT);

Кроме того, CAVR не допускает объявления вида:
Код
for (unsigned char mask ...)

Цитата(xemul @ Dec 25 2008, 17:13) *
Странно, что еще до интегралов не добрались...

До интегралов ща доберемся... smile.gif
Код
...
#define BIT 0
#define PORTW PORTD
#define x 10
...
void transmit_byte(unsigned char const *byte, unsigned char direct){
   unsigned char  mask;
         switch(direct){
        case 0: //младший бит вперед
          for (mask=1;mask;mask<<=1) {PORTW=(*byte&mask)? PORTW|(1<<BIT):PORTW&~(1<<BIT);
                                      delay_us(x); /*или delay_ms(x); */}
         break;
                   case 1:  //старший бит вперед
          for (mask=0x80;mask;mask>>=1) {PORTW=(*byte&mask)? PORTW|(1<<BIT):PORTW&~(1<<BIT);
                                      delay_us(x);}
          
         break;
        
                           }
                                                                                            
                                                                                           }
...
transmit_byte(&byte,0); //младший бит вперед
...
transmit_byte(&byte,1); //старший бит вперед
...


Сообщение отредактировал Goodefine - Dec 25 2008, 18:28


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


Гуру
******

Группа: Модераторы
Сообщений: 8 455
Регистрация: 15-05-06
Из: Рига, Латвия
Пользователь №: 17 095



Цитата(Goodefine @ Dec 25 2008, 20:19) *
Компилятор CAVR (и avr-gcc тоже) не поймет запись
Код
(byte & bitmask)? PORTW |= (1<<BIT): PORTW &= ~(1<<BIT);
Что именно в этой записи ему будет непонятно? Единственным возможным побочным эффектом может быть лишнее чтение PORTW после записи.


--------------------
На любой вопрос даю любой ответ
"Write code that is guaranteed to work, not code that doesn’t seem to break" (C++ FAQ)
Go to the top of the page
 
+Quote Post
Goodefine
сообщение Dec 25 2008, 20:27
Сообщение #21


Местный
***

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



Цитата(Сергей Борщ @ Dec 25 2008, 23:13) *
Что именно в этой записи ему будет непонятно?..

Х/з, самому интересно. Сначала и я так же написал... CAVR говорит "Error... mising":" ", у avr-gcc более длинное ругательство... Насколько я понял, компилятору не нравятся знаки равенства в выражениях после оператора сравнения...


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


Гуру
******

Группа: Модераторы
Сообщений: 8 455
Регистрация: 15-05-06
Из: Рига, Латвия
Пользователь №: 17 095



Цитата(Goodefine @ Dec 25 2008, 22:27) *
у avr-gcc более длинное ругательство... Насколько я понял, компилятору не нравятся знаки равенства в выражениях после оператора сравнения...
Я заменил PORTW на PORTD, поскольку у меги8 нет порта W:
CODE
main.cpp:
#include <avr/io.h>
#include <stdint.h>
#define BIT 1
void Test1(uint8_t byte, uint8_t bitmask)
{
(byte & bitmask)? PORTD |= (1<<BIT): PORTD &= ~(1<<BIT);
}

main.lst:
484 .section .text._Z5Test1hh,"ax",@progbits
485 .global _Z5Test1hh
487 _Z5Test1hh:
488 .LFB37:
489 .LSM75:
490 /* prologue: frame size=0 */
491 /* prologue end (size=0) */
492 .LVL9:
493 .LSM76:
494 0000 70E0 ldi r23,lo8(0) ; bitmask,
495 .LVL10:
496 0002 90E0 ldi r25,lo8(0) ; byte,
497 .LVL11:
498 0004 6823 and r22,r24 ; bitmask, byte
499 0006 7923 and r23,r25 ; bitmask, byte
500 .LVL12:
501 0008 672B or r22,r23 ; bitmask
502 000a 01F0 breq .L57 ; ,
503 .LSM77:
504 000c 919A sbi 50-0x20,1 ; ,
505 000e 0895 ret
506 .L57:
507 0010 9198 cbi 50-0x20,1 ; ,
508 0012 0895 ret
509 /* epilogue: frame size=0 */
510 /* epilogue: noreturn */
511 /* epilogue end (size=0) */
512 /* function void Test1(uint8_t, uint8_t) size 10 (10) */
Никакой ругани.


--------------------
На любой вопрос даю любой ответ
"Write code that is guaranteed to work, not code that doesn’t seem to break" (C++ FAQ)
Go to the top of the page
 
+Quote Post
Goodefine
сообщение Dec 25 2008, 21:03
Сообщение #23


Местный
***

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



Цитата(Сергей Борщ @ Dec 25 2008, 23:42) *
Я заменил PORTW на PORTD, поскольку у меги8 нет порта...

Дык и я заменил smile.gif
Код
#define PORTW PORTD

Цитата(Сергей Борщ @ Dec 25 2008, 23:42) *
Никакой ругани...

У Вас объектный код (*.cpp)? Привожу скриншот компиляции Вашего кода (просто вставил его в рабочий проект) в WinAVR 20080610 под AVR Studio 4
А вот так компилится:
Код
void Test1(uchar byte, uchar bitmask)
{
PORTD=(byte & bitmask)? PORTD | (1<<BIT): PORTD & ~(1<<BIT);
}

Эскизы прикрепленных изображений
Прикрепленное изображение
 


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


Участник
*

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



Цитата(Goodefine @ Dec 26 2008, 00:03) *
Дык и я заменил smile.gif
Код
#define PORTW PORTD


У Вас объектный код (*.cpp)? Привожу скриншот компиляции Вашего кода (просто вставил его в рабочий проект) в WinAVR 20080610 под AVR Studio 4
А вот так компилится:
Код
void Test1(uchar byte, uchar bitmask)
{
PORTD=(byte & bitmask)? PORTD | (1<<BIT): PORTD & ~(1<<BIT);
}

Попробуйте разделить все три прцедуры на строчки и поймёте где трабл. Да, не нравятся ему аргументы, но в какой позиции строки он не написал.
Кстати, посмотрите, byte может у вас определено ранее #defin'ом как unsigned char? Может просто имя переменной поменять?

Ксати, глотнул пива, идея пришла: А не прокатит ли такая конструкция:
Код
for ((Direction)? mask=1<<0:mask=1<<7;mask;(Direction)? mask<<=1:mask>>1)
{PORTx=(*byte&mask)? PORTx|(1<<BIT):PORTx&~(1<<BIT);delay_us(x);}

Сюда даже вместо 7 (в 'for') можно как-то подставить sizeof(); (хоть в байтах*8-1,хоть в битах-1) ?
Тогда прога будет просто супер универсальной! (Я даже себе в библию программиста запишу lol.gif )
И если Direction задано через union...struct... как бит, то налицо ещё и прямая экономия места... ?

Сообщение отредактировал DenisIV - Dec 25 2008, 22:08
Go to the top of the page
 
+Quote Post
Сергей Борщ
сообщение Dec 25 2008, 22:40
Сообщение #25


Гуру
******

Группа: Модераторы
Сообщений: 8 455
Регистрация: 15-05-06
Из: Рига, Латвия
Пользователь №: 17 095



Цитата(Goodefine @ Dec 25 2008, 23:03) *
У Вас объектный код (*.cpp)?
Вопроса не понял. Студию не пользую, вот откомпилил в режиме С (не С++):
Код
#include    <avr/io.h>
typedef unsigned char uchar;
#define BIT 0
void Test1(uchar byte, uchar bitmask)
{
    (byte & bitmask)? PORTD | (1<<BIT): PORTD & ~(1<<BIT);
}

avr-gcc  -mmcu=atmega8 -Wall -gdwarf-2  -DF_CPU=3686400UL  -Os  -fsigned-char -funsigned-bitfields -fpack-struct -fshort-enums -MD -MP -MT ./release/obj/test.o -MF ./release/dep/test.o.d  -ffunction-sections  -fdata-sections -fverbose-asm -Wa,-ahlmsdc=./release/lst/test.lst -c  test.c -o release/obj/test.o
Версия WinAVR - 20071221. Завтра могу поставить более свежую.


--------------------
На любой вопрос даю любой ответ
"Write code that is guaranteed to work, not code that doesn’t seem to break" (C++ FAQ)
Go to the top of the page
 
+Quote Post
DenisIV
сообщение Dec 25 2008, 22:40
Сообщение #26


Участник
*

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



Ещё глотнул пива...
Ведь оператор for работает так:
Код
for([первая инструкция];[условие выполнения];[инструкция после тела]) [тело]

и его можно заменить на:
Код
[первая инструкция]
while ([условие выполнения])
{
[тело]
[инструкция после тела]
}

итого мы можем:
Код
(Direction)? mask=1<<0:mask=1<<7;
while(mask)
  {
   PORTx=(*byte&mask)? PORTx|(1<<BIT):PORTx&~(1<<BIT);
   delay_us(x);
   (Direction)? mask<<=1:mask>>1)
  }

Или не можем?
По-моему это абсолютно идентичные логически и т.д. конструкции...
Гуру, если не прав, поправьте...
Go to the top of the page
 
+Quote Post
Сергей Борщ
сообщение Dec 25 2008, 22:46
Сообщение #27


Гуру
******

Группа: Модераторы
Сообщений: 8 455
Регистрация: 15-05-06
Из: Рига, Латвия
Пользователь №: 17 095



Цитата(DenisIV @ Dec 25 2008, 23:27) *
Сюда даже вместо 7 (в 'for') можно как-то подставить sizeof(); (хоть в байтах*8-1,хоть в битах-1) ?
sizeof(mask) * __CHAR_BITS__
Цитата(DenisIV @ Dec 25 2008, 23:27) *
И если Direction задано через union...struct... как бит, то налицо ещё и прямая экономия места... ?
Скажем так: если это константа, известная на этапе компиляции. В С++ она может быть параметром шаблона.


Цитата(DenisIV @ Dec 26 2008, 00:40) *
итого мы можем:
Код
(Direction)? mask=1<<0:mask=1<<7;
while(mask)
  {
   PORTx=(*byte&mask)? PORTx|(1<<BIT):PORTx&~(1<<BIT);
   delay_us(x);
   (Direction)? mask<<=1:mask>>1)
  }
Да. Если мы пойдем еще дальше, и заметим, что при входе в цикл mask никак не может быть равно нулю, т.е. цикл всегда должен выполниться хотя бы один раз - мы можем заменить цикл while() {} на более оптимальный do {} while():
Код
mask=1<<(Direction) ? 0 : 7;
do
{
   *byte & mask ? PORTx |= (1<<BIT) : PORTx &= ~(1<<BIT);
   delay_us(x);
}
while ( Direction ? mask<<=1 : mask>>1 );


--------------------
На любой вопрос даю любой ответ
"Write code that is guaranteed to work, not code that doesn’t seem to break" (C++ FAQ)
Go to the top of the page
 
+Quote Post
Goodefine
сообщение Dec 25 2008, 22:56
Сообщение #28


Местный
***

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



Цитата(DenisIV @ Dec 26 2008, 00:27) *
Попробуйте разделить все три процедуры на строчки и поймёте где трабл.

Разделил. Ругается на оба знака присваивания:
Цитата
../main.c:139: error: expected expression before '=' token
../main.c:144: error: expected expression before '=' token

Цитата(DenisIV @ Dec 26 2008, 00:27) *
Кстати, посмотрите, byte может у вас определено ранее #defin'ом как unsigned char? Может просто имя переменной поменять?

Не-а, не в этом дело...
Цитата(DenisIV @ Dec 26 2008, 00:27) *
Ксати, глотнул пива, идея пришла: А не прокатит ли такая конструкция:
Код
...

(Я даже себе в библию программиста запишу lol.gif )

Такая нет. Зато прокатит эта, записывайте... smile.gif
Код
void transmit_byte(unsigned char const *byte, unsigned char direct){
   unsigned char  mask;
       for (mask=(direct)? 1:0x80;mask;delay_us(x),mask=(direct)? mask<<1:mask>>1)
                    PORTW=(*byte&mask)? PORTW|(1<<BIT):PORTW&~(1<<BIT);
                                                                                                     }

Тока нас застрелить могут за такую конструкцию... smile.gif

Цитата(Сергей Борщ @ Dec 26 2008, 01:40) *
Вопроса не понял...

Про С++ в смысле
Цитата(Сергей Борщ @ Dec 26 2008, 01:40) *
Код
...
    (byte & bitmask)? PORTD | (1<<BIT): PORTD & ~(1<<BIT);
...

Правильно, так без знаков присваивания компилится (первый раз у Вас они были), только не работает, надо:
Код
PORTD=(byte & bitmask)? PORTD | (1<<BIT): PORTD & ~(1<<BIT);


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


Участник
*

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



Цитата(Goodefine @ Dec 26 2008, 01:56) *
Такая нет. Зато прокатит эта, записывайте... smile.gif
Код
void transmit_byte(unsigned char const *byte, unsigned char direct){
   unsigned char  mask;
       for (mask=(direct)? 1:0x80;mask;delay_us(x),mask=(direct)? mask<<1:mask>>1)
                    PORTW=(*byte&mask)? PORTW|(1<<BIT):PORTW&~(1<<BIT);
}

Тока нас застрелить могут за такую конструкцию... smile.gif

Могут... И будут правы: функция delay вызывается 7 раз из 8... (эт плохо...)
А for заменяется while...
Походу некоторые компилёры требуют конкретной операции внутри скобок for, а то
(условие)?[тело true]:[тело false] - эт ж if(условие)[тело true]else[тело false] и их и тошнит...

2moderator:А может эти вышеперечисленные весчи собирать и в какую-ндь тему отдельно выделенную закидывать? ('Перед тем, как задать вопрос по С/C++, ознакомтесь...')
А там и возможность замены ?/if, for/while, volatile, #pragma, и базовые вопросы/вырезки сообщений и т.д.
Так сказать, перед тем, как наступить на грабли, прочитайте... Или в поиск... А если нет-то к нам...
?
Go to the top of the page
 
+Quote Post
Goodefine
сообщение Dec 26 2008, 06:52
Сообщение #30


Местный
***

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



Цитата(DenisIV @ Dec 26 2008, 03:42) *
Могут... И будут правы: функция delay вызывается 7 раз из 8... (эт плохо...)

Согласен, но лечится это легко:
Код
void transmit_byte(unsigned char const *byte, unsigned char direct){
   unsigned char  mask;
       for (mask=(direct)? 1:0x80;mask;mask=(direct)? mask<<1:mask>>1)
                  {PORTW=(*byte&mask)? PORTW|(1<<BIT):PORTW&~(1<<BIT);delay_us(x);}
                                                                 }


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


Гуру
******

Группа: Свой
Сообщений: 13 372
Регистрация: 27-11-04
Из: Riga, Latvia
Пользователь №: 1 244



Цитата(DenisIV @ Dec 26 2008, 02:42) *
Походу некоторые компилёры требуют конкретной операции внутри скобок for, а то
(условие)?[тело true]:[тело false] - эт ж if(условие)[тело true]else[тело false] и их и тошнит...
2moderator:А может эти вышеперечисленные весчи собирать и в какую-ндь тему отдельно выделенную закидывать?

Извините, конечно, но написанное Вами про conditional operator нужно закидывать в мусорник sad.gif. Христа ради почитайте стандарт языка.
Цитата
Не знаю, помню когда сдвиг вправо у меня компилёр ошибался
и иногда задвигал в старший бит '1', а влево - всегда '0'

И этот перл - тоже.
P.S.
Программисты пользуются компиляторами и они у них ведут себя стандартно. Рекомендую тоже пререстать пользоватся "компилёрами", правда для этого придется сначала повысить свою квалификацию "программера" до программиста.


--------------------
Feci, quod potui, faciant meliora potentes
Go to the top of the page
 
+Quote Post
DenisIV
сообщение Dec 26 2008, 12:25
Сообщение #32


Участник
*

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



Цитата(zltigo @ Dec 26 2008, 10:48) *
Рекомендую тоже пререстать пользоватся "компилёрами", правда для этого придется сначала повысить свою квалификацию "программера" до программиста.

Зачем так грубо?
Квалификации в области asm более чем достаточно. Была в 90-х годах версия АОН "Полесье" - знакомьтесь : я её автор. С я изучаю не так давно, а слова компилёр, программер, винт флэшка, скомпилять, отформатить являются слэнгом и не говорят о том, что человек чего-то не знает или не уважает. Например, если человек приходит в аптеку и просит резинку, ему дадут не жвачку. Они знают что это. Просто если иногда кому-то режет слух, скажите прямо об этом. Хотя у меня эта работа совмещена с хобби и поэтому я не раздражаюсь, если так говорят.
Я раздражаюсь, если народ не представляет себе, о чём говорит. Например :
- Я такой крутой программист, могу для ПК написать чё хошь!
- Напиши, мне нужен генератор например 1 кГц на н-ной ножке LPT порта.
- Легко!
Потом берём осциллограф и смотрим : Вау, откуда взялся джиттер ?
- Кричит, что щас исправит... Пытается... Не получается... Винда доступ не даёт... Драйвер свой писать надо...
- А под ДОСом сможешь?
- А как под дос написать?

Итого мы видим, что человек учился с 1 по 10 класс, пропустил 2 и 3 классы. И этой базы у него нет. И он не представляет себе аппаратную часть ПК. А как можно написать программу, не зная схемы? Настоящий программист должен и в схемах рубить и с паяльником уметь!
Go to the top of the page
 
+Quote Post
_Pasha
сообщение Dec 26 2008, 12:45
Сообщение #33


;
******

Группа: Участник
Сообщений: 5 646
Регистрация: 1-08-07
Пользователь №: 29 509



Цитата(Сергей Борщ @ Dec 26 2008, 00:13) *
Что именно в этой записи ему будет непонятно? Единственным возможным побочным эффектом может быть лишнее чтение PORTW после записи.

была такая история...
Go to the top of the page
 
+Quote Post
zltigo
сообщение Dec 26 2008, 13:06
Сообщение #34


Гуру
******

Группа: Свой
Сообщений: 13 372
Регистрация: 27-11-04
Из: Riga, Latvia
Пользователь №: 1 244



Цитата(DenisIV @ Dec 26 2008, 15:25) *
Я раздражаюсь, если народ не представляет себе, о чём говорит.....

Представьте себе! я тоже. Дальше объяснять надо smile.gif smile.gif smile.gif?
Цитата
...и с паяльником уметь!

и с паяльником я с 5 лет - уже 43 года как... Что не мешает мне и прилично программировать.


--------------------
Feci, quod potui, faciant meliora potentes
Go to the top of the page
 
+Quote Post
Goodefine
сообщение Dec 26 2008, 13:47
Сообщение #35


Местный
***

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



Цитата(_Pasha @ Dec 26 2008, 16:45) *

И правда, скобки нужны. А все, видать, потому что оператор присваивания имеет самый низкий приоритет...Так работает:
Код
(*byte&mask)? (PORTW|=(1<<BIT)):(PORTW&=~(1<<BIT));

Результат абсолютно идентичный...

Сообщение отредактировал Goodefine - Dec 26 2008, 14:00


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


Гуру
******

Группа: Свой
Сообщений: 10 920
Регистрация: 5-04-05
Пользователь №: 3 882



Сообщение модератора.
Уважаемые, участники! Завязывайте флудить и "меряться пиписьками". Пожалуйста, придерживайтесь темы топика!
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 Текстовая версия Сейчас: 21st July 2025 - 20:53
Рейтинг@Mail.ru


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