скіду штыфт з дапамогай "& = ~ (1 << PINXX)"

папярэджанне пра шкоду курэння: пачатковец агульная

чаму гэта стандартны метад для скіду шпількі:

REGISTER_NAME &= ~(1 << PINXX);

а не проста:

REGISTER_NAME &= (0 << PINXX);

thanks in advance for time, answers & bibliographical hints

1
Ніхто не зразумее, што. Гэта пытанне для розуму чытачоў.
дададзена аўтар Amit, крыніца
Другі метад не выглядае простым, ён выглядае як складаны спосаб сказаць register_name = 0 (які не з'яўляецца такой жа, як у першым спосабе)
дададзена аўтар npostavs, крыніца

5 адказы

Гэта трэба мець на ўвазе, што кожны знак азначае, што ў

REGISTER_NAME &= ~(1 << PINXX);

1) << - this is logical shift left. This means that number on left side is shifted left by number of binary position, which is in right side.

For example. 1 << 5 means 0b00000001 shifted left 5 times (while zeroes appears at right). i.e. result will be 0b00100000 == 32.

In other words, 1 << X means "give a number, in which only bit #X is set, and other bits are zeros"

Ok. At this point you can see that 0 << anything gives always zero,

2) <�моцны> ~ - гэта пабітавае адмаўленне. Гэта Інвертуйце значэнне кожнага біта ў кожнай пазіцыі ў двайковым прадстаўленні колькасці.

I.e. ~0b00100000 (or ~(1 << 5)) == 0b11011111.

Concluding, ~(1 << X) means "give a number, in which all bits are set, except of bit #X, which is to became zero"

3) &= - this is assignment combined with bitwise AND. I.e. X &= Y is the same that X = X & Y;

4) & - this is bitwise AND. result of this operation is number, in which only that bits are set, which are set at same position in both operands, and zero otherwise.

Гэта азначае, што калі канкрэтны біт у адным з аперанд усталяваны, той жа біт у выніку будзе роўная біт у такім жа становішчы іншага аперанда. Калі гэты біт роўны нулю ў любым аперанда, той жа біт выніку будзе роўны нулю.

You can rephrase X &= Y in this way: "if a bit in Y is one, leave the bit at the same position in X unchanged (whatever it is - one or zero). If the bit in Y is zero, then clear the same bit in X."

As was said above, ~(1 << N) gives a number where every bit is set, except of N. So X &= ~(1 << N) means "Clear bit #N, and remain all other bits unchanged".

Цяпер вы можаце бачыць, што

REGISTER_NAME &= (0 << PINXX); 

is nonsense, because it means "Clear all the bits". It is the same as REGISTER_NAME = 0;

By the way, if you are using assignment in this form:

REGISTER_NAME |= (0 << PINXX) | (1 << PINYY);

гэта не азначае, што "ўстанавіць бітая PINYY і выразныя бітая PINXX», гэта азначае «ўсталяваць бітавую PINYY і нічога не рабіць з бітным PINXX (як і ўсімі іншымі бітамі)»

2
дададзена
вельмі добра растлумачана
дададзена аўтар MikeD, крыніца

Чаму б зрушваючы нуль быць больш «просты»? Гэта не мае ніякага сэнсу, гэта проста 0, які пры пабітавае аперацыі AND б ачысціць ўвесь рэестр. Не зусім тое, што вы хочаце.

Памятаеце, што гэта:

REGISTER &= ~(1 << PIN);

сродак

REGISTER = REGISTER & ~(1 << PIN);

гэта значыць гэта пабітавае і рэгістр з канстантай, якая мае 1s ва ўсіх пазіцыях, акрамя біта нумары PIN . У прыватнасці, у ~ аператар ставіцца да зрушанай значэння, а не толькі ў 1 .

Гэта мае эфект ўстаноўкі толькі што біт 0, а не дакранацца да іншых. Толькі тое, што вы хочаце, што, вядома, чаму гэта код, які вы заўсёды бачыце выкарыстоўваецца. :)

0
дададзена
дзіўнае, дзякуй
дададзена аўтар mgd, крыніца

To set a bit, you variable |= (1 << position). This will generate something like 0000100, assuming position = 2.
To unset a bit, you do the reverse: you AND instead of OR, and the mask is the opposite of the other.

Мяркуючы, што пазіцыя = 2,

  1. 1 << position: 00000100 as before.
  2. Reverse it with bitwise not (~): 11111011.
  3. Apply bitwise AND. If it's `11011100, for example, you get:

    11011100 &
    11111011 =
    -----------
    11011000
    _____^____

Дзеля мэты я меркаваў, 8-бітавы значэння, але працэдура не мае якіх-небудзь змяненняў з больш доўгімі шырыні. Гэта можа здацца трохі цяжка ў першы раз, але, калі вы Вылічэнне сябе, логіка ззаду яго павінен з'явіцца; гэта матэматыка, у рэшце рэшт.

0
дададзена
вельмі карысна, дзякуй
дададзена аўтар mgd, крыніца

першая каманда скіне штыфт XX , другая каманда скідае усе кантакты, звязаныя з гэтым рэгістра

0
дададзена

Я думаю, што блытаніна адбываецца таму, што вы атрымалі недакладнае апісанне таго, што адбываецца ў «стандартным» шляху.

Я падазраю, што вы сказалі, што калі вы робіце гэта:

REGISTER_NAME &= ~(1 << PINXX);

гэта азначае, што "лагічна і штыфт ў становішчы PINXX з ~ 1 , гэта значыць з 0".

Але гэта не значыць, што. Што гэта на самай справе азначае, што залежыць ад таго, наколькі вялікі рэгістр. Я буду лічыць, што гэта 16 біт, а PINXX 8.

Тады што стандартны спосаб на самай справе кажа гэта:

REGISTER_NAME &= ~(1 << 8)

або (калі ў вас ёсць кампілятар, які прымае 0b для двайковых лікаў)

REGISTER_NAME &= ~(0b0000000100000000)

або

REGISTER_NAME &= 0b1111111011111111

That is, the command isn't operating on just one pin - it's operating on all of them. (Just the operation on everything but the pin you want to change is "logically AND with 1", which means it is left alone). The expression ~(1 << PINXX) is just a way to construct a number that's all 1s in the places you don't want to touch, and 0 in the spot you do.

Ваша прапанавалі «прасцей» версія будзе эквівалентная:

REGISTER_NAME &= 0b0000000000000000

Які б скінуць ўсе кантакты, кіраваныя гэтага рэгістра.

0
дададзена
права. Дзякуй - адказы былі настолькі карысныя мне цікава, як я мог быць настолькі дурны, каб не ўсвядомілі гэта.
дададзена аўтар mgd, крыніца