AnsweredAssumed Answered

STM32F0-Discovery (input capture)

Question asked by Fabio_IT on Jun 10, 2013
Latest reply on Aug 9, 2013 by Lucetti.Walter
Hi everyone!

I'm trying to interface with a HC-SR04 ultrasonic range finder without success...
Briefly I'm initializing two timers, one for generate the 10uS long starting pulse (TRIGGER) and the other to read the pulse duration replied (ECHO). Cause of pin disposition constraints I had to remap some pins.

#include "stm32f0xx.h"
#include <stdio.h>
 
int fputc(int ch, FILE * f) {
  /* Transmit the character using USART1 */
  USART_SendData(USART1, (uint8_t) ch);
 
  /* Wait until transmit finishes */
  while (USART_GetFlagStatus(USART1, USART_FLAG_TXE) == RESET);
 
  return ch;
}
 
/*
  SysTick handler
 */
void SysTick_Handler(void) {
  msTicks++;
}
 
/*
  Function to provide delay (in mSec)
 */
void Delay (uint32_t dlyTicks) {                                             
  uint32_t curTicks;
 
  curTicks = msTicks;
  while ((msTicks - curTicks) < dlyTicks);
}
 
/*
  TIM2 interrupt handler
 */
void TIM2_IRQHandler(void) {
  if (TIM_GetITStatus(TIM2, TIM_IT_Update) != RESET) {
    printf("TIM2 interrupt\r\n");
    printf("SR04: %u %u\r\n", TIM_GetCapture1(TIM1), TIM_GetCapture2(TIM1));
    TIM_ClearITPendingBit(TIM2, TIM_IT_Update);
  }
}
 
/*
  sr04 test
 */
void configureGPIOforTimersSR04(void) {
  GPIO_InitTypeDef GPIO_InitStruct;
   
  // PA8   ------> TIM1_CH1
  // PB4   ------> TIM3_CH1
 
  /*Enable or disable the AHB peripheral clock */
  RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOA|RCC_AHBPeriph_GPIOB, ENABLE);
 
  /*Configure GPIO pin */
  GPIO_InitStruct.GPIO_Pin = GPIO_Pin_8;
  GPIO_InitStruct.GPIO_Mode = GPIO_Mode_AF;
  GPIO_InitStruct.GPIO_OType = GPIO_OType_PP;
  GPIO_InitStruct.GPIO_PuPd = GPIO_PuPd_NOPULL;
  GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz;
  GPIO_Init(GPIOA, &GPIO_InitStruct);
 
  /*Configure GPIO pin alternate function */
  GPIO_PinAFConfig(GPIOA, GPIO_PinSource8, GPIO_AF_2);
   
  /*Configure GPIO pin */
  GPIO_InitStruct.GPIO_Pin = GPIO_Pin_0|GPIO_Pin_1|GPIO_Pin_4;
  GPIO_InitStruct.GPIO_Mode = GPIO_Mode_AF;
  GPIO_InitStruct.GPIO_OType = GPIO_OType_PP;
  GPIO_InitStruct.GPIO_PuPd = GPIO_PuPd_NOPULL;
  GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz;
  GPIO_Init(GPIOB, &GPIO_InitStruct);
   
  /*Configure GPIO pin alternate function */
  GPIO_PinAFConfig(GPIOB, GPIO_PinSource4, GPIO_AF_1);
}
 
void TIM1_Init(void) {
  TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;
  TIM_ICInitTypeDef TIM_ICInitStructure;
 
  // Configure TIM1 prescaler and period
  TIM_TimeBaseStructInit(&TIM_TimeBaseStructure);
  TIM_TimeBaseStructure.TIM_Prescaler = SystemCoreClock/100000 - 1; // 0..479
  TIM_TimeBaseStructure.TIM_Period = 1000 - 1; // 0..999
  TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;
  TIM_TimeBaseInit(TIM1, &TIM_TimeBaseStructure);
 
  // Configure channel 1 to latch the timer on a rising input on t1.
  TIM_ICInitStructure.TIM_Channel = TIM_Channel_1;
  TIM_ICInitStructure.TIM_ICPolarity = TIM_ICPolarity_Rising;
  TIM_ICInitStructure.TIM_ICSelection = TIM_ICSelection_DirectTI;
  TIM_ICInitStructure.TIM_ICPrescaler = 0;
  TIM_ICInitStructure.TIM_ICFilter = 0;
  TIM_ICInit(TIM1, &TIM_ICInitStructure);
 
  // Configure channel 2 to latch the timer on a falling input on t2.
  //TIM_ICInitStructure.TIM_Channel = TIM_Channel_1;
  TIM_ICInitStructure.TIM_ICPolarity = TIM_ICPolarity_Falling;
  TIM_ICInitStructure.TIM_ICSelection = TIM_ICSelection_IndirectTI;
  TIM_ICInitStructure.TIM_ICPrescaler = 0;
  TIM_ICInitStructure.TIM_ICFilter = 0;
  TIM_ICInit(TIM1, &TIM_ICInitStructure);
   
  // Configure TIM1 in slave mode to reset on the capture 1 event.
  TIM_SelectInputTrigger(TIM1, TIM_TS_TI1FP1);
  TIM_SelectSlaveMode(TIM1, TIM_SlaveMode_Reset);
  TIM_SelectMasterSlaveMode(TIM1, TIM_MasterSlaveMode_Enable);
 
  /* enable counter TIM1 */
  TIM_Cmd(TIM1, ENABLE);
}
 
void TIM3_Init(void) {
  uint16_t PrescalerValue = 0;
 
  TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;
  TIM_OCInitTypeDef TIM_OCInitStructure;
 
  /* Compute the prescaler value, scaling to 1MHz */
  PrescalerValue = (uint16_t) (SystemCoreClock / 1000000) - 1;
 
  // enable timer clock
  RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3 , ENABLE);
   
  // configure timer
  TIM_TimeBaseStructInit(&TIM_TimeBaseStructure);
  TIM_TimeBaseStructure.TIM_Prescaler = PrescalerValue; // 1MHz
  TIM_TimeBaseStructure.TIM_Period = 1000 - 1; // 0..999
  TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;
  TIM_TimeBaseInit(TIM3, &TIM_TimeBaseStructure);
 
  // PWM1 Mode configuration: Channel1
  // Edge-aligned; not single pulse mode
  TIM_OCStructInit(&TIM_OCInitStructure);
  //TIM_OCInitStructure.TIM_Channel = TIM_Channel_1;
  TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1;
  TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;
  TIM_OCInitStructure.TIM_Pulse = 10; // Pulse Width 10uS
  TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High;
  TIM_OC2Init(TIM3, &TIM_OCInitStructure);
 
  // Enable Timer
  TIM_Cmd(TIM3, ENABLE);
}
 
void SR04_Init(void) {
  TIM1_Init();
  TIM3_Init();
  configureGPIOforTimersSR04();
}
 
/*
  Function that initializes timer 2
 */
void TIM2_Init(void) {
  uint16_t PrescalerValue = 0;
   
  TIM_TimeBaseInitTypeDef   TIM_TimeBaseStructure;
  TIM_OCInitTypeDef         TIM_OCInitStructure;
  NVIC_InitTypeDef          NVIC_InitStructure;
 
  /* TIM2 clock enable */
  RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE);
 
  TIM_TimeBaseStructInit(&TIM_TimeBaseStructure);
  TIM_OCStructInit(&TIM_OCInitStructure);
 
  /*Compute the prescaler value */
  PrescalerValue = (uint16_t) (SystemCoreClock / 1000) - 1;
 
  /* Time base configuration */
  TIM_TimeBaseStructure.TIM_Period = 1000;      //in mSecs
  TIM_TimeBaseStructure.TIM_Prescaler = PrescalerValue;
  TIM_TimeBaseStructure.TIM_ClockDivision = 0;
  TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;
  TIM_TimeBaseInit(TIM2, &TIM_TimeBaseStructure);
 
  /* Enable the TIM2 gloabal Interrupt */
  NVIC_InitStructure.NVIC_IRQChannel = TIM2_IRQn;
  NVIC_InitStructure.NVIC_IRQChannelPriority = 3;
  NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
  NVIC_Init(&NVIC_InitStructure);
 
  TIM_ITConfig(TIM2, TIM_IT_Update, ENABLE);
  TIM_Cmd(TIM2, ENABLE);
}
 
/*
  USART1 Tx PA.9, Rx PA.10
 */
void USART1_Init(void) {
  USART_InitTypeDef USART_InitStructure;
  GPIO_InitTypeDef GPIO_InitStructure;
  NVIC_InitTypeDef NVIC_InitStructure;
   
  // configuring clock sources for USART1
  RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOA, ENABLE);
  RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1,ENABLE);
 
  GPIO_PinAFConfig(GPIOA, GPIO_PinSource9, GPIO_AF_1);
  GPIO_PinAFConfig(GPIOA, GPIO_PinSource10, GPIO_AF_1);
    
  /* Configure USART1 pins:  Rx and Tx ----------------------------*/
  GPIO_InitStructure.GPIO_Pin =  GPIO_Pin_9 | GPIO_Pin_10;
  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
  GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
  GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;
  GPIO_Init(GPIOA, &GPIO_InitStructure);
  
  /* Enable USART1 IRQ */
  NVIC_InitStructure.NVIC_IRQChannel = USART1_IRQn;
  NVIC_InitStructure.NVIC_IRQChannelPriority = 3;
  NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
  NVIC_Init(&NVIC_InitStructure);
    
  USART_InitStructure.USART_BaudRate = 115200;
  USART_InitStructure.USART_WordLength = USART_WordLength_8b;
  USART_InitStructure.USART_StopBits = USART_StopBits_1;
  USART_InitStructure.USART_Parity = USART_Parity_No;
  USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;
  USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;
  USART_Init(USART1, &USART_InitStructure);
   
  // enabling USART1
  USART_Cmd(USART1,ENABLE);
 
  // enable incoming data interrupt
  USART_ITConfig(USART1, USART_IT_RXNE, ENABLE);
}
 
/*
  Main function
 */
int main(void) {
    SystemCoreClockUpdate();                      /* Get Core Clock Frequency   */
  if (SysTick_Config(SystemCoreClock / 1000)) { /* SysTick 1 msec interrupts  */
    while (1);                                  /* Capture error              */
  }
  TIM2_Init();
  USART1_Init();
  SR04_Init();
 
  printf("STM32F0-Discovery\r\n");
  printf("System core clock: %u Hz\r\n\r\n", SystemCoreClock);
 
  while (1);
}
 
#ifdef  USE_FULL_ASSERT
void assert_failed(uint8_t* file, uint32_t line) {
  while (1) {
  }
}
#endif

Any suggestion will be appreciated!

Almost forgot... sonar trigger is attached to pin PB4, echo to pin PA8

Outcomes