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는 바이너리입니다.00000001i위치만큼 왼쪽으로 이동했습니다. 예를 들어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')=1i가 = 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값 (바이너리 형식) 및 그와 함께 클럭 펄스를 제공합니다.