cancel
Showing results for 
Search instead for 
Did you mean: 

STM32F103 Input PWM capture signal with different width

AlexC
Visitor

Hi, I tried to read signal from ultrasonic parking unit by capturing PWM input. Signal has one start pulse 530 Hz width (1.87 ms) and a sequence with 0 and 1 (9.942 kHz and 4,97 kHz) period between pulses sequences is about 193 ms.

AlexC_0-1741091416656.png

I use STM32F103 blue pill board with external 8Mhz quartz oscillator.

AlexC_1-1741091778061.png

My clock config:

 

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

  /** Initializes the RCC Oscillators according to the specified parameters
  * in the RCC_OscInitTypeDef structure.
  */
  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 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_DIV2;
  RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1;

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

 

My Timer configuration:

 

static void MX_TIM3_Init(void)
{

  /* USER CODE BEGIN TIM3_Init 0 */

  /* USER CODE END TIM3_Init 0 */

  TIM_ClockConfigTypeDef sClockSourceConfig = {0};
  TIM_SlaveConfigTypeDef sSlaveConfig = {0};
  TIM_IC_InitTypeDef sConfigIC = {0};
  TIM_MasterConfigTypeDef sMasterConfig = {0};

  /* USER CODE BEGIN TIM3_Init 1 */

  /* USER CODE END TIM3_Init 1 */
  htim3.Instance = TIM3;
  htim3.Init.Prescaler = 0;
  htim3.Init.CounterMode = TIM_COUNTERMODE_UP;
  htim3.Init.Period = 65535;
  htim3.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1;
  htim3.Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_DISABLE;
  if (HAL_TIM_Base_Init(&htim3) != HAL_OK)
  {
    Error_Handler();
  }
  sClockSourceConfig.ClockSource = TIM_CLOCKSOURCE_INTERNAL;
  if (HAL_TIM_ConfigClockSource(&htim3, &sClockSourceConfig) != HAL_OK)
  {
    Error_Handler();
  }
  if (HAL_TIM_IC_Init(&htim3) != HAL_OK)
  {
    Error_Handler();
  }
  sSlaveConfig.SlaveMode = TIM_SLAVEMODE_RESET;
  sSlaveConfig.InputTrigger = TIM_TS_TI1FP1;
  sSlaveConfig.TriggerPolarity = TIM_INPUTCHANNELPOLARITY_RISING;
  sSlaveConfig.TriggerPrescaler = TIM_ICPSC_DIV1;
  sSlaveConfig.TriggerFilter = 0;
  if (HAL_TIM_SlaveConfigSynchro(&htim3, &sSlaveConfig) != 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(&htim3, &sConfigIC, TIM_CHANNEL_1) != HAL_OK)
  {
    Error_Handler();
  }
  sConfigIC.ICPolarity = TIM_INPUTCHANNELPOLARITY_FALLING;
  sConfigIC.ICSelection = TIM_ICSELECTION_INDIRECTTI;
  if (HAL_TIM_IC_ConfigChannel(&htim3, &sConfigIC, TIM_CHANNEL_2) != HAL_OK)
  {
    Error_Handler();
  }
  sMasterConfig.MasterOutputTrigger = TIM_TRGO_RESET;
  sMasterConfig.MasterSlaveMode = TIM_MASTERSLAVEMODE_DISABLE;
  if (HAL_TIMEx_MasterConfigSynchronization(&htim3, &sMasterConfig) != HAL_OK)
  {
    Error_Handler();
  }
  /* USER CODE BEGIN TIM3_Init 2 */
  HAL_TIM_IC_Start_IT(&htim3, TIM_CHANNEL_2);
  /* USER CODE END TIM3_Init 2 */

}

 

Capture callback:

 

#define RADAR_FRONT_START_PULSE 18000	// Hz
#define RADAR_REAR_START_PULSE 19000	// Hz
#define RADAR_HIGH_PULSE 5000			// Hz
#define RADAR_LOW_PULSE 10000			// Hz
#define RADAR_PULSE_DEVIATION 2000		// Hz

void HAL_TIM_IC_CaptureCallback(TIM_HandleTypeDef *htim)
{
	if (!CHECK_RADAR_ON) return;


	if(htim -> Instance == TIM3 && htim -> Channel == HAL_TIM_ACTIVE_CHANNEL_2)
	{
		HandleRearRadarPulses(htim);
	}
	if(htim -> Instance == TIM2 && htim -> Channel == HAL_TIM_ACTIVE_CHANNEL_2)
	{
		HandleFrontRadarPulses(htim);
	}
}
void HandleRearRadarPulses(TIM_HandleTypeDef *htim)
{
	static int8_t 		index = 32;
	static int8_t 		start_cpatured = 0;
	static uint32_t 	captured_pulses = 0;
	uint16_t 			packet = 0;
	uint32_t 			pulse = 0;

	pulse = SystemCoreClock / (HAL_TIM_ReadCapturedValue(htim, TIM_CHANNEL_2));
	if (IS_REAR_START_PULSE(pulse))
	{
		start_cpatured = 1;
		index = 32;
		HAL_GPIO_WritePin(GPIOB, GPIO_PIN_10, GPIO_PIN_SET);
		return;
	}
	if (start_cpatured){
		if (IS_HIGH_PULSE(pulse)) captured_pulses |= (1 << index);

		if (index == 0) {
			rear_min_distance = 255;
			for (int i=0; i<4; i+=1) {
				packet = (captured_pulses & (255 << (RADAR_PACKET_LENGTH * i))) >> (RADAR_PACKET_LENGTH * i);
				rear_sensors[i] = packet;
				if (packet < rear_min_distance) rear_min_distance = packet;
			}
			captured_pulses = 0;
			start_cpatured = 0;
			HAL_GPIO_WritePin(GPIOB, GPIO_PIN_10, GPIO_PIN_RESET);
		}
		index --;
	}
}

 

Main problem is to catch start pulse on this config. To work as expected I used to reduce width of start pulse from 530 Hz to 19 kHz to be able to catch it. For example, using timer on black pill STM32F4 with 32 bit AutoRload Register start pulse was captured with 530 Hz.
To detect correct package detection I also set pin state once start pulse was captured and reset after complete package reception.

AlexC_2-1741092707594.png

Is it possible to catch such kind of signals with 16 bit Counter Period (AutoRload Register) with correct start pulse width (530 Hz) or problem with different thing?
If I correctly understand that first pulse tried to capture 2 times because of its width 1.87 ms, as timer capture period is about 0.9 ms (Counter_Period / F clock -> 65535 / 72 Mhz = 0.9 ms).

Thanks in advice! 

1 REPLY 1
AScha.3
Chief III

Hi,

>Is it possible to catch such kind of signals with 16 bit Counter Period (AutoRload Register) with correct start pulse width (530 Hz) or problem with different thing?

Yes, no problem. Just use prescaler, maybe :71 , to set the timer to count on 1us clock.

Then 65k gives a range up to 65ms to captureand still good resolution to check 100 or 200 us long pulse coming.

If you feel a post has answered your question, please click "Accept as Solution".