Skip to main content
Associate
July 12, 2024
Question

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

  • July 12, 2024
  • 3 replies
  • 3117 views

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??.

3 replies

AScha.3
Super User
July 12, 2024

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""."
PrvitAuthor
Associate
July 15, 2024

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.

AScha.3
Super User
July 15, 2024

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""."
Andrew Neil
Super User
July 12, 2024

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.

A complex system that works is invariably found to have evolved from a simple system that worked.A complex system designed from scratch never works and cannot be patched up to make it work.
PrvitAuthor
Associate
July 15, 2024

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.

Karl Yamashita
Principal
July 16, 2024

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 */

}

 

 

If a reply has proven helpful, click on Accept as Solution so that it'll show at top of the post.CAN Jammer an open source CAN bus hacking toolCANableV3 Open Source
PrvitAuthor
Associate
July 16, 2024

i have removed the comments but still the same problem,
and yes i have enabled the event interrupt.