wiring_shift.c
함수 코드를 조사하고있었습니다.
그리고 digitalWrite 함수에서 무슨 일이 일어나는지 잘 이해하지 못했습니다. !!(val & (1 << i))
가 val
에서 비트 값을 가져 오는 것을 확인했습니다. 하지만 정확히 어떻게 작동합니까?
전체 기능은 다음과 같습니다.
void shiftOut(uint8_t dataPin, uint8_t clockPin, uint8_t bitOrder, uint8_t val) { uint8_t i; for (i = 0; i < 8; i++) { if (bitOrder == LSBFIRST) digitalWrite(dataPin, !!(val & (1 << i))); else digitalWrite(dataPin, !!(val & (1 << (7 - i)))); digitalWrite(clockPin, HIGH); digitalWrite(clockPin, LOW); } }
댓글
답변
bitOrder == LSBFIRST
로 가정하겠습니다.
p>
-
i
는 비트 번호, 즉 기록 할 다음 비트의 “인덱스”입니다. -
1
는 바이너리의00000001
입니다. -
<<
는 왼쪽 시프트 연산자입니다. 두 번째 인수가 나타내는만큼 왼쪽으로 이동 한 첫 번째 인수를 반환합니다. -
1<<i
는 바이너리입니다.00000001
i
위치만큼 왼쪽으로 이동했습니다. 예를 들어0...010...0
와 같이 단일 1이 오른쪽에서 세어 i 번째 위치에 있습니다 (가장 오른쪽 위치 0) -
&
는 “비트 및 연산자”입니다. 여기서any_bit & 0
는 0이�는
any_bit
-
val & (1 << i)
는0...0(i-th bit of val)0...0
바이너리에서, val의 i 번째 비트는 결과의 i 번째 위치에 있습니다. -
!!
는 이중 부정입니다. 0을 0으로 변환하고 0이 아닌 값을 1로 변환 -
!!(val & (1 << i))
는 0 또는 1이며 정확히 i 번째 비트 비트입니다.
댓글
- 이해 한 내용을 요약하겠습니다.
val = '10010111'
를 가정 해 보겠습니다.for i=2
!!(val & (1 << i))
=!!('10010111' & '00000100')
=!!('00000100')
=1
i가 = 3 인 경우!!(val & (1 << i))
=!!('10010111' & '00001000')
=!!('00000000')
=0
- 정답입니다!
- 이는 shiftOut에 16 비트 이상의 데이터를 제공하면 최하위 8 비트를 전송하고 나머지는 무시합니다.
-
shiftOut()
는uint8_t
데이터를 사용합니다. 16 비트 인수로 호출하면 컴파일러는shiftOut()
에 대한 실제 호출 전 에 8 개의 최상위 비트를 암시 적으로 제거합니다. - @SteveMcDonald : 예, 출력은 이중 부정없이 동일합니다.
digitalWrite()
는 모든 0 값 (단지 1이 아님)은HIGH
를 의미합니다. 분명히shiftOut()
의 작성자는이 동작에 의존하고 싶지 않았으며 대신 항상 0 (예 :digitalWrite()
)을 호출하고 싶었습니다. div id = “a09f0b06d5″>
) 또는 1 (HIGH
).
!!(val & (1 << i))
는이 코드에서 가장 복잡한 부분입니다.이 부분을 이해 한다면하지 않는 알 겠어요?shift out
값 (바이너리 형식) 및 그와 함께 클럭 펄스를 제공합니다.