In this topic , I use HAL library and stm32cube to create i2c communication between master and slave microcontroller. In my test stm32f7 nucleo used as the master and stm32f7 discovery used as the slave.
1. Master configuration.
1.1 GPIO and system clock setting
RCC clock setting RCC-> High speed clock (hse) -> crystal
Up to 216MHz
I2C setting I2C1 -> PB8 : SCL PB9 :SDA
USART setting USART3 -> asynchronous PD9 : TX PD8: RX
1.2 I2C and Serial setting
I2C mode ->standard mode
Frequency-> 100kHz
USART baud rate -> 115200
USART word length 8 Bits
2. Slave configuration
2.1 GPIO and system clock setting
RCC clock setting RCC-> High speed clock (hse) -> crystal
Up to 216MHz
I2C setting I2C1 -> PB8 : SCL PB9 :SDA
FreeRTOS -> Checked
2.2 I2C and FreeRTOS setting
I2C mode ->standard mode
Frequency-> 100kHz
Primary slave address 0x6B.
RTOS_setting -> Add task and queues
3.Generate program and edit Src/main.c file
Master
#include "stm32f7xx_hal.h"
#define ADD 0x6b
I2C_HandleTypeDef hi2c1;
DMA_HandleTypeDef hdma_i2c1_rx;
DMA_HandleTypeDef hdma_i2c1_tx;
UART_HandleTypeDef huart3;
DMA_HandleTypeDef hdma_usart3_tx;
DMA_HandleTypeDef hdma_usart3_rx;
/* USER CODE BEGIN PV */
/* Private variables ---------------------------------------------------------*/
/* USER CODE END PV */
/* Private function prototypes -----------------------------------------------*/
void SystemClock_Config(void);
void Error_Handler(void);
static void MX_GPIO_Init(void);
static void MX_DMA_Init(void);
static void MX_I2C1_Init(void);
static void MX_USART3_UART_Init(void);
/* USER CODE BEGIN PFP */
/* Private function prototypes -----------------------------------------------*/
/* USER CODE END PFP */
/* USER CODE BEGIN 0 */
/* USER CODE END 0 */
int main(void)
{
/* USER CODE BEGIN 1 */
/* USER CODE END 1 */
/* MCU Configuration----------------------------------------------------------*/
/* Reset of all peripherals, Initializes the Flash interface and the Systick. */
HAL_Init();
/* Configure the system clock */
SystemClock_Config();
/* Initialize all configured peripherals */
MX_GPIO_Init();
MX_DMA_Init();
MX_I2C1_Init();
MX_USART3_UART_Init();
int16_t i=100;
char cmd[2];
char cmd_1[2];
char buf[40];
while (1)
{
cmd[0]=i>>8;
cmd[1]=i&0xff;
HAL_I2C_Master_Transmit(&hi2c1,ADD<<1,cmd,2,1000);
HAL_I2C_Master_Receive(&hi2c1,ADD<<1,cmd_1,2,1000);
int16_t a= cmd_1[0]<<8|cmd_1[1];
memset(buf,'\0',sizeof(buf));
sprintf(buf,"I send%:d..I receive:%d\n",i,a);
HAL_UART_Transmit( &huart3,buf,sizeof(buf),0x100);
i+=1;
HAL_Delay(1);
}
/* USER CODE END 3 */
}
........................................................
Slave
Edit Src/main.c
#include "stm32f7xx_hal.h"
#include "stm32f7xx_hal_uart.h"
#include "stm32f7xx_hal_sdram.h"
#include "stm32f7xx_hal_ltdc.h"
#include "stm32746g_discovery.h"
#include "stm32746g_discovery_lcd.h"
#include "stm32746g_discovery_sdram.h"
#include "stm32f7xx_ll_fmc.h"
#include "string.h"
#include "cmsis_os.h"
/* USER CODE BEGIN Includes */
/* USER CODE END Includes */
/* Private variables ---------------------------------------------------------*/
I2C_HandleTypeDef hi2c1;
DMA_HandleTypeDef hdma_i2c1_rx;
DMA_HandleTypeDef hdma_i2c1_tx;
osThreadId defaultTaskHandle;
osThreadId myTask02Handle;
osMessageQId myQueue01Handle;
void SystemClock_Config(void);
void Error_Handler(void);
static void MX_GPIO_Init(void);
static void MX_DMA_Init(void);
static void MX_I2C1_Init(void);
void StartDefaultTask(void const * argument);
void StartTask02(void const * argument);
int main(void)
{
/* USER CODE BEGIN 1 */
/* USER CODE END 1 */
/* MCU Configuration----------------------------------------------------------*/
/* Reset of all peripherals, Initializes the Flash interface and the Systick. */
HAL_Init();
/* Configure the system clock */
SystemClock_Config();
/* Initialize all configured peripherals */
MX_GPIO_Init();
MX_DMA_Init();
MX_I2C1_Init();
BSP_LCD_Init();
BSP_LCD_LayerDefaultInit(0, LCD_FB_START_ADDRESS);
BSP_LCD_LayerDefaultInit(1, LCD_FB_START_ADDRESS+(BSP_LCD_GetXSize()*BSP_LCD_GetYSize()*4));
SPI2->DR=1;
BSP_LCD_DisplayOn();
BSP_LCD_SelectLayer(0);
BSP_LCD_Clear(LCD_COLOR_BLACK);
BSP_LCD_SelectLayer(1);
BSP_LCD_Clear(LCD_COLOR_BLACK);
BSP_LCD_SetFont(&LCD_DEFAULT_FONT);
BSP_LCD_SetBackColor(LCD_COLOR_WHITE);
BSP_LCD_SetTextColor(LCD_COLOR_DARKBLUE);
/* Create the thread(s) */
/* definition and creation of defaultTask */
osThreadDef(defaultTask, StartDefaultTask, osPriorityRealtime, 0, 512);
defaultTaskHandle = osThreadCreate(osThread(defaultTask), NULL);
/* definition and creation of myTask02 */
osThreadDef(myTask02, StartTask02, osPriorityIdle, 0, 256);
myTask02Handle = osThreadCreate(osThread(myTask02), NULL);
osMessageQDef(myQueue01,16, uint16_t);
myQueue01Handle = osMessageCreate(osMessageQ(myQueue01), NULL);
osKernelStart();
while (1)
{
}
}
.................................................................................................
void StartDefaultTask(void const * argument)
{
char buffer[2];
int16_t data;
for(;;)
{
HAL_I2C_Slave_Receive(&hi2c1, buffer,2,0x10000);
HAL_I2C_Slave_Transmit(&hi2c1, buffer,2,0x1000);
data=(buffer[0]<<8)|(buffer[1]);
osMessagePut(myQueue01Handle, (int16_t)data, 2);
osDelay(1);
}
/* USER CODE END 5 */
}
/* StartTask02 function */
void StartTask02(void const * argument)
{
osEvent evt;
char buf[2]="";
int16_t data_receive;
for(;;)
{
evt = osMessageGet(myQueue01Handle,0x1000);
if (evt.status == osEventMessage) {
data_receive=evt.value.p ;
sprintf(buf,"Data receive =%d",data_receive);
BSP_LCD_DisplayStringAt(0, LINE(6), (uint8_t *)buf, CENTER_MODE);
} else {
BSP_LCD_DisplayStringAt(0, LINE(6), (uint8_t *)"Failed", CENTER_MODE);
}
osDelay(10);
}
/* USER CODE END StartTask02 */
}
![]() |
Stm32cube+ Freertos I2C communication between master and slave |
1.1 GPIO and system clock setting
RCC clock setting RCC-> High speed clock (hse) -> crystal
Up to 216MHz
I2C setting I2C1 -> PB8 : SCL PB9 :SDA
USART setting USART3 -> asynchronous PD9 : TX PD8: RX
1.2 I2C and Serial setting
I2C mode ->standard mode
Frequency-> 100kHz
USART baud rate -> 115200
USART word length 8 Bits
2. Slave configuration
2.1 GPIO and system clock setting
RCC clock setting RCC-> High speed clock (hse) -> crystal
Up to 216MHz
I2C setting I2C1 -> PB8 : SCL PB9 :SDA
FreeRTOS -> Checked
2.2 I2C and FreeRTOS setting
I2C mode ->standard mode
Frequency-> 100kHz
Primary slave address 0x6B.
RTOS_setting -> Add task and queues
3.Generate program and edit Src/main.c file
Master
#include "stm32f7xx_hal.h"
#define ADD 0x6b
I2C_HandleTypeDef hi2c1;
DMA_HandleTypeDef hdma_i2c1_rx;
DMA_HandleTypeDef hdma_i2c1_tx;
UART_HandleTypeDef huart3;
DMA_HandleTypeDef hdma_usart3_tx;
DMA_HandleTypeDef hdma_usart3_rx;
/* USER CODE BEGIN PV */
/* Private variables ---------------------------------------------------------*/
/* USER CODE END PV */
/* Private function prototypes -----------------------------------------------*/
void SystemClock_Config(void);
void Error_Handler(void);
static void MX_GPIO_Init(void);
static void MX_DMA_Init(void);
static void MX_I2C1_Init(void);
static void MX_USART3_UART_Init(void);
/* USER CODE BEGIN PFP */
/* Private function prototypes -----------------------------------------------*/
/* USER CODE END PFP */
/* USER CODE BEGIN 0 */
/* USER CODE END 0 */
int main(void)
{
/* USER CODE BEGIN 1 */
/* USER CODE END 1 */
/* MCU Configuration----------------------------------------------------------*/
/* Reset of all peripherals, Initializes the Flash interface and the Systick. */
HAL_Init();
/* Configure the system clock */
SystemClock_Config();
/* Initialize all configured peripherals */
MX_GPIO_Init();
MX_DMA_Init();
MX_I2C1_Init();
MX_USART3_UART_Init();
int16_t i=100;
char cmd[2];
char cmd_1[2];
char buf[40];
while (1)
{
cmd[0]=i>>8;
cmd[1]=i&0xff;
HAL_I2C_Master_Transmit(&hi2c1,ADD<<1,cmd,2,1000);
HAL_I2C_Master_Receive(&hi2c1,ADD<<1,cmd_1,2,1000);
int16_t a= cmd_1[0]<<8|cmd_1[1];
memset(buf,'\0',sizeof(buf));
sprintf(buf,"I send%:d..I receive:%d\n",i,a);
HAL_UART_Transmit( &huart3,buf,sizeof(buf),0x100);
i+=1;
HAL_Delay(1);
}
/* USER CODE END 3 */
}
........................................................
Slave
Edit Src/main.c
#include "stm32f7xx_hal.h"
#include "stm32f7xx_hal_uart.h"
#include "stm32f7xx_hal_sdram.h"
#include "stm32f7xx_hal_ltdc.h"
#include "stm32746g_discovery.h"
#include "stm32746g_discovery_lcd.h"
#include "stm32746g_discovery_sdram.h"
#include "stm32f7xx_ll_fmc.h"
#include "string.h"
#include "cmsis_os.h"
/* USER CODE BEGIN Includes */
/* USER CODE END Includes */
/* Private variables ---------------------------------------------------------*/
I2C_HandleTypeDef hi2c1;
DMA_HandleTypeDef hdma_i2c1_rx;
DMA_HandleTypeDef hdma_i2c1_tx;
osThreadId defaultTaskHandle;
osThreadId myTask02Handle;
osMessageQId myQueue01Handle;
void SystemClock_Config(void);
void Error_Handler(void);
static void MX_GPIO_Init(void);
static void MX_DMA_Init(void);
static void MX_I2C1_Init(void);
void StartDefaultTask(void const * argument);
void StartTask02(void const * argument);
int main(void)
{
/* USER CODE BEGIN 1 */
/* USER CODE END 1 */
/* MCU Configuration----------------------------------------------------------*/
/* Reset of all peripherals, Initializes the Flash interface and the Systick. */
HAL_Init();
/* Configure the system clock */
SystemClock_Config();
/* Initialize all configured peripherals */
MX_GPIO_Init();
MX_DMA_Init();
MX_I2C1_Init();
BSP_LCD_Init();
BSP_LCD_LayerDefaultInit(0, LCD_FB_START_ADDRESS);
BSP_LCD_LayerDefaultInit(1, LCD_FB_START_ADDRESS+(BSP_LCD_GetXSize()*BSP_LCD_GetYSize()*4));
SPI2->DR=1;
BSP_LCD_DisplayOn();
BSP_LCD_SelectLayer(0);
BSP_LCD_Clear(LCD_COLOR_BLACK);
BSP_LCD_SelectLayer(1);
BSP_LCD_Clear(LCD_COLOR_BLACK);
BSP_LCD_SetFont(&LCD_DEFAULT_FONT);
BSP_LCD_SetBackColor(LCD_COLOR_WHITE);
BSP_LCD_SetTextColor(LCD_COLOR_DARKBLUE);
/* Create the thread(s) */
/* definition and creation of defaultTask */
osThreadDef(defaultTask, StartDefaultTask, osPriorityRealtime, 0, 512);
defaultTaskHandle = osThreadCreate(osThread(defaultTask), NULL);
/* definition and creation of myTask02 */
osThreadDef(myTask02, StartTask02, osPriorityIdle, 0, 256);
myTask02Handle = osThreadCreate(osThread(myTask02), NULL);
osMessageQDef(myQueue01,16, uint16_t);
myQueue01Handle = osMessageCreate(osMessageQ(myQueue01), NULL);
osKernelStart();
while (1)
{
}
}
.................................................................................................
void StartDefaultTask(void const * argument)
{
char buffer[2];
int16_t data;
for(;;)
{
HAL_I2C_Slave_Receive(&hi2c1, buffer,2,0x10000);
HAL_I2C_Slave_Transmit(&hi2c1, buffer,2,0x1000);
data=(buffer[0]<<8)|(buffer[1]);
osMessagePut(myQueue01Handle, (int16_t)data, 2);
osDelay(1);
}
/* USER CODE END 5 */
}
/* StartTask02 function */
void StartTask02(void const * argument)
{
osEvent evt;
char buf[2]="";
int16_t data_receive;
for(;;)
{
evt = osMessageGet(myQueue01Handle,0x1000);
if (evt.status == osEventMessage) {
data_receive=evt.value.p ;
sprintf(buf,"Data receive =%d",data_receive);
BSP_LCD_DisplayStringAt(0, LINE(6), (uint8_t *)buf, CENTER_MODE);
} else {
BSP_LCD_DisplayStringAt(0, LINE(6), (uint8_t *)"Failed", CENTER_MODE);
}
osDelay(10);
}
/* USER CODE END StartTask02 */
}