순서
- MAX31865 ADC와 Nucleo32L476RG를 SPI 통신 해보기로 한다.
- 센서, 칩 데이터시트 모으기 ( Max31865, PT100, Nucleo-L476RG, PLS10 )
* SPI 통신을 위한 오픈소스 펌웨어 구하기 (손으로 직접 짜는 게 낫다. 결국 라이브러리 처럼 짜야하지만..)
* 분석하고 해당 보드에 적용시키기
- 데이터 시트 조사
- SPI 통신에 필요한 통신에 필요한 슬레이브 칩 레지스터 주소 확인.
- SPI 통신에 필요한 타이밍 다이어그램 조사(CPOL, CPHA).
- SPI 통신에 필요한 최대 클럭속도 확인.
- 코딩
자료조사
MAX31865
PT100
세팅
STM32CubeMX
- Mode : Full-Duplex Master (기본)
- Hardware NSS Signal : Hardware NSS Input Signal
- 분주비(Prescaler) : 조정하고자 하는 칩의 최대속도의 이하로 조절해주야 한다.
- SCLK Max Frequency 5Mhz 이하가 되도록 설정한다. (32로 설정)
- 데이터크기 : 8bits ( A7~ A0 )
- CPOL_Clcok Polarity
- 제어하려는 칩은 SCLK가 High일때 Off 상태이다-> CPOL = 1(High)
- 애초에 Note : SPOL = 1 이 타이밍다이어그램 하단에 적혀있음.
- High에서 Low로 갔다가 값이 바뀌는 친구라서 그냥 High(1)
- CPHA = 1 (Edge 2)
- 설명대로 못찾아서 데이터시트를 쭉 찾아봤다
- 다시한번 타이밍 다이어그램을 보니, 비트를 읽을때 엣지가 밑으로한번 위로 한번할때 읽는다.
- High에서 Low로 갈때 엣지1, 그리고 다시올라갈때 엣지2, 이때 MSB가 생성되어서 2엣지 = CPHA : 1
- SS가 될 GPIO는 HIGH가 평소에 나와야 하기 때문에 OutLevel = High 로 한다.
레지스터 관련
- 데이터시트에 다있다.
- 구성 주소(SS)0x00
- RTD의 첫 데이터 주소는 0x01, 마지막주소는 0x02
- AutoConversion Mode : 시그널을 계속 변환을 해주는 모드인가보다.
- 사람들이 안쓴다.. 이유는 모르겠지만 안쓰는이유가 있겠지?
- OneShot : 오토 컨버젼을 끈후 사용가능. 시그널을 한번씩만 변환하는 모드
- 카패시터가 동작할 수 있게 오토 컨버전을 키고 52ms(기본_60Hz필터모드 기준) 정도 기다려줘야한다.
코딩
4ilo-코드
- stm32f4xx 버전으로 짜여진 코드이다.
현재 사용하는 stm32l4xx버전으로 바꾸자
- SPI를 할줄 알면 라이브러리 없이 쉽게 짤 수 있다.
- 순서
- 포트,핀 설정
- Configure Register 설정 (0x00 뚫기)
- RTD MSB, LSB 받아서 분석 (0x01, 0x02 뚫기)
결과
- 시간내에 개발을 못해서 다음에 하기로 하였다.
- 4일간 찾아낸 것들을 정리해본다.
- SPI 통신 요약
- Write : Addr, 명령 이 2바이트를 보낸다.
- Read : Addr을 보내고, 해당 값을 받아서 1바이트씩 주고받는다.
- MOSI와 MISO는 각 MOSI, MISO에 꽂아써야하고, 크로스해서 꽂는게 아니다.
- RCC 를 써서 클럭을 강제로 높일수는 있지만,
그냥 클럭의 Max치를 쓰고, 크리스탈의 기본값(데이터시트)를 참고해서 사용해도 통신은 된다.
- HAL_SPI와 HAL_GPIO는 따로 논다.
- SPI에 관련된 GPIO를 GPIO함수로 건들여도 움직이지않는다.
- 해당 SPI함수들( __SPI_ENABLE, HAL_SPI_TransmitReceive()등)이 있으니 사용하면됨
- STM에서는 GPIO Output(High)를 이용해서 해당 CS를 다룰 수 있었으며, 이 것만 타이밍 맞게 GPIO 함수를 사용해 움직여 주면 된다.
추 후
- RSL10 보드로 SPI 구현해야함.
- 시간 남으면 STM32L4보드 구현을 마칠 예정
참고
기타
- IRQ : 인터럽트 요청
- DMA : 직접 메모리 엑세스
- 핀 읽기 : (포트)(핀)