cancel
Showing results for 
Search instead for 
Did you mean: 

STM32 I2C Not Working with Other Interrupts

AlexanderKibarov
Associate III

Hello, I'm using the STM32F413ZH board to read data from the MPU6050. While the data retrieval works when I implement it in a blank project, it fails to function correctly in my current project. This project also includes two additional UART interrupts, though they are not currently connected to the system. What might be causing the issue?

In this project, HAL_StatusTypeDef always returns HAL_BUSY

Thank You.

 

 

#include "main.h"
#include "string.h"

#define MAX_NMEA_PROTOCOL_CHARACTER_LENGTH_ 82

I2C_HandleTypeDef hi2c1;

UART_HandleTypeDef huart4;
UART_HandleTypeDef huart5;
UART_HandleTypeDef huart3;

PCD_HandleTypeDef hpcd_USB_OTG_FS;

void SystemClock_Config(void);
static void MX_GPIO_Init(void);
static void MX_USART3_UART_Init(void);
static void MX_USB_OTG_FS_PCD_Init(void);
static void MX_UART4_Init(void);
static void MX_UART5_Init(void);
static void MX_I2C1_Init(void);

HAL_StatusTypeDef hal_status_one;  //THIS CODE FOR I2C 
uint8_t data_mpu[1] = {0x00};  //THIS CODE FOR I2C 

struct Data_Struct {
	uint8_t leds_mode;
	uint8_t windows_angle;
	uint8_t turn_home;
	uint8_t tilt_protect;
	uint8_t turn_capsize;
} KIBAR_DATA;

uint8_t last_data[3] = { 255, 255, 255 };
uint8_t private_array[1];
uint8_t template_buffer[12] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
		0x00, 0x00, 0x00, 0x00 };
uint8_t instruction_buffer[2] = { 0x00, 0x00 };
uint8_t main_buffer[5] = { 0x00, 0x00, 0x00, 0x00, 0x00 };
volatile uint8_t ff_index = 0;
volatile uint8_t array_index = 0;
volatile uint8_t is_there_back = 0;

volatile uint8_t gps_counter = 0;
volatile uint8_t mode_register = 0;
uint8_t private_gps_buffer[1] = { 0x00 };
uint8_t template_gps_buffer[MAX_NMEA_PROTOCOL_CHARACTER_LENGTH_];
uint8_t latitude_gps_buffer[9];
uint8_t longitude_gps_buffer[10];

//Uart NVIC Interrupt(Uart Global Interrupt) Aktif Edilmeli
void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart) {
	if (huart == &huart4) {
		HAL_UART_Receive_IT(&huart4, private_array, 1);
		if (private_array[0] == 255) {
			ff_index++;
			if (ff_index == 3) {
				if (array_index == 2) {
					for (int i = 0; i < 2; i++) {
						instruction_buffer[i] = template_buffer[i];
					}
					is_there_back = 1;
				} else if (array_index == 5) {
					for (int i = 0; i < 5; i++) {
						main_buffer[i] = template_buffer[i];
					}
					if (is_there_back == 1) {
						if (instruction_buffer[1] == 108) {
							KIBAR_DATA.leds_mode = main_buffer[1];
						}
						if (instruction_buffer[1] == 119) {
							KIBAR_DATA.windows_angle = main_buffer[1];
						}
						if (instruction_buffer[1] == 104) {
							if (KIBAR_DATA.turn_home == 0)
								KIBAR_DATA.turn_home = 1;
							else
								KIBAR_DATA.turn_home = 0;
						}
						if (instruction_buffer[1] == 116) {
							KIBAR_DATA.tilt_protect = main_buffer[1];
						}
						if (instruction_buffer[1] == 99) {
							if (KIBAR_DATA.turn_capsize == 0)
								KIBAR_DATA.turn_capsize = 1;
							else
								KIBAR_DATA.turn_capsize = 0;
						}
						is_there_back = 0;
					}
				}
				memset(template_buffer, 0x00, 12);
				ff_index = 0;
				array_index = 0;
			}
		} else {
			template_buffer[array_index] = private_array[0];
			array_index++;
		}
	}

	if (huart == &huart5) {
		HAL_UART_Receive_IT(&huart5, private_gps_buffer, 1);
		if (gps_counter == 0 && mode_register == 0
				&& private_gps_buffer[0] == 0x24)
			mode_register = 1;
		if (gps_counter == 0 && mode_register == 0
				&& private_gps_buffer[0] != 0x24)
			mode_register = 2;
		if (mode_register == 1) {
			if (private_gps_buffer[0] == 0x0A) {
				template_gps_buffer[gps_counter] = private_gps_buffer[0];
				if (gps_counter > 30) {
					for (int i = 7; i < 17; i++) {
						if (i != 11) {
							latitude_gps_buffer[i - 7] = template_gps_buffer[i];
						} else continue;
					}
					for (int i = 20; i < 31; i++) {
						if (i != 25) {
							longitude_gps_buffer[i - 20] = template_gps_buffer[i];
						} else continue;
					}
				}
				memset(template_gps_buffer, 0x00, MAX_NMEA_PROTOCOL_CHARACTER_LENGTH_);
				gps_counter = 0;
				mode_register = 0;
			} else {
				template_gps_buffer[gps_counter] = private_gps_buffer[0];
				gps_counter++;
				if (gps_counter == 5) {
					if (!(private_gps_buffer[0] == 0x4C)) {
						memset(template_gps_buffer, 0x00, MAX_NMEA_PROTOCOL_CHARACTER_LENGTH_);
						gps_counter = 0;
						mode_register = 2;
					}
				}
			}
		} else if (mode_register == 2) {
			if (private_gps_buffer[0] == 0x24) {
				template_gps_buffer[gps_counter] = private_gps_buffer[0];
				gps_counter++;
				mode_register = 1;
			}
		}
	}
}

int main(void)
{
  memset(template_gps_buffer, 0x00, MAX_NMEA_PROTOCOL_CHARACTER_LENGTH_);
  memset(latitude_gps_buffer, 0x00, 9);
  memset(longitude_gps_buffer, 0x00, 10);
  KIBAR_DATA.turn_capsize = 0;
  KIBAR_DATA.turn_home = 0;

  HAL_Init();

  SystemClock_Config();

  MX_GPIO_Init();
  MX_USART3_UART_Init();
  MX_USB_OTG_FS_PCD_Init();
  MX_UART4_Init();
  MX_UART5_Init();
  MX_I2C1_Init();

  HAL_UART_Receive_IT(&huart4, private_array, 1);
  HAL_UART_Receive_IT(&huart5, private_gps_buffer, 1);

  while (1) {
    //THIS CODE FOR I2C 
    hal_status_one = HAL_I2C_Mem_Read(&hi2c1, 0xD0, 0x75, 1, data_mpu, 1, 100);
	}
}


static void MX_I2C1_Init(void)
{
  hi2c1.Instance = I2C1;
  hi2c1.Init.ClockSpeed = 100000;
  hi2c1.Init.DutyCycle = I2C_DUTYCYCLE_2;
  hi2c1.Init.OwnAddress1 = 0;
  hi2c1.Init.AddressingMode = I2C_ADDRESSINGMODE_7BIT;
  hi2c1.Init.DualAddressMode = I2C_DUALADDRESS_DISABLE;
  hi2c1.Init.OwnAddress2 = 0;
  hi2c1.Init.GeneralCallMode = I2C_GENERALCALL_DISABLE;
  hi2c1.Init.NoStretchMode = I2C_NOSTRETCH_DISABLE;
  if (HAL_I2C_Init(&hi2c1) != HAL_OK)
  {
    Error_Handler();
  }
}

static void MX_UART4_Init(void)
{
  huart4.Instance = UART4;
  huart4.Init.BaudRate = 9600;
  huart4.Init.WordLength = UART_WORDLENGTH_8B;
  huart4.Init.StopBits = UART_STOPBITS_1;
  huart4.Init.Parity = UART_PARITY_NONE;
  huart4.Init.Mode = UART_MODE_TX_RX;
  huart4.Init.HwFlowCtl = UART_HWCONTROL_NONE;
  huart4.Init.OverSampling = UART_OVERSAMPLING_16;
  if (HAL_UART_Init(&huart4) != HAL_OK)
  {
    Error_Handler();
  }
}

static void MX_UART5_Init(void)
{
  huart5.Instance = UART5;
  huart5.Init.BaudRate = 115200;
  huart5.Init.WordLength = UART_WORDLENGTH_8B;
  huart5.Init.StopBits = UART_STOPBITS_1;
  huart5.Init.Parity = UART_PARITY_NONE;
  huart5.Init.Mode = UART_MODE_TX_RX;
  huart5.Init.HwFlowCtl = UART_HWCONTROL_NONE;
  huart5.Init.OverSampling = UART_OVERSAMPLING_16;
  if (HAL_UART_Init(&huart5) != HAL_OK)
  {
    Error_Handler();
  }
}

static void MX_GPIO_Init(void)
{
  GPIO_InitTypeDef GPIO_InitStruct = {0};

  __HAL_RCC_GPIOC_CLK_ENABLE();
  __HAL_RCC_GPIOH_CLK_ENABLE();
  __HAL_RCC_GPIOA_CLK_ENABLE();
  __HAL_RCC_GPIOB_CLK_ENABLE();
  __HAL_RCC_GPIOD_CLK_ENABLE();
  __HAL_RCC_GPIOG_CLK_ENABLE();

  HAL_GPIO_WritePin(GPIOB, LD1_Pin|LD3_Pin|LD2_Pin, GPIO_PIN_RESET);

  HAL_GPIO_WritePin(USB_PowerSwitchOn_GPIO_Port, USB_PowerSwitchOn_Pin, GPIO_PIN_RESET);

  GPIO_InitStruct.Pin = USER_Btn_Pin;
  GPIO_InitStruct.Mode = GPIO_MODE_IT_RISING;
  GPIO_InitStruct.Pull = GPIO_NOPULL;
  HAL_GPIO_Init(USER_Btn_GPIO_Port, &GPIO_InitStruct);

  GPIO_InitStruct.Pin = LD1_Pin|LD3_Pin|LD2_Pin;
  GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
  GPIO_InitStruct.Pull = GPIO_NOPULL;
  GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
  HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);

  GPIO_InitStruct.Pin = USB_PowerSwitchOn_Pin;
  GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
  GPIO_InitStruct.Pull = GPIO_NOPULL;
  GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
  HAL_GPIO_Init(USB_PowerSwitchOn_GPIO_Port, &GPIO_InitStruct);

  GPIO_InitStruct.Pin = USB_OverCurrent_Pin;
  GPIO_InitStruct.Mode = GPIO_MODE_INPUT;
  GPIO_InitStruct.Pull = GPIO_NOPULL;
  HAL_GPIO_Init(USB_OverCurrent_GPIO_Port, &GPIO_InitStruct);
}

 

 

 

 

 

 

 

 

29 REPLIES 29

It was fixed when I switched i2c from 1st to 2nd but I don't know why

You're using the NUCLEO-F413ZH board, correct?

Assuming no UART conflicts, my guess would be the dev board has pullup resistors on the pins used for I2C2's SCL and SDA lines, but not on I2C1's.  I can't seem to locate a schematic for that board to verify, though.

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


@AlexanderKibarov wrote:

It was fixed when I switched i2c from 1st to 2nd but i dont know why


You mean you used I2C2 instead of I2C1 ?

Again,  observe what's happening on the I2C lines - what's different ?

As @TDK said, the HAL_BUSY return likely means that one/both line is being held low.

Look at the I2C lines to see if that is, indeed, the case with I2C1 but not I2C2.

If it is the case, then look at the schematic to see why that might be ...

Note that everyone can see all posts - there's no need to repeat the same thing.

You can mention users by using '@' ...


@Dazai wrote:

  I can't seem to locate a schematic for that board to verify, though.


Here: https://www.st.com/en/evaluation-tools/nucleo-f413zh.html#cad-resources

@AlexanderKibarov what pins were you using for I2C1 and I2C2 ?

And what pins for the UARTs ?

Hello sir, there are pullup resistors on mpu6050. But then I read data again via i2c1, it worked for a while, then data reception stopped again for no reason.

And I also observed that if I remove and plug in the sensor while getting HAL_BUSY, it works correctly.

But then I read the data again via i2c1, it worked for a while, then the data reception stopped again for no reason. I think there is an error as you said, a problem in the data lines. everything seems random.

And I also observed that if I remove and plug in the sensor while getting HAL_BUSY, it works correctly.

Again, no need to repeat replies!

:face_with_tears_of_joy: