Перейти к содержанию
    

Как из Байта получить восемь значений 0 и 1

Странно, что еще до интегралов не добрались...

#define BIT 1 /* задаем нужный номер пина (0...7) */
for (unsigned char bitmask = 1; bitmask; bitmask <<= 1)
{
   (byte & bitmask)? PORTW |= (1<<BIT): PORTW &= ~(1<<BIT);
   delay_ms(x);
}

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Странно, что еще до интегралов не добрались...

#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?)

 

Не сталкивались?

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

иногда задвигал в старший бит '1', а влево - всегда '0'

(Или это был кольцевой сдвиг?)

Нету такого сдвига в стандарте Си.

(Или тип переменной был signed?)
Угу, скорее всего именно так. Операция сдвига над переменной типа signed проводилась. Когда у переменной типа signed устанавливают старший бит, то число становится отрицательным. А при операции сдвига знак у такой переменной меняется не должен. Т.е. единичка-то вправо сдвигается, но в старшем бите она все равно остается.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

...

Компилятор CAVR (и avr-gcc тоже) не поймет запись

 (byte & bitmask)? PORTW |= (1<<BIT): PORTW &= ~(1<<BIT);

Кроме того, CAVR не допускает объявления вида:

for (unsigned char mask ...)

Странно, что еще до интегралов не добрались...

До интегралов ща доберемся... :)

...
#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

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Компилятор CAVR (и avr-gcc тоже) не поймет запись

 (byte & bitmask)? PORTW |= (1<<BIT): PORTW &= ~(1<<BIT);

Что именно в этой записи ему будет непонятно? Единственным возможным побочным эффектом может быть лишнее чтение PORTW после записи.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Что именно в этой записи ему будет непонятно?..

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

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

у avr-gcc более длинное ругательство... Насколько я понял, компилятору не нравятся знаки равенства в выражениях после оператора сравнения...
Я заменил PORTW на PORTD, поскольку у меги8 нет порта W:
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) */

Никакой ругани.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Я заменил PORTW на PORTD, поскольку у меги8 нет порта...

Дык и я заменил :)

#define PORTW PORTD

Никакой ругани...

У Вас объектный код (*.cpp)? Привожу скриншот компиляции Вашего кода (просто вставил его в рабочий проект) в WinAVR 20080610 под AVR Studio 4

А вот так компилится:

void Test1(uchar byte, uchar bitmask)
{
PORTD=(byte & bitmask)? PORTD | (1<<BIT): PORTD & ~(1<<BIT);
}

post-29581-1230238754_thumb.jpg

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Дык и я заменил :)
#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: )

И если Direction задано через union...struct... как бит, то налицо ещё и прямая экономия места... ?

Изменено пользователем DenisIV

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

У Вас объектный код (*.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. Завтра могу поставить более свежую.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Ещё глотнул пива...

Ведь оператор 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)
  }

Или не можем?

По-моему это абсолютно идентичные логически и т.д. конструкции...

Гуру, если не прав, поправьте...

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

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

 

 

итого мы можем:

(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 );

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Попробуйте разделить все три процедуры на строчки и поймёте где трабл.

Разделил. Ругается на оба знака присваивания:

../main.c:139: error: expected expression before '=' token

../main.c:144: error: expected expression before '=' token

Кстати, посмотрите, byte может у вас определено ранее #defin'ом как unsigned char? Может просто имя переменной поменять?

Не-а, не в этом дело...

Ксати, глотнул пива, идея пришла: А не прокатит ли такая конструкция:

...

(Я даже себе в библию программиста запишу lol.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);
                                                                                                     }

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

 

Вопроса не понял...

Про С++ в смысле

...
    (byte & bitmask)? PORTD | (1<<BIT): PORTD & ~(1<<BIT);
...

Правильно, так без знаков присваивания компилится (первый раз у Вас они были), только не работает, надо:

PORTD=(byte & bitmask)? PORTD | (1<<BIT): PORTD & ~(1<<BIT);

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Такая нет. Зато прокатит эта, записывайте... :)

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);
}

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

Могут... И будут правы: функция delay вызывается 7 раз из 8... (эт плохо...)

А for заменяется while...

Походу некоторые компилёры требуют конкретной операции внутри скобок for, а то

(условие)?[тело true]:[тело false] - эт ж if(условие)[тело true]else[тело false] и их и тошнит...

 

2moderator:А может эти вышеперечисленные весчи собирать и в какую-ндь тему отдельно выделенную закидывать? ('Перед тем, как задать вопрос по С/C++, ознакомтесь...')

А там и возможность замены ?/if, for/while, volatile, #pragma, и базовые вопросы/вырезки сообщений и т.д.

Так сказать, перед тем, как наступить на грабли, прочитайте... Или в поиск... А если нет-то к нам...

?

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Могут... И будут правы: функция 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);}
                                                                 }

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Присоединяйтесь к обсуждению

Вы можете написать сейчас и зарегистрироваться позже. Если у вас есть аккаунт, авторизуйтесь, чтобы опубликовать от имени своего аккаунта.

Гость
Ответить в этой теме...

×   Вставлено с форматированием.   Вставить как обычный текст

  Разрешено использовать не более 75 эмодзи.

×   Ваша ссылка была автоматически встроена.   Отображать как обычную ссылку

×   Ваш предыдущий контент был восстановлен.   Очистить редактор

×   Вы не можете вставлять изображения напрямую. Загружайте или вставляйте изображения по ссылке.

×
×
  • Создать...