mozg12342 0 31 марта, 2018 Опубликовано 31 марта, 2018 · Жалоба Добрый день!!! Решил вот опробовать Atmel studio 7. Столкнулся со следующими странностями: Если в поле условия оператора if вставить любую логическую операцию, то компилятор отказывается выполнять её и просто пропускает. Если к примеру выполню необходимую операцию, запишу в переменную и переменную вставлю в поле условия, то работает как надо. Раньше писал код в Code Vision? там так делать можно было. Можно ли в студии так делать или прийдется каждый раз использовать промежуточную переменную? Написал простой код для примера: #define F_CPU 8000000 #include <avr/io.h> #include <avr/interrupt.h> #include <util/delay.h> unsigned char r; int main(void) { DDRB=0b11111111; PORTB=0b00000000; DDRC=0b00000000; PORTC=0b00000001; DDRD=0b00000000; PORTD=0b00000000; ACSR=0x80; //------------------------------------------------ while (1) { if(~(PINC|0b11111110)) //если bit 0 порта С равен нулю, то выполнить условие { PORTB=0xFF; } r=(~(PINC|0b11111110)); } } Дизасемблер показывает: 00000013 CLR R1 Clear Register 00000014 OUT 0x3F,R1 Out to I/O location 00000015 LDI R28,0x5F Load immediate 00000016 LDI R29,0x04 Load immediate 00000017 OUT 0x3E,R29 Out to I/O location 00000018 OUT 0x3D,R28 Out to I/O location --- No source file ------------------------------------------------------------- 00000019 LDI R18,0x00 Load immediate 0000001A LDI R26,0x60 Load immediate 0000001B LDI R27,0x00 Load immediate 0000001C RJMP PC+0x0002 Relative jump 0000001D ST X+,R1 Store indirect and postincrement 0000001E CPI R26,0x61 Compare with immediate 0000001F CPC R27,R18 Compare with carry 00000020 BRNE PC-0x03 Branch if not equal 00000021 RCALL PC+0x0003 Relative call subroutine 00000022 RJMP PC+0x0015 Relative jump 00000023 RJMP PC-0x0023 Relative jump --- C:\STUDIOmk\transmitter\transmitter\Debug/.././main.c ---------------------- { DDRB=0b11111111; 00000024 SER R24 Set Register 00000025 OUT 0x17,R24 Out to I/O location PORTB=0b00000000; 00000026 OUT 0x18,R1 Out to I/O location DDRC=0b00000000; 00000027 OUT 0x14,R1 Out to I/O location PORTC=0b00000001; 00000028 LDI R24,0x01 Load immediate 00000029 OUT 0x15,R24 Out to I/O location DDRD=0b00000000; 0000002A OUT 0x11,R1 Out to I/O location PORTD=0b00000000; 0000002B OUT 0x12,R1 Out to I/O location ACSR=0x80; 0000002C LDI R24,0x80 Load immediate 0000002D OUT 0x08,R24 Out to I/O location PORTB=0xFF; 0000002E SER R25 Set Register if(~(PINC|0b11111110)) //если bit 0 порта С равен нулю, то выполнить условие 0000002F IN R24,0x13 In from I/O location а PORTB=0xFF; 00000030 OUT 0x18,R25 Out to I/O location r=(~(PINC|0b11111110)); 00000031 IN R24,0x13 In from I/O location 00000032 ORI R24,0xFE Logical OR with immediate 00000033 COM R24 One's complement 00000034 STS 0x0060,R24 Store direct to data space 00000036 RJMP PC-0x0007 Relative jump --- No source file ------------------------------------------------------------- 00000037 CLI Global Interrupt Disable 00000038 RJMP PC-0x0000 Relative jump Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Harvester 0 31 марта, 2018 Опубликовано 31 марта, 2018 · Жалоба if(~(PINC|0b11111110)) //если bit 0 порта С равен нулю, то выполнить условие Для проверки бита нужно использовать оператор "логическое И" (&). А для логического отрицания - оператор "!". В вашем исполнении условие всегда истинно, поэтому компилятор его выкидывает. Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
k155la3 27 31 марта, 2018 Опубликовано 31 марта, 2018 · Жалоба А если внимательно почитать warn, то скорее всего там есть упоминание об это факте. Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
dimka76 63 31 марта, 2018 Опубликовано 31 марта, 2018 · Жалоба if( (PINC & (1 << 0)) == 0 ) //если bit 0 порта С равен нулю, то выполнить условие Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
aiwa 0 31 марта, 2018 Опубликовано 31 марта, 2018 · Жалоба Можно ли в студии так делать или прийдется каждый раз использовать промежуточную переменную? Причина не в переменной. По стандарту языка компилятор перед выполнением операции расширяет байт до целого нулями. Которые после инвертирования превращаются в "непредвиденные" единицы. Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Сергей Борщ 143 1 апреля, 2018 Опубликовано 1 апреля, 2018 · Жалоба Которые после инвертирования превращаются в "непредвиденные" единицы.Да там и до расширения после "ИЛИ" единиц хватает. Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
k155la3 27 1 апреля, 2018 Опубликовано 1 апреля, 2018 · Жалоба if( (PINC & (1 << 0)) == 0 ) //если bit 0 порта С равен нулю, то выполнить условие if( (PINC & 0x01) ^ 0x01 ) . . . //если bit 0 порта С равен нулю, то выполнить условие if( (PINC & 0x10) ^ 0x10 ) . . . //если bit 7 порта С равен нулю, то выполнить условие //если bit 7 bit 4 порта С равен нулю, то выполнить условие #define IS_BIT_NULL(PORT, BIT_MASK) ( (PORT & BIT_MASK) ^ BIT_MASK ) Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
adnega 11 1 апреля, 2018 Опубликовано 1 апреля, 2018 · Жалоба if( (PINC & 0x10) ^ 0x10 ) . . . //если bit 7 порта С равен нулю, то выполнить условие может, маска "bit 7" равна 0x80 ? Зачем себя путать, отказываясь от (((PINC >> n) & 1) == 0/1) ? Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
k155la3 27 1 апреля, 2018 Опубликовано 1 апреля, 2018 · Жалоба может, маска "bit 7" равна 0x80 ? Вах ! подловили "двоечника" :) . . . Зачем себя путать, отказываясь от (((PINC >> n) & 1) == 0/1) ? Когда надо "просчитать" несколько битов сразу (в одном условии), использовать сдвиг можно, но менее компактно. IMHO. Если маски изначально забиты в виде имен-макросов, то ошибки маловероятны. ps для проверки одного бита на 1 достаточно if( PINC & ONE_BIT_MASK ) . . . . . на 0 if( ~PINC & ONE_BIT_MASK ) . . . . . естественно, эти выражения несовместимы с лог. операторами && итд. Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
mozg12342 0 1 апреля, 2018 Опубликовано 1 апреля, 2018 (изменено) · Жалоба Для проверки бита нужно использовать оператор "логическое И" (&). А для логического отрицания - оператор "!". В вашем исполнении условие всегда истинно, поэтому компилятор его выкидывает. Моя логика такая: если бит 0 порта С равен еденице, то 0b00000001 поразрядное или 0b11111110 __________ 0b11111111 поразрядное отрицание __________ 0b00000000 если бит 0 порта С равен нулю то 0b00000000 поразрядное или 0b11111110 __________ 0b11111110 поразрядное отрицание __________ 0b00000001 Изменено 1 апреля, 2018 пользователем mozg12342 Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
adnega 11 1 апреля, 2018 Опубликовано 1 апреля, 2018 · Жалоба Вах ! подловили "двоечника" :) Ага. В пределах байта это сразу бросилось в глаза, а вот в 32 битной маске уже без листочка и ручки не смогу. Когда надо "просчитать" несколько битов сразу (в одном условии), использовать сдвиг можно, но менее компактно. IMHO. В боевом коде выглядит довольно компактно и понятно if(TIM3->SR & (1 << TIM_SR_CC1IIF)) Конечно же никаких магический чисел быть не должно. Если маски изначально забиты в виде имен-макросов, то ошибки маловероятны. Я везде использую не маски, а номера битов. Да, в условиях появляется лишние (1 <<, зато инициализация удобная TIM3->CCMR1 = 0 | (OC_MODE_PWM1 << TIM_CCMR1_OC1M) | (OC_MODE_PWM1 << TIM_CCMR1_OC2M); TIM3->CCER = (1 << TIM_CCER_CC1E); TIM3->DIER = 0 | (1 << TIM_DIER_CC1IE) | (0 << TIM_DIER_CC2IE) | (1 << TIM_DIER_UIE); Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
jcxz 243 1 апреля, 2018 Опубликовано 1 апреля, 2018 · Жалоба Моя логика такая: Прочитайте про типы данных в языке си. И про приведения (расширения) типов. и про типы операций, что такое "побитовое И", а что такое "побитовое ИЛИ". Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
adnega 11 1 апреля, 2018 Опубликовано 1 апреля, 2018 · Жалоба поразрядное и Это называется "или". Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
jcxz 243 1 апреля, 2018 Опубликовано 1 апреля, 2018 · Жалоба В боевом коде выглядит довольно компактно и понятно if(TIM3->SR & (1 << TIM_SR_CC1IIF)) Скобки-то зачем? Приоритет операций никто не отменял. Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
mozg12342 0 1 апреля, 2018 Опубликовано 1 апреля, 2018 · Жалоба if( (PINC & (1 << 0)) == 0 ) //если bit 0 порта С равен нулю, то выполнить условие Прекрасно!!! эта комбинация работает!, ровно как и комбинация if(~PINC&(1<<0)). А я видимо немного на мудрил. Хотя по логике и на бумаге вроде все верно Спасибо! Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться