Skip to main content
Visitor II
July 28, 2025
Question

MCU Will Not Generate Any SCL Pulses or Drive SDA Low Using CubeMX Generated Code

  • July 28, 2025
  • 2 replies
  • 260 views

I am attempting to interface an STM32H723 with an ADXL345 accelerometer. I used CubeMX and generated I2C driver code with 400kHZ clock frequency and error/event interrupts enabled. I have attempted both I2C1 and I2C2, but neither peripheral generates any clock pulses or driving of the SDA pin low. I am using 4.7K pull-up resistor between SDA/SCL and 3.3V. I am attempting to  do a 1-byte simple register read of the ADXL345 device from register 0x00, and the ADXL345 device address for read is 0xA7. However, I cannot seem to get I2C1 or I2C2 pins to drive any activity - they just remain pulled high to 3.3V. I am wondering if I am missing something in the initialization code CubMX generated. Cross-referencing with the reference manual, nothing looks out of the ordinary for what I attempted to configure. If anyone could point out anything odd in the init code, I'd greatly appreciate it. 

Init code:

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 = 0x00707CBB;
 hi2c2.Init.OwnAddress1 = 0;
 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 */

}
void HAL_I2C_MspInit(I2C_HandleTypeDef* i2cHandle)
{

 GPIO_InitTypeDef GPIO_InitStruct = {0};
 RCC_PeriphCLKInitTypeDef PeriphClkInitStruct = {0};
 if(i2cHandle->Instance==I2C2)
 {
 /* USER CODE BEGIN I2C2_MspInit 0 */

 /* USER CODE END I2C2_MspInit 0 */

 /** Initializes the peripherals clock
 */
 PeriphClkInitStruct.PeriphClockSelection = RCC_PERIPHCLK_I2C2;
 PeriphClkInitStruct.I2c123ClockSelection = RCC_I2C1235CLKSOURCE_D2PCLK1;
 if (HAL_RCCEx_PeriphCLKConfig(&PeriphClkInitStruct) != HAL_OK)
 {
 Error_Handler();
 }

 __HAL_RCC_GPIOF_CLK_ENABLE();
 /**I2C2 GPIO Configuration
 PF0 ------> I2C2_SDA
 PF1 ------> I2C2_SCL
 */
 GPIO_InitStruct.Pin = GPIO_PIN_0|GPIO_PIN_1;
 GPIO_InitStruct.Mode = GPIO_MODE_AF_OD;
 GPIO_InitStruct.Pull = GPIO_NOPULL;
 GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
 GPIO_InitStruct.Alternate = GPIO_AF4_I2C2;
 HAL_GPIO_Init(GPIOF, &GPIO_InitStruct);

 /* I2C2 clock enable */
 __HAL_RCC_I2C2_CLK_ENABLE();

 /* I2C2 interrupt Init */
 HAL_NVIC_SetPriority(I2C2_EV_IRQn, 0, 0);
 HAL_NVIC_EnableIRQ(I2C2_EV_IRQn);
 HAL_NVIC_SetPriority(I2C2_ER_IRQn, 0, 0);
 HAL_NVIC_EnableIRQ(I2C2_ER_IRQn);
 /* USER CODE BEGIN I2C2_MspInit 1 */

 /* USER CODE END I2C2_MspInit 1 */
 }
}

 

int main(void)
{

 /* USER CODE BEGIN 1 */

 /* USER CODE END 1 */

 /* MPU Configuration--------------------------------------------------------*/
 MPU_Config();

 /* 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_I2C2_Init();
 /* USER CODE BEGIN 2 */
 
 uint8_t devIdReg = 0x00;
 uint8_t devIdValue = 0x00;
 
 HAL_I2C_Mem_Read_IT(&hi2c2, 0xA7, devIdReg, I2C_MEMADD_SIZE_8BIT, (uint8_t *)&devIdValue, 1);

 /* USER CODE END 2 */

 /* Infinite loop */
 /* USER CODE BEGIN WHILE */
 while (1)
 {
 /* USER CODE END WHILE */

 /* USER CODE BEGIN 3 */
 }
 /* USER CODE END 3 */
}


And before anyone asks: I have tried to use the MasterTransmit_IT() HAL function, but this also generates no activity on the line. I also have attempted to execute the communication attempt with the ADXL345 disconnected and the I2C pins just connected to the breadboard with the pullups - still no clock pulses, so I don't think the accelormeter is in any odd state where it it's holding the lines high. I also have seen that once the HAL Mem_Read() or MasterTransmit() functions are called, the START bit is set although I see no start condition on line. After this, the BUSY flag is stuck set in the ISR register. I also have ensured the PE bit is set in CR1. 

    This topic has been closed for replies.

    2 replies

    Super User
    July 28, 2025

    Use HAL_I2C_IsDeviceReady and ensure it returns HAL_OK before doing anything else with I2C. If it doesn't return HAL_OK, check the ErrorCode for the failure reason.

    Is BUSY is set, it indicates that the lines are low, likely due to a START condition.

    TDK_0-1753722089918.png

     

    Get blocking functions working before trying non-blocking.

    Super User
    July 28, 2025

    Please show your schematic - see: How to write your question to maximize your chances to find a solution

    Some good, clear photos of your setup may also help.

     

    If you just set the used pins as GPIO, can you set the SDA and SCL lines high & low?

     

    Have you tried this on an ST board; eg, Nucleo ?

    Have you tried ST's I2C examples?

     

    As @TDK said, get it working using blocking calls before moving on the non-blocking (interrupts, etc); use HAL_I2C_IsDeviceReady to confirm that you can address the slave.