Побитовое |

AVS
Offline
Зарегистрирован: 11.12.2017

Подскажите, правильно ли я понимаю, что при такой записи( мождет атк нормальные люди вообще не пишут, но тем не менее 

если бит ADSC на данный момент установлен в 1, то

ADCSRA |= (0 << ADSC);

такая запись не установит этот бит в 0, а такая 

ADCSRA = (0 << ADSC);

установит?

DetSimen
DetSimen аватар
Онлайн
Зарегистрирован: 25.01.2017

вторая запись установит ВСЕ биты ADCSRA в 0

DetSimen
DetSimen аватар
Онлайн
Зарегистрирован: 25.01.2017

сначала надо в промежуточном регистре сделать маску.  установить бит ADSC в 1 и инвертировать.  а потом сделать & ADCSRA и получившейся маски.  

sadman41
Offline
Зарегистрирован: 19.10.2016
ADCSRA |= (0 << ADSC) то же самое, что ADCSRA = ADCSRA | (0 << ADSC)
 
Теперь представляйте, что ADCSRA - это A, (0 << ADSC) - это B и смотрите сюда: http://lebedevann.tesigoh29.ru/p62aa1.html -> Дизъюнкция
AVS
Offline
Зарегистрирован: 11.12.2017

пф, ахаха, серьезно?? вот это поворот...а потом я удивляюсь, почему у меня все работает непойми как

ADCSRA &= ~(1 << ADSC);

как понимаю, нужно писать как-то так7

DetSimen
DetSimen аватар
Онлайн
Зарегистрирован: 25.01.2017
AVS
Offline
Зарегистрирован: 11.12.2017

sadman41 пишет:

ADCSRA |= (0 << ADSC) то же самое, что ADCSRA = ADCSRA | (0 << ADSC)
 
Теперь представляйте, что ADCSRA - это A, (0 << ADSC) - это B и смотрите сюда: http://lebedevann.tesigoh29.ru/p62aa1.html -> Дизъюнкция

ADCSRA - 0b10000000 (aden  = 1)

0 << ADSC -0b00000000

0b10000000|0b00000000 = 0b10000000 

то есть останется так же единица

AVS
Offline
Зарегистрирован: 11.12.2017

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

AVS
Offline
Зарегистрирован: 11.12.2017

а как тоглда, к примеру, написать вот такую строчку 

SMCR в этом регистре нужно установить следущие биты так (0 << SM2),(1 << SM1),(0 << SM0) ;

по отделоьности, SMCR& = ~((1 << SM2)|(1 << SM0))

и SMCR| = (1 << SM1)

или можнно как-то в 1 строку упихнуть?

DetSimen
DetSimen аватар
Онлайн
Зарегистрирован: 25.01.2017

чем вдумчиво изучать битовые операции, используй лучше ардуинкины setBit() и clearBit().  Папрастому. 

 

AVS
Offline
Зарегистрирован: 11.12.2017

но ведь я уже вот почти полностью разобрался) мне к сожалению или к счастью больше нравится такая запись

ЕвгенийП
ЕвгенийП аватар
Offline
Зарегистрирован: 25.05.2015

DetSimen пишет:

чем вдумчиво изучать битовые операции, используй лучше ардуинкины setBit() и clearBit().  Папрастому. 

Настоящие программисты не используют Паскаль!

AVS
Offline
Зарегистрирован: 11.12.2017

я, конечно, не настоящий программист, но все же

AVS пишет:

а как тоглда, к примеру, написать вот такую строчку 

SMCR в этом регистре нужно установить следущие биты так (0 << SM2),(1 << SM1),(0 << SM0) ;

по отделоьности, SMCR& = ~((1 << SM2)|(1 << SM0))

и SMCR| = (1 << SM1)

или можнно как-то в 1 строку упихнуть?

DetSimen
DetSimen аватар
Онлайн
Зарегистрирован: 25.01.2017

SMCR  = SMCR & (~((1 << SM2)|(1 << SM0))) | (1 << SM1);

в одну строчку. 

DetSimen
DetSimen аватар
Онлайн
Зарегистрирован: 25.01.2017

Наверняка есть решение короче. но сёдня чота башке болеть охота, думать ей лень. 

AVS
Offline
Зарегистрирован: 11.12.2017

все, суть я понял, примногоблагодарен

DetSimen
DetSimen аватар
Онлайн
Зарегистрирован: 25.01.2017

нальёшь, при случае. 

5N62V
Offline
Зарегистрирован: 25.02.2016

DetSimen пишет:

SMCR  = SMCR & (~((1 << SM2)|(1 << SM0))) | (1 << SM1);

в одну строчку. 

А так можно записать : SMCR&=0b11111010; ?

DetSimen
DetSimen аватар
Онлайн
Зарегистрирован: 25.01.2017

5N62V пишет:

А так можно записать : SMCR&=0b11111010; ?

Если в бите SM1 был 0, то результат будет не как требуется по логике.

5N62V
Offline
Зарегистрирован: 25.02.2016

DetSimen пишет:

Если в бите SM1 был 0, то результат будет не как требуется по логике.

ага, опередили, уже увидел :) тогда все равно надо будет еще SMCR|=2; писать

AVS
Offline
Зарегистрирован: 11.12.2017

DetSimen пишет:

нальёшь, при случае. 

да я вам уже минимум два раза налить должен)

AVS
Offline
Зарегистрирован: 11.12.2017

не, ну если в таком виде писать, то можно ведь и просто SMCR=0b11111010; написать

5N62V
Offline
Зарегистрирован: 25.02.2016

AVS пишет:

не, ну если в таком виде писать, то можно ведь и просто SMCR=0b11111010; написать

тогда все остальные биты регистра вы так же устанавливаете в единицу.

AVS
Offline
Зарегистрирован: 11.12.2017

5N62V пишет:

AVS пишет:

не, ну если в таком виде писать, то можно ведь и просто SMCR=0b11111010; написать

тогда все остальные биты регистра вы так же устанавливаете в единицу.

не, ну я имею ввиду, что если нам не важны остальные биты и, к примеру, они установленный в 0, то так же прописываем 0

SMCR=0b00000101;

ну а вообще, конечно, это опасно, можно ненароком перезаписать то, что не стоило бы трогать

5N62V
Offline
Зарегистрирован: 25.02.2016

Если другие биты не важны, то можно. Но я так понимаю , это дурной тон писать магические цифры. Хотя такая запись работает в разы быстрее, что может быть важно в , например, функциях, особенно в ф-ях прерывания.

AVS
Offline
Зарегистрирован: 11.12.2017

5N62V пишет:

Если другие биты не важны, то можно. Но я так понимаю , это дурной тон писать магические цифры. Хотя такая запись работает в разы быстрее, что может быть важно в , например, функциях, особенно в ф-ях прерывания.

насколько мне известно, не оч хорошо в прерывания пихать ф-ии

ЕвгенийП
ЕвгенийП аватар
Offline
Зарегистрирован: 25.05.2015

5N62V пишет:

такая запись работает в разы быстрее, 

В разы бастрее чего? Вы думаете, что

a = 0x04;

работает быстрее, чем

#define Bit_TWO 2
a = (1 << Bit_TWO);

Таки нет. Одинаково. Или Вы о чём-то другом?

AVS
Offline
Зарегистрирован: 11.12.2017

ЕвгенийП пишет:

5N62V пишет:

такая запись работает в разы быстрее, 

В разы бастрее чего? Вы думаете, что

a = 0x04;

работает быстрее, чем

#define Bit_TWO 2
a = (1 << Bit_TWO);

Таки нет. Одинаково. Или Вы о чём-то другом?

 я думаю 5N62V имел ввиду, что вот это SMCR = 0b00001011; работает куда быстрее, чем вот это SMCR  = SMCR & (~((1 << SM2) | (1 << SM0))) | (1 << SM1);, мне кажется так и есть

b707
Онлайн
Зарегистрирован: 26.05.2017

AVS пишет:

 я думаю 5N62V имел ввиду, что вот это SMCR = 0b00001011; работает куда быстрее, чем вот это SMCR  = SMCR & (~((1 << SM2) | (1 << SM0))) | (1 << SM1);, мне кажется так и есть

это не так. При компиляции вся длинная цепочка

(~((1 << SM2) | (1 << SM0))) | (1 << SM1);

заменяется одной константой

Реально это эквивалентно по времени одной операции SMCR  = SMCR & X

5N62V
Offline
Зарегистрирован: 25.02.2016

ЕвгенийП пишет:

Таки нет. Одинаково. Или Вы о чём-то другом?

Я полагаю, что запись SMCR  = SMCR & (~((1 << SM2)|(1 << SM0))) | (1 << SM1);  работает медленнее, чем

 SMCR  &= 250;

 SMCR|=2;

 

b707
Онлайн
Зарегистрирован: 26.05.2017

5N62V пишет:

Я полагаю, что запись SMCR  = SMCR & (~((1 << SM2)|(1 << SM0))) | (1 << SM1);  работает медленнее, чем

 SMCR  &= 250;

 SMCR|=2;

 

а я думаю быстрее...

В первой записи 2 действия, во второй - четыре.

5N62V
Offline
Зарегистрирован: 25.02.2016

b707 пишет:

это не так. При компиляции вся длинная цепочка

(~((1 << SM2) | (1 << SM0))) | (1 << SM1);

заменяется одной константой

Реально это эквивалентно по времени одной операции SMCR  = SMCR & X

Хм. Я когда-то задался этим вопросом, прогнал на цикле 1000 раз и замерил время. Вариант просто присваивания значению регистру крутился в 4 раза быстрее, чем вариант со сдвигами и битовыми операциями. С тех пор стараюсь их не использовать.   Хотя.... Может быть все дело было в оптимизации, и поэтому результат эксперимента был мной неправильно истолкован. Подумалось.

b707
Онлайн
Зарегистрирован: 26.05.2017

5N62V пишет:

Хм. Я когда-то задался этим вопросом, прогнал на цикле 1000 раз и замерил время. Вариант просто присваивания значению регистру крутился в 4 раза быстрее, чем вариант со сдвигами и битовыми операциями.

Результат сравнения времени очень завсисит от того, являются аргументы константами или переменными

5N62V
Offline
Зарегистрирован: 25.02.2016

b707 пишет:

 

Результат сравнения времени очень завсисит от того, являются аргументы константами или переменными

На сколько я помню, я подставлял константы.

5N62V
Offline
Зарегистрирован: 25.02.2016

AVS пишет:

насколько мне известно, не оч хорошо в прерывания пихать ф-ии

я и не предлагаю.  Я говорил про функцию обработчик прерывания.

ЕвгенийП
ЕвгенийП аватар
Offline
Зарегистрирован: 25.05.2015

5N62V, я думаю, что при умолчательной (из коробки) оптимизации разницы быть не должно никакой. Но, поскольку хрен его знает, что там эта 02 наоптимизирует, я тоже проведу тест, как домой приду и выложу тогда.

ЕвгенийП
ЕвгенийП аватар
Offline
Зарегистрирован: 25.05.2015

AVS пишет:

насколько мне известно, не оч хорошо в прерывания пихать ф-ии

Чем это они так провинились? Нормально вполне. А что, по Вашему, делает attachInterrupt? Вы не поверите, но организует вызов Вашей функции из обработчика прерывания.

5N62V
Offline
Зарегистрирован: 25.02.2016

ЕвгенийП пишет:

  я тоже проведу тест

Уже:

#define CIRCLE 1000
uint32_t time = 0;

void setup() {
Serial.begin(9600);

}

void loop() {
  time = micros();
for(uint16_t i = 0; i<CIRCLE; i++) PORTD = 0b10001100;
time = micros()-time;
Serial.print("Way1. Time = "); Serial.println(time);

  time = micros();
for(uint16_t i = 0; i<CIRCLE; i++) PORTD=((1<<7)|(1<<3)|(1<<2));
time = micros()-time;
Serial.print("Way2. Time = "); Serial.println(time);

while(1);

}

и вот результат:

Way1. Time = 316
Way2. Time = 316
 
 
ПС. видно с памятью моей плохо.  :( Был неправ, каюсь :)
ЕвгенийП
ЕвгенийП аватар
Offline
Зарегистрирован: 25.05.2015

Ну, собственно так и должно быть из общих соображений.