STM32 One Wire and DS18B20 communcation problems, I think its a GPIO setting problem

Viewed 33

I am getting my feet wet with SMT32 and some basic lower level things instead of using libraries.

I am running into a problem with a ( I would think ) very basic program.

All I want to do is use the STM32 ( Nucelo - F302R8 ) to try and detect a DS18B20 sensor on a OneWire bus. ( Port C Pin 0 ) If it detects it, put on the on-board LED ( Port B, Pin 13 ) , if not turn it off. That is it, nothing else for now at least.

I have read the initializing parts of the DS18B20 Datasheets and seen how a lot of people do it online but I do not want to use their libraries, I want to understand how to get it working myself. However I have tried to follow their lead and come up with the below, I can say why I am getting no luck though.

My code needs to setup an Output ( Port C, Pin 0 ) , pull the One Wire line low for 480us, setup as an Input, wait 60uS and then read the line. If the line is Low then there is a sensor there, if its High then there is not one ( From my understanding )

I have checked the wiring and the sensor with my Arduino and both seem to be working fine with those standard libraries.

Here is the Output and Input functions :

void ONEWIRE_OUTPUT(GPIO_TypeDef* GPIOx,uint32_t GPIO_Pin)
{
    GPIO_InitTypeDef GPIO_InitStructOUT = {0}; // Holds the pin info.
    GPIO_InitStructOUT.Pin = GPIO_PIN_0;
    GPIO_InitStructOUT.Mode = GPIO_MODE_OUTPUT_PP;
    GPIO_InitStructOUT.Speed = GPIO_SPEED_LOW;

    HAL_GPIO_Init(GPIOC, &GPIO_InitStructOUT);

}

void ONEWIRE_INPUT(GPIO_TypeDef* GPIOx,uint32_t GPIO_Pin)
{

    GPIO_InitTypeDef  gpio_prms = {0};
    gpio_prms.Pin   = GPIO_Pin;
    gpio_prms.Mode  = GPIO_MODE_INPUT;
    gpio_prms.Pull  = GPIO_PULLUP;

    HAL_GPIO_Init(GPIOx, &gpio_prms);
}

The delay I am using to get to uS is the following : I have found how to setup these timers online and I think they are correct but I do not have an oscilloscope with me right now to check if it is outputting that.

void Delay_us(uint16_t delay)
{
    __HAL_TIM_SET_COUNTER(&htim1,0); // set the counter value a 0
    while (__HAL_TIM_GET_COUNTER(&htim1) < delay ); // wait for the counter to reach
}

My Mian loop is as follows :

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

  /* USER CODE END 2 */

  /* Infinite loop */
  /* USER CODE BEGIN WHILE */
  HAL_TIM_Base_Start(&htim1); // Starting timer 1


  int timer_val;

  while (1)
  {
      //Setup as Output
      ONEWIRE_OUTPUT(GPIOC, GPIO_PIN_0);

      // Hold low for 480uS
      HAL_GPIO_WritePin(GPIOC, GPIO_PIN_0, 0);
      Delay_us(480);

      timer_val = __HAL_TIM_GET_COUNTER(&htim1);
      uart_buf_len = sprintf(uart_buf, "%u us -- Should be around 480 us\r\n" , timer_val );
      HAL_UART_Transmit(&huart2, (uint8_t *)uart_buf, uart_buf_len, 100);


      //release and change to INPUT
      ONEWIRE_INPUT(GPIOC, GPIO_PIN_0);

      //wait 60uS
      Delay_us(60);
      //Read, If there is a low - True, else False
      timer_val = __HAL_TIM_GET_COUNTER(&htim1);
      uart_buf_len = sprintf(uart_buf, "%u us -- Should be around 60 us\r\n" , timer_val );
      HAL_UART_Transmit(&huart2, (uint8_t *)uart_buf, uart_buf_len, 100);

      //Update LED
      if ( HAL_GPIO_ReadPin(GPIOC, GPIO_PIN_0) ) {
          HAL_GPIO_WritePin(GPIOB, GPIO_PIN_13, GPIO_PIN_RESET);
      }else
      {
          HAL_GPIO_WritePin(GPIOB, GPIO_PIN_13, GPIO_PIN_SET);
      }
      HAL_Delay(1000);
      // Delay a second

    /* USER CODE END WHILE */

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

I have a feeling it has to do with how to setup the Output and Input specifics but I might be barking up the wrong tree there. I am pretty sure Push Pull is the best Output mode to use in this instance.

My other thought is that I did in fact get the Timer setting wrong, But I have my doubts, I think I have them correct.

I have been able to get a very faint glow on an LED when the pin is in Output mode and then have it blink for an extremely short time while trouble shooting things.

Any ideas would be welcome, I know this code is not pretty, and there are 1000 better ways to do it but this is purely me just messing around and trying to learn things. It was all going great until I got stuck here.

Lastly as this is a new topic any recommendations on where to learn more about STM32 programming would be welcome, I have a few books but will lookup any new reccomrecommended ones.

0 Answers
Related