STM32 I2C Not Working with Other Interrupts
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content
‎2024-07-31 6:36 AM - last edited on ‎2024-07-31 7:19 AM by Andrew Neil
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);
}
Solved! Go to Solution.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content
‎2024-07-31 7:27 AM
Sorry, I tried to delete that part until you replied, but I guess I couldn't make it. If you look again, you will see that I deleted them too.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content
‎2024-07-31 7:29 AM
Please try the step-by-step approach I suggested.
A complex system designed from scratch never works and cannot be patched up to make it work.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content
‎2024-07-31 7:31 AM
Thank you. I am gonna try now.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content
‎2024-07-31 7:42 AM
Always ensure a call to HAL_I2C_IsDeviceReady returns HAL_OK before you do anything else on the bus with that device.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content
‎2024-07-31 7:45 AM
@AlexanderKibarov wrote:Thank you. I am gonna try now.
:thumbs_up:
While you're doing it, observe what's happening on the I2C lines.
A complex system designed from scratch never works and cannot be patched up to make it work.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content
‎2024-07-31 7:53 AM
hello, HAL_BUSY is returning as a result
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content
‎2024-07-31 8:04 AM
Hello @AlexanderKibarov,
You can start from the blink project that is working fie and add step by step the UART configuration.
You can look to the datasheet, there are some GPIO pin that are shared between UART and I2C1.
Saket_Om
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content
‎2024-07-31 9:55 AM
This indicates SDA or SCL is likely being held low, which is a hardware problem.
Verify pinout is correct. Ensure your external pullups are in the range of 1-5 kOhm. You are using external pullups, yes?
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content
‎2024-07-31 11:16 AM
It was fixed when I switched i2c from 1st to 2nd but i dont know why
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content
‎2024-07-31 11:16 AM
It was fixed when I switched i2c from 1st to 2nd but I don't know why
