상세 컨텐츠

본문 제목

라즈베리파이와 STM32간 I2C 통신하기

기타

by 전산거북이 2026. 7. 7. 17:04

본문

개요

STM32 보드와 라즈베리파이 간 I2C 통신 방법을 기술한 문서입니다.

라즈베리파이 한 대당 여러 개의 STM32 보드를 연결해야 하므로, I2C 연결을 지향합니다.

핀 연결하기

기본적으로 5V와 GND를 연결한 상태에서, 오른쪽 핀에 SCL, SDA 핀을 연결합니다. 라즈베리파이의 SCL과 STM32의 SCL 핀이 연결되며, SDA역시 동일합니다.

프로젝트 생성하기

공통 설정

STM32 CubeMX에서 프로젝트를 생성합니다.

위 PB8, 9를 각각 SCL, SDA로 설정해줍니다.

이후, Connectivity → I2C1 → Mode를 Disable에서 I2C로 설정해줍니다.

또한, Parameter Settings에서 I2C Speed Mode는 Standard로, Clock Speed는 100000Hz로 잡아준 뒤, Primary slave address는 0x0a를 설정해줍니다. 이 값은 바꾸어도 괜찮지만, 반드시 설정은 해 주어야 합니다.

GPIO Settings의 GPIO Pull-up/Pull-down은 Pull-up으로, Maximum output speed는 Very High로 설정해줍니다.

NVIC/DMA 중 원하는 것을 골라 설정을 해 주어야 합니다.

NVIC 설정법

NVIC Settings에서 다음 event interrupt와 error interrput를 모두 enable 해줍니다.

DMA 설정법

DMA Settings에서 Add를 해 줍니다. 이후, slave를 설정할 것이므로 I2C_RX를 선택하면 됩니다.

만약, Master로 사용할 것이라면 I2C_TX를 선택해줍니다.

코드 작성

Code Generate를 한 뒤 다음을 추가해주어야 합니다.

우선, 데이터를 받아야 하는 부분입니다.

/* USER CODE BEGIN PV */
uint8_t RX_Buffer [10];        // Data to receive
volatile uint8_t rx_flag = 0;
/* USER CODE END PV */

다음은 receive 대기를 위한 코드입니다.

  /* USER CODE BEGIN 2 */
  HAL_I2C_Slave_Receive_IT(&hi2c1, (uint8_t*)RX_Buffer, 1);
  HAL_Delay(100);
  /* USER CODE END 2 */
  while (1)
  {
    /* USER CODE END WHILE */


    /* USER CODE BEGIN 3 */
      if(rx_flag == 1)
      {
          if(RX_Buffer[0] == 0x01)
          {
              HAL_GPIO_WritePin(LD2_GPIO_Port, LD2_Pin, GPIO_PIN_SET);
          }
          else if(RX_Buffer[0] == 0x00)
          {
              HAL_GPIO_WritePin(LD2_GPIO_Port, LD2_Pin, GPIO_PIN_RESET);
          }
          else
          {
              HAL_GPIO_TogglePin(LD2_GPIO_Port, LD2_Pin);
          }
          HAL_I2C_Slave_Receive_IT(&hi2c1, (uint8_t*)RX_Buffer, 1);
      }
  }
  /* USER CODE END 3 */

while문에서는 0x01을 받으면 LED를 키고, 0x00을 받으면 LED를 끄는것으로 하였습니다.

그 외의 값을 받으면 토글하도록 만들어두었습니다.

마지막으로 콜백함수는 다음과 같이 구현하였습니다. Drivers/Src/stm32f4xx_hal_i2c.c 에 weak로 작성되어있으니, 찾아서 가지고 오면 됩니다.

void HAL_I2C_SlaveRxCpltCallback(I2C_HandleTypeDef *hi2c)
{
    if(hi2c->Instance == I2C1)
    {
        rx_flag = 1;
    }
}

실행 결과

서버(라즈베리파이)에서 값을 보내주게 되면, stm32에서 그 값을 받아 적절히 LED를 제어합니다.

값을 보내기 위해서 다음과 같이 테스트하십시오: i2cset -y 1 0x0a 0x01 이는 0x0a 주소로 0x01 값을 보낸다는 의미입니다.

참고 문서

https://wiki.st.com/stm32mcu/wiki/Getting_started_with_I2C

'기타' 카테고리의 다른 글

[RDK 보드] config 화면 띄우기  (0) 2026.06.23
[디바이스마트 이벤트] RDK X3 후기  (0) 2026.06.12

관련글 더보기

댓글 영역