Skip to main content
Explorer
October 6, 2025
Question

DS2431 Read ROM returns 0x00 on STM32F446RE

  • October 6, 2025
  • 2 replies
  • 250 views

Post edited by ST moderator to be inline with the community rules especially with the code sharing. In next time please use </> button to paste your code. Please read this post: How to insert source code

Hi everyone,

I’m trying to communicate with a Maxim DS2431 (1-Wire EEPROM) using an STM32F446RE MCU.
I can successfully generate the reset and sometimes detect a presence pulse, but when I send the Read ROM (0x33) command, the data I receive is always 0x00 for all 8 bytes.

I’m implementing the 1-Wire protocol manually (bit-banging) using a GPIO pin.
Below are the hardware details and what I’ve tried so far.


🧱 Hardware setup

  • MCU: STM32F446RE @ 180 MHz

  • DS2431 powered at 3.3V (not parasitic)

  • 1-Wire line connected to: GPIOA_PIN_0

  • Pull-up resistor: tried 2.2kΩ and 1.8

     

    Is there anyone who has worked with DS2431 on STM32 before and can share experience, timing details, or working example code?

    Thanks in advance :folded_hands:

    Here is my 1-Wire read implementation:

    ```c

    /* USER CODE BEGIN Header */
    /* USER CODE END Header */
    /* Includes ------------------------------------------------------------------*/
    #include "main.h"
    
    
    /* Private includes ----------------------------------------------------------*/
    /* USER CODE BEGIN Includes */
    #define DS2431_PORT GPIOA
    #define DS2431_PIN GPIO_PIN_0
    #include "string.h"
    #include "stdio.h"
    
    
    /* USER CODE END Includes */
    
    
    /* Private typedef -----------------------------------------------------------*/
    /* USER CODE BEGIN PTD */
    /* USER CODE END PTD */
    
    
    /* Private define ------------------------------------------------------------*/
    /* USER CODE BEGIN PD */
    /* USER CODE END PD */
    
    
    /* Private macro -------------------------------------------------------------*/
    /* USER CODE BEGIN PM */
    extern UART_HandleTypeDef huart2;
    
    
    /* USER CODE END PM */
    
    
    /* Private variables ---------------------------------------------------------*/
    TIM_HandleTypeDef htim1;
    
    
    UART_HandleTypeDef huart2;
    
    
    /* USER CODE BEGIN PV */
    /* USER CODE END PV */
    
    
    /* Private function prototypes -----------------------------------------------*/
    void SystemClock_Config(void);
    static void MX_GPIO_Init(void);
    static void MX_USART2_UART_Init(void);
    static void MX_TIM1_Init(void);
    /* USER CODE BEGIN PFP */
    /* USER CODE END PFP */
    
    
    /* Private user code ---------------------------------------------------------*/
    /* USER CODE BEGIN 0 */
    void usDelay(uint16_t us)
    {
     __HAL_TIM_SET_COUNTER(&htim1, 0); // Counter'ı sıfırla
     while (__HAL_TIM_GET_COUNTER(&htim1) < us); // Bekle
    }
    
    
    void OneWire_OutputLow(void)
    {
     GPIO_InitTypeDef GPIO_InitStruct = {0};
     GPIO_InitStruct.Pin = DS2431_PIN;
     GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_OD;
     GPIO_InitStruct.Pull = GPIO_NOPULL;
     HAL_GPIO_Init(DS2431_PORT, &GPIO_InitStruct);
     HAL_GPIO_WritePin(DS2431_PORT, DS2431_PIN, GPIO_PIN_RESET);
    }
    
    
    void OneWire_Release(void)
    {
     GPIO_InitTypeDef GPIO_InitStruct = {0};
     GPIO_InitStruct.Pin = DS2431_PIN;
     GPIO_InitStruct.Mode = GPIO_MODE_INPUT;
     GPIO_InitStruct.Pull = GPIO_NOPULL;
     HAL_GPIO_Init(DS2431_PORT, &GPIO_InitStruct);
    }
    
    
    uint8_t OneWire_ReadPin(void)
    {
     return HAL_GPIO_ReadPin(DS2431_PORT, DS2431_PIN);
    }
    
    
    /* -------------------------------------------------------------
     * 1-WIRE RESET + PRESENCE DETECT
     * ------------------------------------------------------------- */
    uint8_t OneWire_Reset(void)
    {
     uint8_t presence = 1; // varsayılan: cihaz yok
    
    
     // Hat LOW yap
     OneWire_OutputLow();
     usDelay(480); // Reset pulse
    
    
     // Hat HIGH (release)
     OneWire_Release();
    
    
     usDelay(70); // Wait before presence check
    
    
     // Presence okuyalım (0 = device present)
     if (OneWire_ReadPin() == GPIO_PIN_RESET)
     presence = 0;
    
    
     usDelay(410); // Wait for end of timeslot
     return presence; // 0 = presence detected, 1 = no device
    }
    
    
    /* -------------------------------------------------------------
     * 1-WIRE WRITE BIT
     * ------------------------------------------------------------- */
    
    
    /* -------------------------------------------------------------
     * 1-WIRE READ BIT
     * ------------------------------------------------------------- */
    uint8_t OneWire_ReadBit(void)
    {
     uint8_t bit = 0;
    
    
     OneWire_OutputLow();
     usDelay(6);
     OneWire_Release();
     usDelay(9);
    
    
     bit = OneWire_ReadPin();
    
    
     usDelay(55);
     return bit;
    }
    
    
    uint8_t OneWire_ReadByte(void)
    {
     uint8_t data = 0;
     for (int i = 0; i < 8; i++)
     {
     // Doğru bit pozisyonuna yerleştir
     data >>= 1;
     if (OneWire_ReadBit())
     data |= 0x80;
     // usDelay(1); // Bu satırı KALDIR - zaten ReadBit içinde delay var
     }
     return data;
    }
    
    
    void OneWire_WriteBit(uint8_t bit)
    {
     if (bit)
     {
     OneWire_OutputLow();
     usDelay(6);
     OneWire_Release();
     usDelay(64);
     }
     else
     {
     OneWire_OutputLow();
     usDelay(60);
     OneWire_Release();
     usDelay(10);
     }
    }
    void OneWire_WriteByte(uint8_t data)
    {
     for (int i = 0; i < 8; i++)
     {
     OneWire_WriteBit(data & 0x01);
     data >>= 1;
     }
    }
    
    
    void OneWire_ReadROM(uint8_t *romData)
    {
     if (OneWire_Reset() == 0) // Presence kontrolü
     {
     OneWire_WriteByte(0x33); // Read ROM komutu
     for (int i = 0; i < 8; i++)
     {
     romData[i] = OneWire_ReadByte();
     }
     }
     else
     {
    
    
     }
    }
    /* USER CODE END 0 */
    
    
    /**
     * @brief The application entry point.
     * @retval int
     */
    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_USART2_UART_Init();
     MX_TIM1_Init();
     /* USER CODE BEGIN 2 */
     uint8_t rom[8];
     char buffer[100];
    
    
     /* USER CODE END 2 */
    
    
     /* Infinite loop */
     /* USER CODE BEGIN WHILE */
     while(1){
    // HAL_GPIO_TogglePin(GPIOA, GPIO_PIN_5);
    // usDelay(1000);
     if (OneWire_Reset() == 0)
     {
     // Presence detected
     HAL_GPIO_WritePin(GPIOA, GPIO_PIN_5, GPIO_PIN_SET);
    
    
    
    
     OneWire_ReadROM(rom);
     sprintf(buffer, "ROM = ");
     HAL_UART_Transmit(&huart2, (uint8_t*)buffer, strlen(buffer), HAL_MAX_DELAY);
    
    
     for (int i = 0; i < 8; i++)
     {
     sprintf(buffer, "%02X ", rom[i]);
     HAL_UART_Transmit(&huart2, (uint8_t*)buffer, strlen(buffer), HAL_MAX_DELAY);
     }
    
    
     sprintf(buffer, "\r\n");
     HAL_UART_Transmit(&huart2, (uint8_t*)buffer, strlen(buffer), HAL_MAX_DELAY);
    
    
     }
     else
     {
     HAL_GPIO_WritePin(GPIOA, GPIO_PIN_5, GPIO_PIN_RESET);
    
    
     // No device
     }
     }
    // if (OneWire_Reset())
    // {
    // OneWire_ReadROM(rom);
    //
    // sprintf(buffer, "ROM = ");
    // HAL_UART_Transmit(&huart2, (uint8_t*)buffer, strlen(buffer), HAL_MAX_DELAY);
    //
    // for (int i = 0; i < 8; i++)
    // {
    // sprintf(buffer, "%02X ", rom[i]);
    // HAL_UART_Transmit(&huart2, (uint8_t*)buffer, strlen(buffer), HAL_MAX_DELAY);
    // }
    //
    // sprintf(buffer, "\r\n");
    // HAL_UART_Transmit(&huart2, (uint8_t*)buffer, strlen(buffer), HAL_MAX_DELAY);
    // }
    // else
    // {
    // char msg[] = "No presence detected.\r\n";
    // HAL_UART_Transmit(&huart2, (uint8_t*)msg, strlen(msg), HAL_MAX_DELAY);
    // }
    //
    // HAL_Delay(1000);
    // }
    
    
    
    
     /* USER CODE END WHILE */
    
    
     /* USER CODE BEGIN 3 */
     /* USER CODE END 3 */
    }
    
    
    /**
     * @brief System Clock Configuration
     * @retval None
     */
    void SystemClock_Config(void)
    {
     RCC_OscInitTypeDef RCC_OscInitStruct = {0};
     RCC_ClkInitTypeDef RCC_ClkInitStruct = {0};
    
    
     /** Configure the main internal regulator output voltage
     */
     __HAL_RCC_PWR_CLK_ENABLE();
     __HAL_PWR_VOLTAGESCALING_CONFIG(PWR_REGULATOR_VOLTAGE_SCALE1);
    
    
     /** Initializes the RCC Oscillators according to the specified parameters
     * in the RCC_OscInitTypeDef structure.
     */
     RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSI;
     RCC_OscInitStruct.HSIState = RCC_HSI_ON;
     RCC_OscInitStruct.HSICalibrationValue = RCC_HSICALIBRATION_DEFAULT;
     RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;
     RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSI;
     RCC_OscInitStruct.PLL.PLLM = 8;
     RCC_OscInitStruct.PLL.PLLN = 180;
     RCC_OscInitStruct.PLL.PLLP = RCC_PLLP_DIV2;
     RCC_OscInitStruct.PLL.PLLQ = 2;
     RCC_OscInitStruct.PLL.PLLR = 2;
     if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK)
     {
     Error_Handler();
     }
    
    
     /** Activate the Over-Drive mode
     */
     if (HAL_PWREx_EnableOverDrive() != 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_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK;
     RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;
     RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV4;
     RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV2;
    
    
     if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_5) != HAL_OK)
     {
     Error_Handler();
     }
    }
    
    
    /**
     * @brief TIM1 Initialization Function
     * @PAram None
     * @retval None
     */
    static void MX_TIM1_Init(void)
    {
    
    
     /* USER CODE BEGIN TIM1_Init 0 */
    
    
     /* USER CODE END TIM1_Init 0 */
    
    
     TIM_ClockConfigTypeDef sClockSourceConfig = {0};
     TIM_MasterConfigTypeDef sMasterConfig = {0};
    
    
     /* USER CODE BEGIN TIM1_Init 1 */
    
    
     /* USER CODE END TIM1_Init 1 */
     htim1.Instance = TIM1;
     htim1.Init.Prescaler = 100-1;
     htim1.Init.CounterMode = TIM_COUNTERMODE_UP;
     htim1.Init.Period = 0xffff-1;
     htim1.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1;
     htim1.Init.RepetitionCounter = 0;
     htim1.Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_ENABLE;
     if (HAL_TIM_Base_Init(&htim1) != HAL_OK)
     {
     Error_Handler();
     }
     sClockSourceConfig.ClockSource = TIM_CLOCKSOURCE_INTERNAL;
     if (HAL_TIM_ConfigClockSource(&htim1, &sClockSourceConfig) != HAL_OK)
     {
     Error_Handler();
     }
     sMasterConfig.MasterOutputTrigger = TIM_TRGO_UPDATE;
     sMasterConfig.MasterSlaveMode = TIM_MASTERSLAVEMODE_DISABLE;
     if (HAL_TIMEx_MasterConfigSynchronization(&htim1, &sMasterConfig) != HAL_OK)
     {
     Error_Handler();
     }
     /* USER CODE BEGIN TIM1_Init 2 */
     HAL_TIM_Base_Start(&htim1);
     /* USER CODE END TIM1_Init 2 */
    
    
    }
    
    
    /**
     * @brief USART2 Initialization Function
     * @PAram None
     * @retval None
     */
    static void MX_USART2_UART_Init(void)
    {
    
    
     /* USER CODE BEGIN USART2_Init 0 */
    
    
     /* USER CODE END USART2_Init 0 */
    
    
     /* USER CODE BEGIN USART2_Init 1 */
    
    
     /* USER CODE END USART2_Init 1 */
     huart2.Instance = USART2;
     huart2.Init.BaudRate = 9600;
     huart2.Init.WordLength = UART_WORDLENGTH_8B;
     huart2.Init.StopBits = UART_STOPBITS_1;
     huart2.Init.Parity = UART_PARITY_NONE;
     huart2.Init.Mode = UART_MODE_TX_RX;
     huart2.Init.HwFlowCtl = UART_HWCONTROL_NONE;
     huart2.Init.OverSampling = UART_OVERSAMPLING_16;
     if (HAL_UART_Init(&huart2) != HAL_OK)
     {
     Error_Handler();
     }
     /* USER CODE BEGIN USART2_Init 2 */
    
    
     /* USER CODE END USART2_Init 2 */
    
    
    }
    
    
    /**
     * @brief GPIO Initialization Function
     * @PAram None
     * @retval None
     */
    static void MX_GPIO_Init(void)
    {
     GPIO_InitTypeDef GPIO_InitStruct = {0};
     /* USER CODE BEGIN MX_GPIO_Init_1 */
     /* USER CODE END MX_GPIO_Init_1 */
    
    
     /* GPIO Ports Clock Enable */
     __HAL_RCC_GPIOC_CLK_ENABLE();
     __HAL_RCC_GPIOH_CLK_ENABLE();
     __HAL_RCC_GPIOA_CLK_ENABLE();
    
    
     /*Configure GPIO pin Output Level */
     HAL_GPIO_WritePin(GPIOA, GPIO_PIN_0, GPIO_PIN_SET);
    
    
     /*Configure GPIO pin Output Level */
     HAL_GPIO_WritePin(GPIOA, GPIO_PIN_5, GPIO_PIN_RESET);
    
    
     /*Configure GPIO pin : PA0 */
     GPIO_InitStruct.Pin = GPIO_PIN_0;
     GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_OD;
     GPIO_InitStruct.Pull = GPIO_NOPULL;
     GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
     HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
    
    
     /*Configure GPIO pin : PA5 */
     GPIO_InitStruct.Pin = GPIO_PIN_5;
     GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
     GPIO_InitStruct.Pull = GPIO_NOPULL;
     GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
     HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
    
    
     /* USER CODE BEGIN MX_GPIO_Init_2 */
     /* USER CODE END MX_GPIO_Init_2 */
    }
    
    
    /* USER CODE BEGIN 4 */
    /* 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 CODE END Error_Handler_Debug */
    }
    
    
    #ifdef USE_FULL_ASSERT
    /**
     * @brief Reports the name of the source file and the source line number
     * where the assert_param error has occurred.
     * @PAram file: pointer to the source file name
     * @PAram line: assert_param error line source number
     * @retval None
     */
    void assert_failed(uint8_t *file, uint32_t line)
    {
     /* USER CODE BEGIN 6 */
     /* USER CODE END 6 */
    }
    #endif /* USE_FULL_ASSERT */

     

    ```

    This topic has been closed for replies.

    2 replies

    Technical Moderator
    October 7, 2025

    Hello @farukke 

    Did you use an oscilloscope or logic analyser to verify whether the device is sending the correct data?

    Super User
    October 7, 2025

    @farukke wrote:

    I’m implementing the 1-Wire protocol manually (bit-banging) using a GPIO pin.


    So how have you proved that your implementation is correct?

    As @Saket_Om said, you need to use an oscilloscope to verify both timing and voltage levels.

     


    @farukke wrote:

    I can successfully generate the reset and sometimes detect a presence pulse


    Sounds very much like a timing issue...

     


    @farukke wrote:

    Is there anyone who has worked with DS2431 on STM32 before and can share experience, timing details, or working example code?


    Yes, there have been many previous threads on 1-WireTM - try a forum search; eg,

    https://community.st.com/t5/forums/searchpage/tab/message?advanced=false&allow_punctuation=false&q=1-Wire

    https://community.st.com/t5/forums/searchpage/tab/message?q=1Wire&noSynonym=false&collapse_discussion=true

     

    Rather than bit-banging, have you considered synthesising the timing using a UART or SPI?

     

    PS:


    @farukke wrote:

     a Maxim DS2431 (1-Wire EEPROM)


    Note that it's now Analog Devices - they acquired Maxim 4 years ago:

    https://www.analog.com/en/products/ds2431.html