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 Settings에서 다음 event interrupt와 error interrput를 모두 enable 해줍니다.

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 값을 보낸다는 의미입니다.
| [RDK 보드] config 화면 띄우기 (0) | 2026.06.23 |
|---|---|
| [디바이스마트 이벤트] RDK X3 후기 (0) | 2026.06.12 |
댓글 영역