STM32F103 SPI LL 드라이버 코드 작성하기

STM32F103 SPI LL 드라이버 코드 작성하기

STM32F1 LL SPI 코드 작성 예제입니다.

 

STM32F103 SPI 통신 LL 드라이버 목차

  1. STM32F103 LL SPI CUBEMX로 초기 설정하기
  2. STM32F103 LL SPI 데이터시트 공부하기
  3. STM32F103 LL SPI 코드 작성하기 (현재 포스팅)

 

데이터 시트를 공부했으니, 분노의 코딩을 할 시간이다.

 

코딩하는 데 있어서 위 그림이 아주 매우 중요하다.  밑에 적혀있는 디스크립션도 매우 잘 되어 있다.

자 코딩해보자.

 

코딩 예제는 이전 HAL 드라이버 포스팅에서 작성한 것과 같다.

 

대략적인 인포는 그 포스팅과 같으니 복붙하겠다.

 

 

SPI 통신의 기본 원리는 데이터를 쓴 만큼 데이터를 받는다. 이 말은 즉 데이터를 받고 싶으면 그 만큼 더미데이터를 보내야 한다는 뜻이다. 이번 포스팅은 SPI를 사용하는 ADC 칩과 통신하고자 한다.

처음 SPI를 시작할 때 ADC 칩을 초기화 해야한다. 이전에 어떤 데이터를 받아 그 일부가 남아있거나, 통신에 실패해 문제가 생겼을 수도 있기 때문이다. 따라서 칩에서 서술하는 초기화 방법을 숙지하고, 코드로 작성하기로 한다.

데이터 시트에서는 초기화 방법을 서술하고 있다.

ADC 칩에서는 DIN핀으로 1의 값을 32번 연속으로 주면 초기화가 된다고 서술하고 있다. 이전 포스팅에서 데이터 비트수를 8로 설정하였으므로, 0xFF 값을 4번 연속으로 호출하도록 한다.

따라서 먼저 SPI 통신을 시작한 후에, Chip Select 핀 출력을 Low로 준 다음 리셋을 시작한다. 그리고 안정시간으로 1ms를 준다. 데이터시트에서는 500us이지만, 맘 편이 2ms를 주었다.

코딩 순서 정하기

맨 위에 있는 그림을 참고해서 코딩 순서를 정해보자. 리셋을 하기 위해서는 0xFF 값을 4번 보내야한다.

  1.  칩 셀렉트 핀(CS)을 Low로 만든다.
  2. 리셋 데이터를 보낸다.                                                        데이터 송신(Transmit) 1
  3.  TXE 플래그가 1이 될 때까지 기다린다.
  4.  리셋 데이터를 보낸다.                                                        데이터 송신(Transmit) 2
  5.  RXNE 플래그가 1이 될 때까지 기다린다.
  6.  데이터를 수신한다.                                                             데이터 수신(Receive) 1
  7.  TXE 플래그가 1이 될 때까지 기다린다.
  8. 리셋 데이터를 보낸다.                                                         데이터 송신(Transmit) 3
  9.  RXNE 플래그가 1이 될 때 까지 기다린다.
  10.  데이터를 수신한다.                                                             데이터 수신(Receive) 2
  11.  리셋 데이터를 보낸다.                                                        데이터 송신(Transmit) 4
  12.  RXNE 플래그가 1이 될 때 까지 기다린다.
  13.  데이터를 수신한다.                                                             데이터 수신(Receive) 3
  14.  RXNE 플래그가 1이 될 때 까지 기다린다.
  15.  데이터를 수신한다.                                                             데이터 수신(Receive) 4
  16.  Busy 상태가 아닐때까지 기다린다.
  17.  칩 셀렉트 핀(CS)을 High로 만든다.

후 것 복잡하다. 처음에는 2번 연속으로 보내고 마지막에는 2번 연속 수신하는 것만 눈여겨 보자. 그 사이에는 보내고 받고를 반복하니 말이다.

 

그래서 코드 작성하면 아래와 같다.

 

ADC 리셋 SPI 코드

설명이야 위에 코드 순서 정한 것과 같으니 별도의 부연 설명은 하지 않겠다. 아래에 사용한 함수에 대한 디스크립션을 첨부하고 부연설명하는 것으로 마무리할까 싶다.

LL_GPIO_ResetOutputPin

GPIO핀을 Low로 설정하고 싶을 때 사용하는 함수다. GPIOA와 같이 핀이 어디 라인쪽에 있는지를 먼저 작성하고, 핀 마스크 값을 입력하면 된다.

LL_SPI_TransmitData8

8비트 데이터를 보내고 싶을 때 사용하는 함수이다. SPI 타입을 지정하고 보낼 데이터를 설정하면 된다.

 

LL_SPI_ReceiveData8

8비트 데이터를 수신하고 싶을 때 사용하면 된다. 변수가 SPI 타입 지정하는 것만 있다. 따라서 수신할 데이터를 리턴 받는 다는 것을 유추할 수 있다.

그냥 데이터를 버리고 싶을 경우에는 LL_SPI_ReceiveData8만 호출하면 되지만, 데이터를 수신해야할 겨우에는 data = LL_SPI_ReceiveData8(SPI1); 과 같이 수신할 데이터를 선언해주고 저장해야한다.

 

LL_SPI_IsActiveFlag_TXE

TXE 플래그가 설정되었는지 알고 싶으면 사용하면된다. 읽고 싶은 SPI 타입을 변수로 받는다. while문을 사용해서 설정될 때까지 기다려주면 된다.

 

LL_SPI_IsActiveFlag_RXNE

RXNE 플래그가 설정되었는지 알고 싶으면 사용하면된다. 읽고 싶은 SPI 타입을 변수로 받는다. while문을 사용해서 설정될 때까지 기다려주면 된다.

 

SPI 통신이 지금 바쁜 상태인지 알고 싶을 때 사용한다.  SPI 인스턴스를 넘겨주면된다. 이건 다른 플래그와는 다르게 0일 때 while문을 탈출해야한다.

!를 붙여서 코드를 짜면 바쁠 때 탈출해버리니

그라믄 안돼~

 

LL_GPIO_SetOutputPin

칩과는 이제 볼일 없으니 Set해야한다. 그럴 때 저 함수 호출해서 쓰면 된다.

 

LL_mDelay

딜레이 쓰고 싶을 때 이거 쓰면된다. 마이크로 단위는 없다.

 

끝!

댓글 남기기

This site uses Akismet to reduce spam. Learn how your comment data is processed.

%d 블로거가 이것을 좋아합니다: