cancel
Showing results for 
Search instead for 
Did you mean: 

Can we transmit and receive in I2C protocol using two i2c pins as master and slave??

Prvit
Associate II

Hey everyone!.

I'm trying to use I2C protocol to transmit data from master to slave using i2c1 and i2c2 pins.

But my rx buffer is not getting updated.

I've gone through a couple of tutorials and I found out that in most of them they used two boards , so it got me thinking can we do it in a single board??? I'm new to stm32 can anyone help me??.

10 REPLIES 10
AScha.3
Chief III

Hi,

sure, you can  transmit data from master to slave using i2c1 and i2c2 pins.

Just : you have pullups on sda and scl ? For low speed testing, internal pullups are ok, just enable pullups on all 4 pins.

+

You have to use INT functions, non blocking . First start receive ( HAL_I2C_Slave_Receive_IT(..) ) , then start transmit :   HAL_I2C_Master_Transmit..

If you feel a post has answered your question, please click "Accept as Solution".

You mean on a single STM32 chip, you want to use the I2C1 peripheral as Master, and the I2C2 peripheral on the same chip as Slave - and connect the two?

Like this:

    STM32
+--------------+
|              |
|     I2C1 SDA +----------+
|     I2C1 SCL +-------+  |
|              |       |  |
|              |       |  |
|     I2C2 SCL +-------+  |
|     I2C2 SDA +----------+
|              |
+--------------+

 

Sure, you could do that - but why would you want to??

As @AScha.3 said, pullups would be required - not shown in my diagram.

Hey, thank you for answering,

I did use the same functions as you said for tx and rx ,but i haven't enabled the pull-ups, to be precise i wasn't given an option to enable pull-ups, I'll check why this might be happening ,but if you have any fix 
please do answer.

do you mean that I should use two boards?

I mean I only have one board with me right now, 
so, I want to try using the same board.

Set pullups in Cube ...see:

AScha3_0-1721021820152.png

 

for all used I2C pins ; no pullups = no I2C game.

+

set speed to something low, 10 kHz or so; 

AScha3_1-1721022047653.png

 

If you feel a post has answered your question, please click "Accept as Solution".

my bad!!!!
i thought when i click on the gpio pins their setting would pop up,
but i have to scroll!!!
thanks a lot.

still no change in the rx buffer.
may be my code is faulty.

 

#include "main.h"

/* Private variables ---------------------------------------------------------*/

 

I2C_HandleTypeDef hi2c1;

I2C_HandleTypeDef hi2c2;

 

/* USER CODE BEGIN PV */

uint8_t TxData[6] = {0x1, 0x2, 0x3, 0x4, 0x5, 0x6},RxData[6];

uint16_t slaveADDR=0x7F<<1;

/* USER CODE END PV */

 

/* Private function prototypes -----------------------------------------------*/

void SystemClock_Config(void);

static void MX_GPIO_Init(void);

static void MX_I2C1_Init(void);

static void MX_I2C2_Init(void);

 

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();

 

/* USER CODE BEGIN Init */

 

/* USER CODE END Init */

 

/* Configure the system clock */

SystemClock_Config();

 

/* USER CODE BEGIN SysInit */

 

/* USER CODE END SysInit */

 

/* Initialize all configured peripherals */

MX_GPIO_Init();

MX_I2C1_Init();

MX_I2C2_Init();

/* USER CODE BEGIN 2 */

//HAL_I2C_Slave_Receive_IT(&hi2c2, RxData, 6);

/* USER CODE END 2 */

 

/* Infinite loop */

/* USER CODE BEGIN WHILE */

while (1)

{

/* USER CODE END WHILE */

 

/* USER CODE BEGIN 3 */

HAL_I2C_Master_Transmit(&hi2c1, slaveADDR, TxData, 6, 1000);

HAL_Delay(1000);

 

}

/* USER CODE END 3 */

}

void SystemClock_Config(void)

{

RCC_OscInitTypeDef RCC_OscInitStruct = {0};

RCC_ClkInitTypeDef RCC_ClkInitStruct = {0};

 

/*AXI clock gating */

RCC->CKGAENR = 0xFFFFFFFF;

 

/** Supply configuration update enable

*/

HAL_PWREx_ConfigSupply(PWR_DIRECT_SMPS_SUPPLY);

 

/** Configure the main internal regulator output voltage

*/

__HAL_PWR_VOLTAGESCALING_CONFIG(PWR_REGULATOR_VOLTAGE_SCALE0);

 

while(!__HAL_PWR_GET_FLAG(PWR_FLAG_VOSRDY)) {}

 

/** Initializes the RCC Oscillators according to the specified parameters

* in the RCC_OscInitTypeDef structure.

*/

RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSE;

RCC_OscInitStruct.HSEState = RCC_HSE_ON;

RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;

RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSE;

RCC_OscInitStruct.PLL.PLLM = 1;

RCC_OscInitStruct.PLL.PLLN = 24;

RCC_OscInitStruct.PLL.PLLP = 2;

RCC_OscInitStruct.PLL.PLLQ = 4;

RCC_OscInitStruct.PLL.PLLR = 2;

RCC_OscInitStruct.PLL.PLLRGE = RCC_PLL1VCIRANGE_3;

RCC_OscInitStruct.PLL.PLLVCOSEL = RCC_PLL1VCOWIDE;

RCC_OscInitStruct.PLL.PLLFRACN = 0;

if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK)

{

Error_Handler();

}

 

/** Initializes the CPU, AHB and APB buses clocks

*/

RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK|RCC_CLOCKTYPE_SYSCLK

|RCC_CLOCKTYPE_PCLK1|RCC_CLOCKTYPE_PCLK2

|RCC_CLOCKTYPE_D3PCLK1|RCC_CLOCKTYPE_D1PCLK1;

RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK;

RCC_ClkInitStruct.SYSCLKDivider = RCC_SYSCLK_DIV1;

RCC_ClkInitStruct.AHBCLKDivider = RCC_HCLK_DIV1;

RCC_ClkInitStruct.APB3CLKDivider = RCC_APB3_DIV1;

RCC_ClkInitStruct.APB1CLKDivider = RCC_APB1_DIV1;

RCC_ClkInitStruct.APB2CLKDivider = RCC_APB2_DIV1;

RCC_ClkInitStruct.APB4CLKDivider = RCC_APB4_DIV1;

 

if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_2) != HAL_OK)

{

Error_Handler();

}

}

static void MX_I2C1_Init(void)

{

 

/* USER CODE BEGIN I2C1_Init 0 */

 

/* USER CODE END I2C1_Init 0 */

 

/* USER CODE BEGIN I2C1_Init 1 */

 

/* USER CODE END I2C1_Init 1 */

hi2c1.Instance = I2C1;

hi2c1.Init.Timing = 0xF010FFFF;

hi2c1.Init.OwnAddress1 = 0;

hi2c1.Init.AddressingMode = I2C_ADDRESSINGMODE_7BIT;

hi2c1.Init.DualAddressMode = I2C_DUALADDRESS_DISABLE;

hi2c1.Init.OwnAddress2 = 0;

hi2c1.Init.OwnAddress2Masks = I2C_OA2_NOMASK;

hi2c1.Init.GeneralCallMode = I2C_GENERALCALL_DISABLE;

hi2c1.Init.NoStretchMode = I2C_NOSTRETCH_DISABLE;

if (HAL_I2C_Init(&hi2c1) != HAL_OK)

{

Error_Handler();

}

 

/** Configure Analogue filter

*/

if (HAL_I2CEx_ConfigAnalogFilter(&hi2c1, I2C_ANALOGFILTER_ENABLE) != HAL_OK)

{

Error_Handler();

}

 

/** Configure Digital filter

*/

if (HAL_I2CEx_ConfigDigitalFilter(&hi2c1, 0) != HAL_OK)

{

Error_Handler();

}

/* USER CODE BEGIN I2C1_Init 2 */

 

/* USER CODE END I2C1_Init 2 */

 

}

 

/**

* @brief I2C2 Initialization Function

* @param None

* @retval None

*/

static void MX_I2C2_Init(void)

{

 

/* USER CODE BEGIN I2C2_Init 0 */

 

/* USER CODE END I2C2_Init 0 */

 

/* USER CODE BEGIN I2C2_Init 1 */

 

/* USER CODE END I2C2_Init 1 */

hi2c2.Instance = I2C2;

hi2c2.Init.Timing = 0xF010FFFF;

hi2c2.Init.OwnAddress1 = 252;

hi2c2.Init.AddressingMode = I2C_ADDRESSINGMODE_7BIT;

hi2c2.Init.DualAddressMode = I2C_DUALADDRESS_DISABLE;

hi2c2.Init.OwnAddress2 = 0;

hi2c2.Init.OwnAddress2Masks = I2C_OA2_NOMASK;

hi2c2.Init.GeneralCallMode = I2C_GENERALCALL_DISABLE;

hi2c2.Init.NoStretchMode = I2C_NOSTRETCH_DISABLE;

if (HAL_I2C_Init(&hi2c2) != HAL_OK)

{

Error_Handler();

}

 

/** Configure Analogue filter

*/

if (HAL_I2CEx_ConfigAnalogFilter(&hi2c2, I2C_ANALOGFILTER_ENABLE) != HAL_OK)

{

Error_Handler();

}

 

/** Configure Digital filter

*/

if (HAL_I2CEx_ConfigDigitalFilter(&hi2c2, 0) != HAL_OK)

{

Error_Handler();

}

/* USER CODE BEGIN I2C2_Init 2 */

 

/* USER CODE END I2C2_Init 2 */

 

}

static void MX_GPIO_Init(void)

{

/* USER CODE BEGIN MX_GPIO_Init_1 */

/* USER CODE END MX_GPIO_Init_1 */

 

/* GPIO Ports Clock Enable */

__HAL_RCC_GPIOH_CLK_ENABLE();

__HAL_RCC_GPIOB_CLK_ENABLE();

 

/* USER CODE BEGIN MX_GPIO_Init_2 */

/* USER CODE END MX_GPIO_Init_2 */

}

 

/* USER CODE BEGIN 4 */

void HAL_I2C_SlaveRxCpltCallback(I2C_HandleTypeDef *hi2c)

{

// Check if the callback is for the correct I2C instance

if (hi2c->Instance == hi2c2.Instance)

{

HAL_I2C_Slave_Receive_IT(&hi2c2, RxData, 6);

HAL_Delay(1000);

}

}

 

/* USER CODE END 4 */

 

/**

* @brief This function is executed in case of error occurrence.

* @retval None

*/

void Error_Handler(void)

{

/* USER CODE BEGIN Error_Handler_Debug */

/* User can add his own implementation to report the HAL error return state */

__disable_irq();

while (1)

{

}

/* USER CODE END Error_Handler_Debug */

}

 

please have a look at this.

1. post code with -- post code symbol.     </>

AScha3_0-1721025413340.png

 

2. why comment out: > //HAL_I2C_Slave_Receive_IT(&hi2c2, RxData, 6);

cannot work...

 

3. remove delay in callback : > HAL_Delay(1000);

What should it do useful in int-callback ??

If you feel a post has answered your question, please click "Accept as Solution".
Karl Yamashita
Lead III

Edit: I've just noticed @AScha.3  mentioned the same thing that I just wrote below, lol. 

 

You've commented out HAL_I2C_Slave_Receive_IT(&hi2c2, RxData, 6); but you need it.

You don't need the delay in the callback.

Make sure you enable the NVIC interrupt.

KarlYamashita_0-1721092165592.png

 

 

 

#include "main.h"

/* Private variables ---------------------------------------------------------*/

 

I2C_HandleTypeDef hi2c1;

I2C_HandleTypeDef hi2c2;

 

/* USER CODE BEGIN PV */

uint8_t TxData[6] = {0x1, 0x2, 0x3, 0x4, 0x5, 0x6},RxData[6];

uint16_t slaveADDR=0x7F<<1;

/* USER CODE END PV */

 

/* Private function prototypes -----------------------------------------------*/

void SystemClock_Config(void);

static void MX_GPIO_Init(void);

static void MX_I2C1_Init(void);

static void MX_I2C2_Init(void);

 

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();

 

/* USER CODE BEGIN Init */

 

/* USER CODE END Init */

 

/* Configure the system clock */

SystemClock_Config();

 

/* USER CODE BEGIN SysInit */

 

/* USER CODE END SysInit */

 

/* Initialize all configured peripherals */

MX_GPIO_Init();

MX_I2C1_Init();

MX_I2C2_Init();

/* USER CODE BEGIN 2 */

HAL_I2C_Slave_Receive_IT(&hi2c2, RxData, 6);

/* USER CODE END 2 */

 

/* Infinite loop */

/* USER CODE BEGIN WHILE */

while (1)

{

/* USER CODE END WHILE */

 

/* USER CODE BEGIN 3 */

HAL_I2C_Master_Transmit(&hi2c1, slaveADDR, TxData, 6, 1000);

HAL_Delay(1000);

 

}

/* USER CODE END 3 */

}

void SystemClock_Config(void)

{

RCC_OscInitTypeDef RCC_OscInitStruct = {0};

RCC_ClkInitTypeDef RCC_ClkInitStruct = {0};

 

/*AXI clock gating */

RCC->CKGAENR = 0xFFFFFFFF;

 

/** Supply configuration update enable

*/

HAL_PWREx_ConfigSupply(PWR_DIRECT_SMPS_SUPPLY);

 

/** Configure the main internal regulator output voltage

*/

__HAL_PWR_VOLTAGESCALING_CONFIG(PWR_REGULATOR_VOLTAGE_SCALE0);

 

while(!__HAL_PWR_GET_FLAG(PWR_FLAG_VOSRDY)) {}

 

/** Initializes the RCC Oscillators according to the specified parameters

* in the RCC_OscInitTypeDef structure.

*/

RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSE;

RCC_OscInitStruct.HSEState = RCC_HSE_ON;

RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;

RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSE;

RCC_OscInitStruct.PLL.PLLM = 1;

RCC_OscInitStruct.PLL.PLLN = 24;

RCC_OscInitStruct.PLL.PLLP = 2;

RCC_OscInitStruct.PLL.PLLQ = 4;

RCC_OscInitStruct.PLL.PLLR = 2;

RCC_OscInitStruct.PLL.PLLRGE = RCC_PLL1VCIRANGE_3;

RCC_OscInitStruct.PLL.PLLVCOSEL = RCC_PLL1VCOWIDE;

RCC_OscInitStruct.PLL.PLLFRACN = 0;

if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK)

{

Error_Handler();

}

 

/** Initializes the CPU, AHB and APB buses clocks

*/

RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK|RCC_CLOCKTYPE_SYSCLK

|RCC_CLOCKTYPE_PCLK1|RCC_CLOCKTYPE_PCLK2

|RCC_CLOCKTYPE_D3PCLK1|RCC_CLOCKTYPE_D1PCLK1;

RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK;

RCC_ClkInitStruct.SYSCLKDivider = RCC_SYSCLK_DIV1;

RCC_ClkInitStruct.AHBCLKDivider = RCC_HCLK_DIV1;

RCC_ClkInitStruct.APB3CLKDivider = RCC_APB3_DIV1;

RCC_ClkInitStruct.APB1CLKDivider = RCC_APB1_DIV1;

RCC_ClkInitStruct.APB2CLKDivider = RCC_APB2_DIV1;

RCC_ClkInitStruct.APB4CLKDivider = RCC_APB4_DIV1;

 

if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_2) != HAL_OK)

{

Error_Handler();

}

}

static void MX_I2C1_Init(void)

{

 

/* USER CODE BEGIN I2C1_Init 0 */

 

/* USER CODE END I2C1_Init 0 */

 

/* USER CODE BEGIN I2C1_Init 1 */

 

/* USER CODE END I2C1_Init 1 */

hi2c1.Instance = I2C1;

hi2c1.Init.Timing = 0xF010FFFF;

hi2c1.Init.OwnAddress1 = 0;

hi2c1.Init.AddressingMode = I2C_ADDRESSINGMODE_7BIT;

hi2c1.Init.DualAddressMode = I2C_DUALADDRESS_DISABLE;

hi2c1.Init.OwnAddress2 = 0;

hi2c1.Init.OwnAddress2Masks = I2C_OA2_NOMASK;

hi2c1.Init.GeneralCallMode = I2C_GENERALCALL_DISABLE;

hi2c1.Init.NoStretchMode = I2C_NOSTRETCH_DISABLE;

if (HAL_I2C_Init(&hi2c1) != HAL_OK)

{

Error_Handler();

}

 

/** Configure Analogue filter

*/

if (HAL_I2CEx_ConfigAnalogFilter(&hi2c1, I2C_ANALOGFILTER_ENABLE) != HAL_OK)

{

Error_Handler();

}

 

/** Configure Digital filter

*/

if (HAL_I2CEx_ConfigDigitalFilter(&hi2c1, 0) != HAL_OK)

{

Error_Handler();

}

/* USER CODE BEGIN I2C1_Init 2 */

 

/* USER CODE END I2C1_Init 2 */

 

}

 

/**

* @brief I2C2 Initialization Function

*  None

* @retval None

*/

static void MX_I2C2_Init(void)

{

 

/* USER CODE BEGIN I2C2_Init 0 */

 

/* USER CODE END I2C2_Init 0 */

 

/* USER CODE BEGIN I2C2_Init 1 */

 

/* USER CODE END I2C2_Init 1 */

hi2c2.Instance = I2C2;

hi2c2.Init.Timing = 0xF010FFFF;

hi2c2.Init.OwnAddress1 = 252;

hi2c2.Init.AddressingMode = I2C_ADDRESSINGMODE_7BIT;

hi2c2.Init.DualAddressMode = I2C_DUALADDRESS_DISABLE;

hi2c2.Init.OwnAddress2 = 0;

hi2c2.Init.OwnAddress2Masks = I2C_OA2_NOMASK;

hi2c2.Init.GeneralCallMode = I2C_GENERALCALL_DISABLE;

hi2c2.Init.NoStretchMode = I2C_NOSTRETCH_DISABLE;

if (HAL_I2C_Init(&hi2c2) != HAL_OK)

{

Error_Handler();

}

 

/** Configure Analogue filter

*/

if (HAL_I2CEx_ConfigAnalogFilter(&hi2c2, I2C_ANALOGFILTER_ENABLE) != HAL_OK)

{

Error_Handler();

}

 

/** Configure Digital filter

*/

if (HAL_I2CEx_ConfigDigitalFilter(&hi2c2, 0) != HAL_OK)

{

Error_Handler();

}

/* USER CODE BEGIN I2C2_Init 2 */

 

/* USER CODE END I2C2_Init 2 */

 

}

static void MX_GPIO_Init(void)

{

/* USER CODE BEGIN MX_GPIO_Init_1 */

/* USER CODE END MX_GPIO_Init_1 */

 

/* GPIO Ports Clock Enable */

__HAL_RCC_GPIOH_CLK_ENABLE();

__HAL_RCC_GPIOB_CLK_ENABLE();

 

/* USER CODE BEGIN MX_GPIO_Init_2 */

/* USER CODE END MX_GPIO_Init_2 */

}

 

/* USER CODE BEGIN 4 */

void HAL_I2C_SlaveRxCpltCallback(I2C_HandleTypeDef *hi2c)

{

// Check if the callback is for the correct I2C instance

if (hi2c->Instance == hi2c2.Instance)

{

HAL_I2C_Slave_Receive_IT(&hi2c2, RxData, 6);

//HAL_Delay(1000);

}

}

 

/* USER CODE END 4 */

 

/**

* @brief This function is executed in case of error occurrence.

* @retval None

*/

void Error_Handler(void)

{

/* USER CODE BEGIN Error_Handler_Debug */

/* User can add his own implementation to report the HAL error return state */

__disable_irq();

while (1)

{

}

/* USER CODE END Error_Handler_Debug */

}

 

 

Tips and Tricks with TimerCallback https://www.youtube.com/@eebykarl
If you find my solution useful, please click the Accept as Solution so others see the solution.