Parking sensor by using STM32CubeIDE and HC-SR04

Sources : 

1- www.kaynak1.com

2- www.kaynak2.com


The hardwares that I used : 

  1. STM32F103C8
  2. ST-LİNK V2
  3. HC-SR04 ULTRASONIC SENSOR
  4. LCD 16 X 2 



  
 

                          
















      






😀😀😀😀😀😀😀😀😀😀😀😀😀😀😀😀😀😀😀😀😀😀😀

😀😀😀😀😀😀😀😀😀😀😀😀😀😀😀😀😀😀😀😀😀😀😀


main.c file : 


#include "main.h"



#include "i2c-lcd.h"


I2C_HandleTypeDef hi2c1;

TIM_HandleTypeDef htim1;


void SystemClock_Config(void);
static void MX_GPIO_Init(void);
static void MX_I2C1_Init(void);
static void MX_TIM1_Init(void);



void delay (uint16_t time)
{
__HAL_TIM_SET_COUNTER(&htim1, 0);
while (__HAL_TIM_GET_COUNTER (&htim1) < time);
}

uint32_t IC_Val1 = 0;
uint32_t IC_Val2 = 0;
uint32_t Difference = 0;
uint8_t Is_First_Captured = 0;  // is the first value captured ?
uint8_t Distance  = 0;

#define TRIG_PIN GPIO_PIN_9
#define TRIG_PORT GPIOA

// Let's write the callback function

void HAL_TIM_IC_CaptureCallback(TIM_HandleTypeDef *htim)
{
if (htim->Channel == HAL_TIM_ACTIVE_CHANNEL_1)  // if the interrupt source is channel1
{
if (Is_First_Captured==0) // if the first value is not captured
{
IC_Val1 = HAL_TIM_ReadCapturedValue(htim, TIM_CHANNEL_1); // read the first value
Is_First_Captured = 1;  // set the first captured as true
// Now change the polarity to falling edge
__HAL_TIM_SET_CAPTUREPOLARITY(htim, TIM_CHANNEL_1, TIM_INPUTCHANNELPOLARITY_FALLING);
}

else if (Is_First_Captured==1)   // if the first is already captured
{
IC_Val2 = HAL_TIM_ReadCapturedValue(htim, TIM_CHANNEL_1);  // read second value
__HAL_TIM_SET_COUNTER(htim, 0);  // reset the counter

if (IC_Val2 > IC_Val1)
{
Difference = IC_Val2-IC_Val1;
}

else if (IC_Val1 > IC_Val2)
{
Difference = (0xffff - IC_Val1) + IC_Val2;
}

Distance = Difference * .034/2;
Is_First_Captured = 0; // set it back to false

// set polarity to rising edge
__HAL_TIM_SET_CAPTUREPOLARITY(htim, TIM_CHANNEL_1, TIM_INPUTCHANNELPOLARITY_RISING);
__HAL_TIM_DISABLE_IT(&htim1, TIM_IT_CC1);
}
}
}

void HCSR04_Read (void)
{
HAL_GPIO_WritePin(TRIG_PORT, TRIG_PIN, GPIO_PIN_SET);  // pull the TRIG pin HIGH
delay(10);  // wait for 10 us
HAL_GPIO_WritePin(TRIG_PORT, TRIG_PIN, GPIO_PIN_RESET);  // pull the TRIG pin low

__HAL_TIM_ENABLE_IT(&htim1, TIM_IT_CC1);
}



int main(void)
{

  HAL_Init();


  SystemClock_Config();


  MX_GPIO_Init();
  MX_I2C1_Init();
  MX_TIM1_Init();
  /* USER CODE BEGIN 2 */

  lcd_init();
  HAL_TIM_IC_Start_IT(&htim1, TIM_CHANNEL_1);

  lcd_send_string ("Mesafe = ");

  /* USER CODE END 2 */


  while (1)
  {
    /* USER CODE END WHILE */



  HCSR04_Read();
  lcd_send_data((Distance/100) + 48);   // 100th pos
  lcd_send_data(((Distance/10)%10) +48);  // 10th pos
  lcd_send_data((Distance%10)+48);  // 1st pos
  lcd_send_string(" cm");
  HAL_Delay(200);
  }
  /* USER CODE END 3 */
}


void SystemClock_Config(void)
{
  RCC_OscInitTypeDef RCC_OscInitStruct = {0};
  RCC_ClkInitTypeDef RCC_ClkInitStruct = {0};

  /** Initializes the CPU, AHB and APB busses clocks
  */
  RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSE;
  RCC_OscInitStruct.HSEState = RCC_HSE_ON;
  RCC_OscInitStruct.HSEPredivValue = RCC_HSE_PREDIV_DIV1;
  RCC_OscInitStruct.HSIState = RCC_HSI_ON;
  RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;
  RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSE;
  RCC_OscInitStruct.PLL.PLLMUL = RCC_PLL_MUL9;
  if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK)
  {
    Error_Handler();
  }
  /** Initializes the CPU, AHB and APB busses 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_DIV2;
  RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1;

  if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_2) != HAL_OK)
  {
    Error_Handler();
  }
}

/**
  * @brief I2C1 Initialization Function
  * @param None
  * @retval None
  */
static void MX_I2C1_Init(void)
{



  /* USER CODE END I2C1_Init 1 */
  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();
  }
  /* USER CODE BEGIN I2C1_Init 2 */

  /* USER CODE END I2C1_Init 2 */

}


static void MX_TIM1_Init(void)
{


  TIM_MasterConfigTypeDef sMasterConfig = {0};
  TIM_IC_InitTypeDef sConfigIC = {0};


  htim1.Instance = TIM1;
  htim1.Init.Prescaler = 72-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_DISABLE;
  if (HAL_TIM_IC_Init(&htim1) != HAL_OK)
  {
    Error_Handler();
  }
  sMasterConfig.MasterOutputTrigger = TIM_TRGO_RESET;
  sMasterConfig.MasterSlaveMode = TIM_MASTERSLAVEMODE_DISABLE;
  if (HAL_TIMEx_MasterConfigSynchronization(&htim1, &sMasterConfig) != HAL_OK)
  {
    Error_Handler();
  }
  sConfigIC.ICPolarity = TIM_INPUTCHANNELPOLARITY_RISING;
  sConfigIC.ICSelection = TIM_ICSELECTION_DIRECTTI;
  sConfigIC.ICPrescaler = TIM_ICPSC_DIV1;
  sConfigIC.ICFilter = 0;
  if (HAL_TIM_IC_ConfigChannel(&htim1, &sConfigIC, TIM_CHANNEL_1) != HAL_OK)
  {
    Error_Handler();
  }
  /* USER CODE BEGIN TIM1_Init 2 */

  /* USER CODE END TIM1_Init 2 */

}

/**
  * @brief GPIO Initialization Function
  * @param None
  * @retval None
  */
static void MX_GPIO_Init(void)
{
  GPIO_InitTypeDef GPIO_InitStruct = {0};

  /* GPIO Ports Clock Enable */
  __HAL_RCC_GPIOD_CLK_ENABLE();
  __HAL_RCC_GPIOA_CLK_ENABLE();
  __HAL_RCC_GPIOB_CLK_ENABLE();

  /*Configure GPIO pin Output Level */
  HAL_GPIO_WritePin(GPIOA, GPIO_PIN_9, GPIO_PIN_RESET);

  /*Configure GPIO pin : PA9 */
  GPIO_InitStruct.Pin = GPIO_PIN_9;
  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 4 */

/* USER CODE END 4 */

/**
  * @brief  This function is executed in case of error occurrence.
  * @retval None
  */
void Error_Handler(void)
{

}

#ifdef  USE_FULL_ASSERT


void assert_failed(uint8_t *file, uint32_t line)
{

}
#endif /* USE_FULL_ASSERT */

/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/

😀😀😀😀😀😀😀😀😀😀😀😀😀😀😀😀😀😀😀😀😀😀😀

😀😀😀😀😀😀😀😀😀😀😀😀😀😀😀😀😀😀😀😀😀😀😀


i2c-lcd.c file : 

/** Put this in the src folder **/


#include "i2c-lcd.h"

extern I2C_HandleTypeDef hi2c1;  // change your handler here accordingly


#define SLAVE_ADDRESS_LCD 0x4E // change this according to ur setup


void lcd_send_cmd (char cmd)

{

  char data_u, data_l;

uint8_t data_t[4];

data_u = (cmd&0xf0);

data_l = ((cmd<<4)&0xf0);

data_t[0] = data_u|0x0C;  //en=1, rs=0

data_t[1] = data_u|0x08;  //en=0, rs=0

data_t[2] = data_l|0x0C;  //en=1, rs=0

data_t[3] = data_l|0x08;  //en=0, rs=0

HAL_I2C_Master_Transmit (&hi2c1, SLAVE_ADDRESS_LCD,(uint8_t *) data_t, 4, 100);

}


void lcd_send_data (char data)

{

char data_u, data_l;

uint8_t data_t[4];

data_u = (data&0xf0);

data_l = ((data<<4)&0xf0);

data_t[0] = data_u|0x0D;  //en=1, rs=0

data_t[1] = data_u|0x09;  //en=0, rs=0

data_t[2] = data_l|0x0D;  //en=1, rs=0

data_t[3] = data_l|0x09;  //en=0, rs=0

HAL_I2C_Master_Transmit (&hi2c1, SLAVE_ADDRESS_LCD,(uint8_t *) data_t, 4, 100);

}


void lcd_clear (void)

{

lcd_send_cmd (0x80);

for (int i=0; i<70; i++)

{

lcd_send_data (' ');

}

}


void lcd_put_cur(int row, int col)

{

    switch (row)

    {

        case 0:

            col |= 0x80;

            break;

        case 1:

            col |= 0xC0;

            break;

    }


    lcd_send_cmd (col);

}



void lcd_init (void)

{

// 4 bit initialisation

HAL_Delay(50);  // wait for >40ms

lcd_send_cmd (0x30);

HAL_Delay(5);  // wait for >4.1ms

lcd_send_cmd (0x30);

HAL_Delay(1);  // wait for >100us

lcd_send_cmd (0x30);

HAL_Delay(10);

lcd_send_cmd (0x20);  // 4bit mode

HAL_Delay(10);


  // dislay initialisation

lcd_send_cmd (0x28); // Function set --> DL=0 (4 bit mode), N = 1 (2 line display) F = 0 (5x8 characters)

HAL_Delay(1);

lcd_send_cmd (0x08); //Display on/off control --> D=0,C=0, B=0  ---> display off

HAL_Delay(1);

lcd_send_cmd (0x01);  // clear display

HAL_Delay(1);

HAL_Delay(1);

lcd_send_cmd (0x06); //Entry mode set --> I/D = 1 (increment cursor) & S = 0 (no shift)

HAL_Delay(1);

lcd_send_cmd (0x0C); //Display on/off control --> D = 1, C and B = 0. (Cursor and blink, last two bits)

}


void lcd_send_string (char *str)

{

while (*str) lcd_send_data (*str++);

}


😀😀😀😀😀😀😀😀😀😀😀😀😀😀😀😀😀😀😀😀😀😀😀

😀😀😀😀😀😀😀😀😀😀😀😀😀😀😀😀😀😀😀😀😀😀😀


i2c-lcd.h file : 


#include "stm32f1xx_hal.h"


void lcd_init (void);   // initialize lcd


void lcd_send_cmd (char cmd);  // send command to the lcd


void lcd_send_data (char data);  // send data to the lcd


void lcd_send_string (char *str);  // send string to the lcd


void lcd_put_cur(int row, int col);  // put cursor at the entered position row (0 or 1), col (0-15);


void lcd_clear (void);


















Comments

Popular posts from this blog

Interface LCD 16x2 with STM32 by using STM32CubeIDE

LED blinking project with STM32