打印

TIM捕获频率不正确

[复制链接]
6968|13
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
fq1110|  楼主 | 2010-6-22 10:31 | 只看该作者 |只看大图 回帖奖励 |倒序浏览 |阅读模式
TI, ic, se, ST, slave
我的初始化函数与中断函数如下:
void TIM4_Config(void)
{
  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 = TIM_ICPSC_DIV1;
   TIM_ICInitStructure.TIM_ICFilter = 0x0;
   TIM_PWMIConfig(TIM4, &TIM_ICInitStructure);
   /* Select the TIM4 Input Trigger: TI2FP2 */
   TIM_SelectInputTrigger(TIM4, TIM_TS_TI1FP1);
   /* Select the slave Mode: Reset Mode */
   TIM_SelectSlaveMode(TIM4, TIM_SlaveMode_Reset);
   /* Enable the Master/Slave Mode */
   TIM_SelectMasterSlaveMode(TIM4, TIM_MasterSlaveMode_Enable);
   /* TIM enable counter */
   TIM_Cmd(TIM4, ENABLE);
   /* Enable the CC2 Interrupt Request */
   TIM_ITConfig(TIM4, TIM_IT_CC1, ENABLE);
}

void TIM4_IRQHandler(void)
{
  TIM_ClearITPendingBit(TIM4, TIM_IT_CC1);
  IC2Value = TIM_GetCapture1(TIM4);
  if (IC2Value != 0)
  {
    Frequency = 72000000 / IC2Value;
  }
  else
  {
    Frequency = 0;
  }
}
我将PB8直接连上PB6,用定时器发出1000HZ的方波,用示波器检测也已经是1khz。然后TIM4的捕获器捕出来的值经计算后却不是1k,请大家帮我检查一下,是不是我上面的初始化函数有问题?我使用官方提供的例子,也是不正确。谢谢大家。初学者,希望大家帮忙。

d.jpg (8.31 KB )

d.jpg
沙发
香水城| | 2010-6-22 11:07 | 只看该作者
捕获频率不正确?差多少?

使用官方提供的例子时查多少?

你自己的程序与官方提供的例子有什么分别?

使用特权

评论回复
板凳
fq1110|  楼主 | 2010-6-22 11:15 | 只看该作者
香版主:
1、捕获出来频率毫无规律,有时1k多,有时2k多。
2、使用官方的例子也是和上述情况一样。
3、基本按照官方固件库里的例子做的,区别就是官方例子中用的是TIM2的通道2。我用的是TIM4的通道1.还有就是固件库中用的TIM_TS_TI2FP2);我用的是TIM_TS_TI1FP1。其他都是一样的。
这问题困扰很久了,不知从哪下手,还请香版主指导一下。

使用特权

评论回复
地板
fq1110|  楼主 | 2010-6-22 11:45 | 只看该作者
使用官网的例子。
/******************** (C) COPYRIGHT 2008 STMicroelectronics ********************
* File Name          : main.c
* Author             : MCD Application Team
* Version            : V2.0.1
* Date               : 06/13/2008
* Description        : Main program body
********************************************************************************
* 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.
*******************************************************************************/

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

/* Private typedef -----------------------------------------------------------*/
/* Private define ------------------------------------------------------------*/
/* Private macro -------------------------------------------------------------*/
/* Private variables ---------------------------------------------------------*/
TIM_ICInitTypeDef  TIM_ICInitStructure;
ErrorStatus HSEStartUpStatus;

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

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

/*******************************************************************************
* Function Name  : main
* Description    : Main program
* Input          : None
* Output         : None
* Return         : None
*******************************************************************************/
int main(void)
{
#ifdef DEBUG
  debug();
#endif

  /* System Clocks Configuration */
  RCC_Configuration();

  /* NVIC configuration */
  NVIC_Configuration();

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

  /* TIM2 configuration: PWM Input mode ------------------------
     The external signal is connected to TIM2 CH2 pin (PA.01),
     The Rising edge is used as active edge,
     The TIM2 CCR2 is used to compute the frequency value
     The TIM2 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(TIM2, &TIM_ICInitStructure);

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

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

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

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

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

  while (1);
}

/*******************************************************************************
* Function Name  : RCC_Configuration
* Description    : Configures the different system clocks.
* Input          : None
* Output         : None
* Return         : None
*******************************************************************************/
void RCC_Configuration(void)
{
  /* RCC system reset(for debug purpose) */
  RCC_DeInit();

  /* Enable HSE */
  RCC_HSEConfig(RCC_HSE_ON);

  /* Wait till HSE is ready */
  HSEStartUpStatus = RCC_WaitForHSEStartUp();

  if (HSEStartUpStatus == SUCCESS)
  {
    /* Enable Prefetch Buffer */
    FLASH_PrefetchBufferCmd(FLASH_PrefetchBuffer_Enable);

    /* Flash 2 wait state */
    FLASH_SetLatency(FLASH_Latency_2);

    /* HCLK = SYSCLK */
    RCC_HCLKConfig(RCC_SYSCLK_Div1);

    /* PCLK2 = HCLK */
    RCC_PCLK2Config(RCC_HCLK_Div1);

    /* PCLK1 = HCLK/2 */
    RCC_PCLK1Config(RCC_HCLK_Div2);

    /* PLLCLK = 8MHz * 9 = 72 MHz */
    RCC_PLLConfig(RCC_PLLSource_HSE_Div1, RCC_PLLMul_9);

    /* Enable PLL */
    RCC_PLLCmd(ENABLE);

    /* Wait till PLL is ready */
    while (RCC_GetFlagStatus(RCC_FLAG_PLLRDY) == RESET)
    {}

    /* Select PLL as system clock source */
    RCC_SYSCLKConfig(RCC_SYSCLKSource_PLLCLK);

    /* Wait till PLL is used as system clock source */
    while (RCC_GetSYSCLKSource() != 0x08)
    {}
  }

  /* TIM2 clock enable */
  RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE);

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

/*******************************************************************************
* Function Name  : GPIO_Configuration
* Description    : Configure the GPIOD Pins.
* Input          : None
* Output         : None
* Return         : None
*******************************************************************************/
void GPIO_Configuration(void)
{
  GPIO_InitTypeDef GPIO_InitStructure;

  /* TIM2 channel 2 pin (PA.01) configuration */
  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_1;
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;

  GPIO_Init(GPIOA, &GPIO_InitStructure);
}

/*******************************************************************************
* Function Name  : NVIC_Configuration
* Description    : Configure the nested vectored interrupt controller.
* Input          : None
* Output         : None
* Return         : None
*******************************************************************************/
void NVIC_Configuration(void)
{
  NVIC_InitTypeDef NVIC_InitStructure;

#ifdef  VECT_TAB_RAM
  /* Set the Vector Table base location at 0x20000000 */
  NVIC_SetVectorTable(NVIC_VectTab_RAM, 0x0);
#else  /* VECT_TAB_FLASH  */
  /* Set the Vector Table base location at 0x08000000 */
  NVIC_SetVectorTable(NVIC_VectTab_FLASH, 0x0);
#endif

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

#ifdef  DEBUG
/*******************************************************************************
* Function Name  : assert_failed
* Description    : Reports the name of the source file and the source line number
*                  where the assert_param error has occurred.
* Input          : - file: pointer to the source file name
*                  - line: assert_param error line source number
* Output         : None
* Return         : None
*******************************************************************************/
void assert_failed(u8* file, u32 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 2008 STMicroelectronics *****END OF FILE****/
将PB6脚连至PA1脚,产生200HZ方波,采集出来的频率也是错误,并且没有规律,这可能是什么问题啊,希望大家帮我解决一下啊。

使用特权

评论回复
5
fq1110|  楼主 | 2010-6-22 13:27 | 只看该作者
怎么没人帮忙解决一下啊。

使用特权

评论回复
6
fq1110|  楼主 | 2010-6-22 14:17 | 只看该作者
我也有许多平滑滤波的处理,这是只是测了一个数据,从来不曾有一次正确。甚至连相近的数据都没有,我就纳闷了。

使用特权

评论回复
7
香水城| | 2010-6-22 15:53 | 只看该作者
1)目前ST网站上最新的固件库和例子是V3.3.0,而4楼贴出的是V2.0.1,请使用最新版本测试一下。
2)1楼和4楼贴出的程序都不完整,看不出是否有问题。

使用特权

评论回复
8
fq1110|  楼主 | 2010-6-22 16:49 | 只看该作者
谢谢大家的帮助,现在我增加了以下代码
TIM_TimeBaseStructure.TIM_Period = 0xffff;
  TIM_TimeBaseStructure.TIM_Prescaler = 1;
  TIM_TimeBaseStructure.TIM_ClockDivision = 0;
  TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;
  TIM_TimeBaseInit(TIM3, &TIM_TimeBaseStructure);
用的36000000/IC2VALUE,可以正确检测到1k左右频率的方波信号,但有一点疑问就是将TIM_TimeBaseStructure.TIM_Prescaler的1值改为0后,使用72000000/IC2VALUE,数据就不正确
了;毫无规律可言,请问这是什么问题啊?预分频因子一定要大于0吗?

使用特权

评论回复
9
fq1110|  楼主 | 2010-6-22 16:50 | 只看该作者
香版主,我会从网上下载最新的代码再做实验,谢谢你的帮助。

使用特权

评论回复
10
fq1110|  楼主 | 2010-6-22 18:00 | 只看该作者
上面一点有人帮忙解决吗?

使用特权

评论回复
11
香水城| | 2010-6-22 18:03 | 只看该作者
看到10楼的帖,注意到一点,如果TIM的时钟频率为72MHz,则测量1KHz的信号将会使16位的寄存器溢出,估计这是你不能得到正确结果的原因。

请把TIM的时钟频率降低,或把输入信号频率提高到1100Hz以上再试试看。

使用特权

评论回复
12
fq1110|  楼主 | 2010-6-22 20:15 | 只看该作者
谢谢香版主提醒,,如果TIM的时钟频率为72MHz,则测量1KHz的信号将会使16位的寄存器溢出,估计这是你不能得到正确结果的原因。最小频率应该是72m/65535=1098hz,所以1khz小于它,而不能得到正确结果,这样理解对吗?
再请教一点,我上面的如何计算可测量的最大频率呢?

使用特权

评论回复
13
香水城| | 2010-6-23 09:41 | 只看该作者
谢谢香版主提醒,,如果TIM的时钟频率为72MHz,则测量1KHz的信号将会使16位的寄存器溢出,估计这是你不能得到正确结果的原因。最小频率应该是72m/65535=1098hz,所以1khz小于它,而不能得到正确结果,这样理解对吗? ...
fq1110 发表于 2010-6-22 20:15


是的。

可测量的最大频率需要根据你对测量误差的要求而定。测量误差要求高则可测量的最大频率就低;测量误差要求低则可测量的最大频率就高;但最高不会超过72MHz/2。

使用特权

评论回复
14
gxgclg| | 2010-6-23 09:46 | 只看该作者
很可能是你换算有误

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

68

主题

530

帖子

1

粉丝