shiftOut 함수는 내부적으로 어떻게 작동합니까? (소스 코드에 대한 설명)

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); } } 

댓글

  • !!(val & (1 << i))는이 코드에서 가장 복잡한 부분입니다.이 부분을 이해 한다면하지 않는 알 겠어요?
  • @ edgar-bonet 사실 이것은 질문이었습니다. 어떻게 든 비트 값을 계산하는 것을 볼 수 있지만 ' 어떻게 이 작업을 수행합니다.
  • shiftOut 함수의 동작을 이해하고 있습니까? 내 말은, ' shift out 값 (바이너리 형식) 및 그와 함께 클럭 펄스를 제공합니다.

답변

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).

답글 남기기

이메일 주소를 발행하지 않을 것입니다. 필수 항목은 *(으)로 표시합니다