아두이노 강좌 #19 shiftOut() 함수 파헤치기
Lucy Archive
Lucy / Facilitate4U
2020. 8. 7. 23:33

Arduino shiftOut() 사용법Arduino shiftOut() 사용법

Arduino shiftOut() 함수 파헤치기

아두이노에서 시리얼 인터페이스를 가진 장치를 제어하기 위해 shiftOut() 함수를 사용 할 수 있습니다. shiftOut() 는 기본적으로 SPI 와 통신 방식이 동일하지만, Software 적인 방법으로 시리얼 인터페이스를 생성합니다. 본 포스트에서는

shiftOut() 함수 사용 방법 및 실제 전송되는 파형

에 대해 작성하였습니다.

시리얼 인터페이스

많은 칩들이 시리얼 인터페이스를 가지고 있어, 아래와 같은 시리얼 인터페이스 장치를 제어하기 위해 Shiftout() 함수를 사용하여 제어 또는 통신 할 수 있습니다. 

DS1302 74HC595타이밍 다이어그램 (좌) DS1302 : RTC , (우) 74HC595 : ShiftResistor


아두이노 시리얼 인터페이스

shiftOut() 함수 정의

Shiftout() 함수는 한 바이트의 데이터를 한번에 한 비트씩 출력합니다. shiftout() 함수에 사용되는 핀은 출력 포트로 설정 되어야 합니다. 

Syntax

  • shiftOut(dataPin, clockPin, bitOrder, value)

Parameters

  • datapin : 데이터 핀 번호, 해당 핀은 출력 포트로 설정 되어 있어야 함
  • clockpin : 클럭 송신 번호, 해당 핀은 출력 포트로 설정 되어 있어야 함
  • bitOrder : BSBFIRST or LSBFIRST
    • MSBFIRST : 높은 비트 순서
    • LSBFIRST : 낮은 비트 순서
  • value : 송신할 데이터 (datatype : byte)

Returns : 반환 값 없음

Example

  • shiftOut(7, 6, MSBFIRST, 255) : 6번 포트를 CLK, 7번 포트를 DATA 핀 설정하여 255값을 시리얼 출력

MSB 와 LSB

아래 그림과 같이 바이트를 비트로 표현 하는 경우 왼쪽의 비트를 MSB(Most Significant Bit, 최상위 비트), 오른쪽의 비트를 LSB(Least Significant Bit, 최하위 비트) 라고 부릅니다. 

MSB 와 LSBMSB 와 LSB

shiftout() 함수의 파라미터 MSBFIRSTLSBFIRST 는 전송할 데이터의 순서를 MSB, LSB 어느 것을 먼저 보낼지 결정하는 파라미터 입니다.


shiftout() 사용 예시와 파형

shiftout() 함수 동작을 알아보기 위해 아래와 같이 회로를 구성하고 코드에 따라 파형이 어떻게 변하는지 확인해보겠습니다.

회로도 및 연결

shiftOut() 회로를 테스트하기 위해 그림과 같이 D3, D4 핀에 2.2kΩ 풀다운 저항을 연결하고, 오실로 스코프로 측정하여 shiftOut() 출력 파형이 어떻게 되는지 확인합니다. shiftOut() 함수에 지정되는 클럭핀과 데이터핀은 지정되어 있지 않고, 아두이노에서 사용되는 모든 핀에 적용이 가능합니다.


코드1 : MSBFIRST 방식

아래의 그림은 MSBFIRST 방식으로 십진수 85 의 값을 shiftOut() 함수로 데이터 출력 후 오실로스코프로 측정한 파형입니다. 십진수 85 의 값이 2진수 0x01010101 의 순서로 데이터에 전송 되는 것을 확인 할 수 있습니다. 데이터가 송신되지 않는 동안 전원이 HIGH 값을 유지 하는 이유는 전송된 마지막 데이터가 1이기 때문입니다. default HIGH 로 유지 하는 것은 아닙니다.

shiftOut(D4, D3, MSBFIRST, 85) 파형shiftOut(D4, D3, MSBFIRST, 85) 코드의 파형


코드2 : LSBFIRST 방식

아래의 그림은 LSBFIRST 방식으로 십준수 85의 값을 shiftOut() 함수로 데이터 출력 후 오실로스코프로 측정한 파형입니다. DEC 85 의 값은 BIN 0b01010101 이지만, LSBFIRST 방식으로 전송하여 역순인 1,0,1,0,1,0,1,0 데이터 순으로 전송 되는 것을 확인 할 수 있습니다. 

shiftOut(D4, D3, LSBFIRST, 85) 파형shiftOut(D4, D3, LSBFIRST, 85) 코드의 파형


shiftOut() 속도

본 포스트에서 사용한 보드는 Arduino Uno 보드로, Arduino Uno 보드에서 shiftOut() 함수를 사용할 경우 클럭 스피드가 약 65.8kHz 로 약 15us 의 주기를 가집니다. 더 빠른 데이터 전송을 위해서는 SPI 하드웨어 핀을 사용하거나, 직접 AVR 코딩을 해야 합니다. SPI는 이후에 따로 포스트를 준비할 예정이고, AVR 코딩 방식은 아두이노 카테고리에서는 다루지 않을 예정입니다.

shiftOut() 의 클럭 스피드shiftOut() 의 클럭 스피드


부록 : shiftOut() 내부 함수

shiftOut() 함수는 wiring_shift.c 에 정의되어 있으며 아래와 같은 내부 코드로 이루어져 있습니다. 코드 내부를 보면 단순히 digitalWrite() 함수를 사용하여 시리얼 출력 하는 데이터를 만든 것으로 확인 됩니다. 이 코드를 응용하여 16bit 또는 32bit shiftOut() 함수를 만들 수 있습니다.

shiftOut() 함수 정의shiftOut() 함수 정의

참고로 if문의 !!(val & (1 << i)) 코드는 아래 그림과 표와 같이 i 가 0 에서 7까지 증가하는 순서에 따라 LSB 부터 1비트씩 마스킹 하는 연산입니다. 

비트연산비트연산 val & (1 << i) 연산 표

shiftOut() 함수의 내부 코드를 보기 위해 직접 파일을 열어 볼 수 도 있지만, Visual Studio Code 에디터를 사용하여 쉽게 내부 코드 구성을 확인 할 수 있습니다. Visual Studio Code 를 사용하여 아두이노 프로그래밍 하는 방법이 필요하신분은 하단의 링크를 참조해주세요.


마무리

본 포스트에서 아두이노의

shiftOut() 함수 사용법, 예제, 송신 파형 및 내부 코드

에 대해 알아보았습니다. 이후 포스트는 shiftOut() 함수를 이용하여 시프트레지스터를 사용하는 방법에 대한 소개를 진행할 예정입니다.

끝까지 읽어주셔서 감사합니다.

관련포스트

👉 아두이노 프로그래밍 언어 관련글 목록 보기

👉 아두이노 74HC595 관련글 목록 보기

👉 아두이노 관련글 전체 목록 보기