input capture

Başlatan muhittin_kaplan, 16 Eylül 2013, 18:26:23

muhittin_kaplan

Ultrasonic Sensör Ulaştı ELime, Çalışmasına baktım,
10us lik bir puls verdikten sonra echo çıkışından size uzaklıkla doğru orantılı Mantık 1 e çekilmiş sinyal gönderiyor.
STM32 ile input capture örneklerini inceledim. (input PWM leride inceledim.) kendi örneğindeki aşağıdaki örnek input PWM ve açıklamasında demişki "feq ve duty" verir.

 
TIM_ICInitStructure.TIM_Channel = TIM_Channel_2;
  TIM_ICInitStructure.TIM_ICPolarity = TIM_ICPolarity_Rising;
  TIM_ICInitStructure.TIM_ICSelection = TIM_ICSelection_DirectTI;
  TIM_ICInitStructure.TIM_ICPrescaler = TIM_ICPSC_DIV1;
  TIM_ICInitStructure.TIM_ICFilter = 0x0;

  TIM_PWMIConfig(TIM3, &TIM_ICInitStructure);

  /* Select the TIM3 Input Trigger: TI2FP2 */
  TIM_SelectInputTrigger(TIM3, TIM_TS_TI2FP2);

  /* Select the slave Mode: Reset Mode */
  TIM_SelectSlaveMode(TIM3, TIM_SlaveMode_Reset);

  /* Enable the Master/Slave Mode */
  TIM_SelectMasterSlaveMode(TIM3, TIM_MasterSlaveMode_Enable);

  /* TIM enable counter */
  TIM_Cmd(TIM3, ENABLE);

  /* Enable the CC2 Interrupt Request */
  TIM_ITConfig(TIM3, TIM_IT_CC2, ENABLE);


anlamadığım şu Sadece yükselen kenarda tetiklenirse Duty yi nasıl bulur ?
  TIM_ICInitStructure.TIM_ICPolarity = TIM_ICPolarity_Rising;

Klein

oradaki polarite counter reset için gereken polarite.
Eğer düşen kenara ayarlarsan  ilk düşen kenarda  sayıcı sıfırlanır. Yükselen kenarda darbe genişliği bayrağı çekilir. diğer düşen kenarda tekrar sayıcı sıfırlanır.

muhittin_kaplan

void TIM3_IRQHandler(void)
{
  /* Clear TIM3 Capture compare interrupt pending bit */
  TIM_ClearITPendingBit(TIM3, TIM_IT_CC2);

  /* Get the Input Capture value */
  IC2Value = TIM_GetCapture2(TIM3);

  if (IC2Value != 0)
  {
    /* Duty cycle computation */
    DutyCycle = (TIM_GetCapture1(TIM3) * 100) / IC2Value;

    /* Frequency computation */
    Frequency = SystemCoreClock / IC2Value;
  }
  else
  {
    DutyCycle = 0;
    Frequency = 0;
  }

}


muhittin_kaplan

inceledim hocam, ama kütüphaneyle yapmak istedim.

Klein

#5
Örneğin linkini verme nedenim periyot ve darbe genişliğini ayrı registerlerden alabileceğini gösternmek içindi.
oid TIM2_IRQHandler(){
    ccr1=TIM2->CCR1; // periyot
    ccr2=TIM2->CCR2; // darbe genişliği
TIM2->SR=0;   


mesaj birleştirme:: 16 Eylül 2013, 18:55:05

hmm. sen de ayrı gregisterlerden almışsın. hesabı görünce hesaplayarak buldun diye düşündüm.

muhittin_kaplan

/* Clear TIM3 Capture compare interrupt pending bit */
  TIM_ClearITPendingBit(TIM3, TIM_IT_CC2);

  /* Get the Input Capture value */
  IC2Value = TIM_GetCapture2(TIM3);

  if (IC2Value != 0)
  {
    /* Duty cycle computation */
    DutyCycle = (TIM_GetCapture1(TIM3) * 100) / IC2Value;

    /* Frequency computation */
    Frequency = SystemCoreClock / IC2Value;
  }
  else
  {
    DutyCycle = 0;
    Frequency = 0;
  }

}


Hocam Yukarda da aynısını Yapıyor.
  IC2Value = TIM_GetCapture2(TIM3); ile CCR2
TIM_GetCapture1(TIM3) ile CCR1 i alıyor. ama her ne hikmetse her defasında farklı sonuç çıkıyor.

Klein

CM3 ile hiç denemedim ama STM32F4 kiti üzerinde denemiştim. Çok düzgün sonuçlar aldım. Kendi filtresi olduğu için bu güne kadar çalıştığım IC modülleri içinde en iyisiydi.

muhittin_kaplan

/**
  ******************************************************************************
  * @file    TIM/PWM_Input/main.c
  * @author  MCD Application Team
  * @version V3.5.0
  * @date    08-April-2011
  * @brief   Main program body
  ******************************************************************************
  * @attention
  *
  * THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS
  * WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE
  * TIME. AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY
  * DIRECT, INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING
  * FROM THE CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE
  * CODING INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS.
  *
  * <h2><center>&copy; COPYRIGHT 2011 STMicroelectronics</center></h2>
  ******************************************************************************
  */

/* Includes ------------------------------------------------------------------*/
#include "stm32f10x.h"

/** @addtogroup STM32F10x_StdPeriph_Examples
  * @{
  */

/** @addtogroup TIM_PWM_Input
  * @{
  */

/* Private typedef -----------------------------------------------------------*/
/* Private define ------------------------------------------------------------*/
/* Private macro -------------------------------------------------------------*/
/* Private variables ---------------------------------------------------------*/


/* Private function prototypes -----------------------------------------------*/
void RCC_Configuration(void);
void GPIO_Configuration(void);
void NVIC_Configuration(void);

/* Private functions ---------------------------------------------------------*/




/**
  * @brief   Main program
  * @param  None
  * @retval None
  */


GPIO_InitTypeDef GPIO_InitStructure;
TIM_ICInitTypeDef  TIM_ICInitStructure;



int IC2Value = 0;
int DutyCycle = 0;
int Frequency = 0;


void TIM3_IRQHandler(void)
{
  /* Clear TIM3 Capture compare interrupt pending bit */
  TIM_ClearITPendingBit(TIM3, TIM_IT_CC2);

  /* Get the Input Capture value */
  IC2Value = TIM_GetCapture2(TIM3);

  if (IC2Value != 0)
  {
    /* Duty cycle computation */
    DutyCycle = (TIM_GetCapture1(TIM3) * 100) / IC2Value;

    /* Frequency computation */
    Frequency = SystemCoreClock / IC2Value;
  }
  else
  {
    DutyCycle = 0;
    Frequency = 0;
  }

}




int main(void)
{
  /*!< At this stage the microcontroller clock setting is already configured,
       this is done through SystemInit() function which is called from startup
       file (startup_stm32f10x_xx.s) before to branch to application main.
       To reconfigure the default setting of SystemInit() function, refer to
       system_stm32f10x.c file
     */

SystemInit();
  /* System Clocks Configuration */
  RCC_Configuration();

  /* NVIC configuration */
  NVIC_Configuration();

  /* Configure the GPIO ports */
  GPIO_Configuration();

  /* TIM3 configuration: PWM Input mode ------------------------
     The external signal is connected to TIM3 CH2 pin (PA.01),
     The Rising edge is used as active edge,
     The TIM3 CCR2 is used to compute the frequency value
     The TIM3 CCR1 is used to compute the duty cycle value
  ------------------------------------------------------------ */

  TIM_ICInitStructure.TIM_Channel = TIM_Channel_2;
  TIM_ICInitStructure.TIM_ICPolarity = TIM_ICPolarity_Rising;
  TIM_ICInitStructure.TIM_ICSelection = TIM_ICSelection_DirectTI;
  TIM_ICInitStructure.TIM_ICPrescaler = TIM_ICPSC_DIV1;
  TIM_ICInitStructure.TIM_ICFilter = 0x0;

  TIM_PWMIConfig(TIM3, &TIM_ICInitStructure);

  /* Select the TIM3 Input Trigger: TI2FP2 */
  TIM_SelectInputTrigger(TIM3, TIM_TS_TI2FP2);

  /* Select the slave Mode: Reset Mode */
  TIM_SelectSlaveMode(TIM3, TIM_SlaveMode_Reset);

  /* Enable the Master/Slave Mode */
  TIM_SelectMasterSlaveMode(TIM3, TIM_MasterSlaveMode_Enable);

  /* TIM enable counter */
  TIM_Cmd(TIM3, ENABLE);

  /* Enable the CC2 Interrupt Request */
  TIM_ITConfig(TIM3, TIM_IT_CC2, ENABLE);


  while (1){
	  int z;
	    GPIO_SetBits(GPIOC,GPIO_Pin_8);
		for (z = 0; z < 0x0000015; ++z) {

		}
	    GPIO_ResetBits(GPIOC,GPIO_Pin_8);
		for (z = 0; z < 0x00000015; ++z) {

		}
	  }
}

/**
  * @brief  Configures the different system clocks.
  * @param  None
  * @retval None
  */
void RCC_Configuration(void)
{
  /* TIM3 clock enable */
  RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3, ENABLE);

  /* GPIOA clock enable */
  RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);
  RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC, ENABLE);
}

/**
  * @brief  Configure the GPIO Pins.
  * @param  None
  * @retval None
  */
void GPIO_Configuration(void)
{


  /* TIM3 channel 2 pin (PA.07) configuration */
  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_7;
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;

  GPIO_Init(GPIOA, &GPIO_InitStructure);


  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_8;
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;

  GPIO_Init(GPIOC, &GPIO_InitStructure);
}

/**
  * @brief  Configure the nested vectored interrupt controller.
  * @param  None
  * @retval None
  */
void NVIC_Configuration(void)
{
  NVIC_InitTypeDef NVIC_InitStructure;

  /* Enable the TIM3 global Interrupt */
  NVIC_InitStructure.NVIC_IRQChannel = TIM3_IRQn;
  NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
  NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;
  NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
  NVIC_Init(&NVIC_InitStructure);
}

#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 can add his own implementation to report the file name and line number,
     ex: printf("Wrong parameters value: file %s on line %d\r\n", file, line) */

  while (1)
  {}
}

#endif

/**
  * @}
  */

/**
  * @}
  */

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


kodlar bunlar, GPIOC.8 den sinyl çıkışı yaptım onu GPIOA.7 ye bağladım. Debug ettiğimde anlamsız degerler alıyorum.

muhittin_kaplan

Denemediğim Yöntem Kalmadı. Olmuyor Debug Anında CCR1 ve CCR2 (yada
TIM_GetCapture2(TIM2)
TIM_GetCapture1(TIM2)

den dogru dürüst bilgi alamıyorum. Acaba Debug yapmamdan kaynaklanıyor olabilir mi ? USartla PC yemi Göndersem.

Klein

PWM modül kullanarak sinyal çıkışı sağlamayı bir dener misin?
CCP1 ve CCP2  yakalandığında ayrı ayrı kesme üretiyorlarsa ( datasheet'e bakmaya üşendim)
Pending bitini hemen sıfırlama.
kesmenin hangi kaynaktan geldiğine bak.  Kesme kaynağına göre hangi işlemi yapman gerekiyorsa onu yap. Ondan sonra pending bitini sıfırla.

muhittin_kaplan

hocam onuda denedim,
başka bir timer la PWM ürettim, capture yapmaya çalıştım yine aynı anlamsız değerler aldım.

Klein

Şimdilik Debug modu suçlu gibi duruyor. Bir de veriyi seri porttan basmayı dene. Eğer yine olmazsa, fırsat bulunca ben de deneyeyim.

muhittin_kaplan

akşam usarttan basacağım değerleri. bakalım ne olacak.
(debug modda timer lar duruyor mu breakpoint koyunca ?)

Klein

Sebebini anlayamadığım bir sorun olmadığı sürece Debug moda pek girmiyorum. Bu yüzden timer davranışları konusunda fikrim yok.