STM32 MCU는 다양한 인터페이스를 통해 외부 장치와 통신할 수 있습니다. 그중 SPI(Serial Peripheral Interface)는 빠르고 간편한 통신을 제공하여 센서, 메모리 장치, 디스플레이 등 다양한 디바이스와의 데이터 교환에 널리 사용됩니다. 이번 글에서는 STM32CubeIDE를 이용하여 SPI 설정 방법을 상세히 설명하고, SPI를 통해 외부 디바이스와 통신하는 예제를 다뤄보겠습니다.
SPI의 개념
SPI는 직렬 통신 프로토콜로, 마스터와 슬레이브 간의 동기화된 데이터 전송을 위해 사용됩니다. SPI는 클럭 신호를 사용하여 데이터를 전송하는데, 주요한 핀은 다음과 같습니다:
- MOSI (Master Out Slave In): 마스터에서 슬레이브로 데이터를 전송하는 선.
- MISO (Master In Slave Out): 슬레이브에서 마스터로 데이터를 전송하는 선.
- SCLK (Serial Clock): 마스터가 슬레이브에 제공하는 클럭 신호.
- SS/CS (Slave Select/Chip Select): 특정 슬레이브를 선택하기 위한 신호.
SPI 설정하기
STM32CubeIDE를 통해 SPI를 설정하는 과정을 단계별로 설명하겠습니다. SPI 설정은 기본적으로 GPIO 핀을 SPI 기능으로 설정하고, SPI 주변 장치를 구성하는 것으로 나뉩니다.
1. 프로젝트 생성
STM32CubeIDE를 실행하고, 새로운 프로젝트를 생성합니다. 사용하려는 보드나 MCU 칩을 선택하고, 프로젝트 이름을 지정한 뒤 생성합니다.
2. Pinout 설정
- Pinout & Configuration 탭에서 SPI를 사용하고자 하는 포트를 선택합니다. 예를 들어,
SPI1
을 사용하려면 Connectivity 아래의 SPI1을 활성화합니다. - 활성화하면 SPI1과 관련된 핀들이 자동으로 GPIO로 설정됩니다. 예를 들어,
PA5
,PA6
,PA7
과 같이 해당 SPI에 할당된 클럭(SCK), 데이터 입력(MISO), 데이터 출력(MOSI) 핀들이 설정됩니다.PA5 (SCK)
: Serial Clock 핀PA6 (MISO)
: Master In Slave Out 핀PA7 (MOSI)
: Master Out Slave In 핀
- Chip Select (CS) 핀은 수동으로 지정해야 합니다. 예를 들어
PB6
을 CS 핀으로 사용하도록 설정할 수 있습니다. 이 핀은 GPIO Output으로 설정하여 슬레이브 선택에 사용됩니다.
3. SPI 설정
Configuration 탭에서 SPI1을 선택하여 세부 설정을 합니다.
- Mode: SPI를 Master로 설정합니다.
- Baud Rate Prescaler: 원하는 클럭 속도에 맞춰 분주기를 설정합니다. 예를 들어,
8
로 설정하면 기본 클럭의 1/8 속도로 동작합니다. - Data Size: 데이터 전송 크기를 설정합니다. 일반적으로
8-bit
으로 설정합니다. - Clock Polarity (CPOL) 및 Clock Phase (CPHA): 연결할 디바이스의 요구사항에 맞춰 클럭 극성과 위상을 설정합니다.
- NSS (Slave Select Management): 하드웨어 NSS 관리 또는 소프트웨어 NSS 관리를 선택합니다. 소프트웨어 관리를 선택하면 CS 핀을 GPIO로 직접 제어할 수 있습니다.
4. GPIO 설정
GPIO 설정은 SPI가 사용하는 핀 외에도 추가로 필요한 핀들을 설정합니다. 특히 CS 핀은 수동으로 GPIO Output으로 설정하여 슬레이브 디바이스를 선택하는 데 사용합니다.
- PB6: GPIO Output, 초기 상태는
High
로 설정합니다.
5. 코드 생성
모든 설정을 완료한 후 Project > Generate Code를 클릭하여 초기화 코드를 생성합니다. STM32CubeIDE는 설정된 SPI 및 GPIO에 대한 초기화 코드를 자동으로 생성합니다.
코드 예제
이제 SPI를 통해 데이터를 송수신하는 예제 코드를 작성해보겠습니다. 예제에서는 SPI를 통해 간단히 데이터를 송신하고, 응답을 수신하는 과정을 다룹니다.
1. 주요 헤더 파일 포함
#include "main.h"
#include "spi.h"
#include "gpio.h"
2. Chip Select 핀 제어 함수
SPI 통신 중에는 CS 핀을 사용하여 슬레이브 장치를 선택해야 합니다. 아래는 CS 핀을 제어하기 위한 함수입니다.
void CS_Select(void)
{
HAL_GPIO_WritePin(GPIOB, GPIO_PIN_6, GPIO_PIN_RESET); // CS Low
}
void CS_Deselect(void)
{
HAL_GPIO_WritePin(GPIOB, GPIO_PIN_6, GPIO_PIN_SET); // CS High
}
3. SPI 초기화 코드
STM32CubeIDE에서 자동 생성된 SPI 초기화 코드는 spi.c
파일에 포함되어 있습니다. 해당 코드는 아래와 같이 기본 설정을 포함합니다.
void MX_SPI1_Init(void)
{
hspi1.Instance = SPI1;
hspi1.Init.Mode = SPI_MODE_MASTER;
hspi1.Init.Direction = SPI_DIRECTION_2LINES;
hspi1.Init.DataSize = SPI_DATASIZE_8BIT;
hspi1.Init.CLKPolarity = SPI_POLARITY_LOW;
hspi1.Init.CLKPhase = SPI_PHASE_1EDGE;
hspi1.Init.NSS = SPI_NSS_SOFT;
hspi1.Init.BaudRatePrescaler = SPI_BAUDRATEPRESCALER_8;
hspi1.Init.FirstBit = SPI_FIRSTBIT_MSB;
hspi1.Init.TIMode = SPI_TIMODE_DISABLE;
hspi1.Init.CRCCalculation = SPI_CRCCALCULATION_DISABLE;
hspi1.Init.CRCPolynomial = 10;
if (HAL_SPI_Init(&hspi1) != HAL_OK)
{
Error_Handler();
}
}
4. SPI 통신 예제
아래는 SPI를 사용하여 데이터를 송신하고, 응답을 수신하는 예제 코드입니다. 이 예제에서는 간단히 1바이트 데이터를 슬레이브로 전송하고, 슬레이브로부터 1바이트 응답을 받습니다.
uint8_t SPI_TransmitReceive(uint8_t data)
{
uint8_t received_data = 0;
CS_Select();
HAL_SPI_TransmitReceive(&hspi1, &data, &received_data, 1, HAL_MAX_DELAY);
CS_Deselect();
return received_data;
}
int main(void)
{
HAL_Init();
SystemClock_Config();
MX_GPIO_Init();
MX_SPI1_Init();
uint8_t send_data = 0x9A; // 송신할 데이터
uint8_t received_data;
while (1)
{
received_data = SPI_TransmitReceive(send_data);
HAL_Delay(1000); // 1초 대기
}
}
코드 설명
- CS_Select()와 CS_Deselect() 함수를 사용하여 슬레이브 디바이스를 선택합니다.
- HAL_SPI_TransmitReceive() 함수를 사용하여 데이터를 송수신합니다. 이 함수는 송신할 데이터와 수신할 버퍼를 인수로 받으며, 설정된 SPI를 통해 통신을 수행합니다.
- main() 함수에서 초기화 작업을 수행한 후,
SPI_TransmitReceive()
함수를 이용해 데이터를 송신하고 응답을 받습니다.
결론
STM32CubeIDE를 사용하여 STM32에서 SPI를 설정하고 사용하는 방법을 알아보았습니다. SPI는 직렬 통신 방식으로 간편하고 빠르게 데이터를 송수신할 수 있는 장점이 있습니다. 이번 예제에서는 간단한 송수신 과정을 다뤘지만, 실제 응용에서는 센서 데이터 읽기, 메모리 장치와의 통신 등 다양한 디바이스와의 연결에 사용할 수 있습니다.
STM32CubeIDE는 GUI를 통해 쉽게 SPI 설정을 할 수 있어 복잡한 레지스터 설정 없이도 SPI 통신을 구현할 수 있습니다. 이를 통해 보다 빠르게 개발을 진행할 수 있으며, 다양한 디바이스와의 통합 작업에도 유리합니다.
'STM32' 카테고리의 다른 글
STM32 아날로그 신호 출력 DAC 설정하기 (0) | 2024.11.27 |
---|---|
STM32 ADC 설정 및 사용하기 (0) | 2024.11.26 |
STM32 I2C 설정 및 센서 통신 예제 (0) | 2024.11.24 |
STM32 UART 설정 및 사용 가이드 (0) | 2024.11.23 |
STM32 Timer 활용 - PWM 생성 및 타이머 인터럽트 설정 (0) | 2024.11.22 |