xemul 0 25 декабря, 2008 Опубликовано 25 декабря, 2008 · Жалоба Странно, что еще до интегралов не добрались... #define BIT 1 /* задаем нужный номер пина (0...7) */ for (unsigned char bitmask = 1; bitmask; bitmask <<= 1) { (byte & bitmask)? PORTW |= (1<<BIT): PORTW &= ~(1<<BIT); delay_ms(x); } Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
DenisIV 0 25 декабря, 2008 Опубликовано 25 декабря, 2008 · Жалоба Странно, что еще до интегралов не добрались... #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?) Не сталкивались? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
rezident 0 25 декабря, 2008 Опубликовано 25 декабря, 2008 · Жалоба иногда задвигал в старший бит '1', а влево - всегда '0' (Или это был кольцевой сдвиг?) Нету такого сдвига в стандарте Си. (Или тип переменной был signed?)Угу, скорее всего именно так. Операция сдвига над переменной типа signed проводилась. Когда у переменной типа signed устанавливают старший бит, то число становится отрицательным. А при операции сдвига знак у такой переменной меняется не должен. Т.е. единичка-то вправо сдвигается, но в старшем бите она все равно остается. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Goodefine 0 25 декабря, 2008 Опубликовано 25 декабря, 2008 (изменено) · Жалоба ... Компилятор 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); //старший бит вперед ... Изменено 25 декабря, 2008 пользователем Goodefine Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Сергей Борщ 121 25 декабря, 2008 Опубликовано 25 декабря, 2008 · Жалоба Компилятор CAVR (и avr-gcc тоже) не поймет запись (byte & bitmask)? PORTW |= (1<<BIT): PORTW &= ~(1<<BIT); Что именно в этой записи ему будет непонятно? Единственным возможным побочным эффектом может быть лишнее чтение PORTW после записи. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Goodefine 0 25 декабря, 2008 Опубликовано 25 декабря, 2008 · Жалоба Что именно в этой записи ему будет непонятно?.. Х/з, самому интересно. Сначала и я так же написал... CAVR говорит "Error... mising":" ", у avr-gcc более длинное ругательство... Насколько я понял, компилятору не нравятся знаки равенства в выражениях после оператора сравнения... Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Сергей Борщ 121 25 декабря, 2008 Опубликовано 25 декабря, 2008 · Жалоба у 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) */ Никакой ругани. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Goodefine 0 25 декабря, 2008 Опубликовано 25 декабря, 2008 · Жалоба Я заменил 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); } Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
DenisIV 0 25 декабря, 2008 Опубликовано 25 декабря, 2008 (изменено) · Жалоба Дык и я заменил :) #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) ? Тогда прога будет просто супер универсальной! (Я даже себе в библию программиста запишу ) И если Direction задано через union...struct... как бит, то налицо ещё и прямая экономия места... ? Изменено 25 декабря, 2008 пользователем DenisIV Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Сергей Борщ 121 25 декабря, 2008 Опубликовано 25 декабря, 2008 · Жалоба У Вас объектный код (*.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. Завтра могу поставить более свежую. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
DenisIV 0 25 декабря, 2008 Опубликовано 25 декабря, 2008 · Жалоба Ещё глотнул пива... Ведь оператор 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) } Или не можем? По-моему это абсолютно идентичные логически и т.д. конструкции... Гуру, если не прав, поправьте... Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Сергей Борщ 121 25 декабря, 2008 Опубликовано 25 декабря, 2008 · Жалоба Сюда даже вместо 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 ); Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Goodefine 0 25 декабря, 2008 Опубликовано 25 декабря, 2008 · Жалоба Попробуйте разделить все три процедуры на строчки и поймёте где трабл. Разделил. Ругается на оба знака присваивания: ../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); Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
DenisIV 0 25 декабря, 2008 Опубликовано 25 декабря, 2008 · Жалоба Такая нет. Зато прокатит эта, записывайте... :) 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, и базовые вопросы/вырезки сообщений и т.д. Так сказать, перед тем, как наступить на грабли, прочитайте... Или в поиск... А если нет-то к нам... ? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Goodefine 0 26 декабря, 2008 Опубликовано 26 декабря, 2008 · Жалоба Могут... И будут правы: функция 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);} } Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться