打印
[STM32F1]

STM32F1的定时器1~4的PWM输入捕获

[复制链接]
10967|13
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主

主程序

int main(void)
{
   TIM_Config();
    TIM_PWM_Config();
        
  /* Infinite loop */
  while (1);
}
沙发
mmuuss586|  楼主 | 2014-7-17 13:54 | 只看该作者
定时器1、2、3、4的IO及中断初始化配置程序
定时器一稍微有所区别;
NVIC_InitStructure.NVIC_IRQChannel = TIM1_CC_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);


/**
  * @brief  Configure the TIM IRQ Handler.
  * @param  None
  * @retval None
  */
static void TIM_Config(void)
{
  GPIO_InitTypeDef GPIO_InitStructure;
  NVIC_InitTypeDef NVIC_InitStructure;
  
  /* TIM2 clock enable */
RCC_APB2PeriphClockCmd(RCC_APB2Periph_TIM1, ENABLE);
  RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2|RCC_APB1Periph_TIM3|RCC_APB1Periph_TIM4, ENABLE);
  
  /* GPIOA clock enable */
  RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA |RCC_APB2Periph_GPIOB, ENABLE);
  
  /* TIM2 chennel2 configuration : PA.01 */
  GPIO_InitStructure.GPIO_Pin   = GPIO_Pin_0|GPIO_Pin_6|GPIO_Pin_8;
  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_6;
  GPIO_InitStructure.GPIO_Mode  = GPIO_Mode_IN_FLOATING;  
  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;  
  GPIO_Init(GPIOB, &GPIO_InitStructure);
  /* Enable the TIM2 global Interrupt */
NVIC_InitStructure.NVIC_IRQChannel = TIM1_CC_IRQn;
  NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
  NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
  NVIC_Init(&NVIC_InitStructure);

  NVIC_InitStructure.NVIC_IRQChannel = TIM2_IRQn;
  NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
  NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
  NVIC_Init(&NVIC_InitStructure);

NVIC_InitStructure.NVIC_IRQChannel = TIM3_IRQn;
  NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
  NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
  NVIC_Init(&NVIC_InitStructure);

NVIC_InitStructure.NVIC_IRQChannel = TIM4_IRQn;
  NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
  NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
  NVIC_Init(&NVIC_InitStructure);
}

使用特权

评论回复
板凳
mmuuss586|  楼主 | 2014-7-17 13:54 | 只看该作者
本帖最后由 mmuuss586 于 2014-7-17 13:56 编辑

定时器1、2、3、4的定时器及PWM输入捕获部分配置程序:
定时器初始化最好加上,降低频率后,测试会稳定不少;

static void TIM_PWM_Config(void)
{
TIM_TimeBaseInitTypeDef  TIM_TimeBaseStructure;
  
TIM_TimeBaseStructure.TIM_Period = 50000;   
  TIM_TimeBaseStructure.TIM_Prescaler = 71;           //71+1=72·ÖƵ,F=1M   
  TIM_TimeBaseStructure.TIM_ClockDivision = 0;   
  TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;

TIM_TimeBaseInit(TIM1, &TIM_TimeBaseStructure);
  TIM_TimeBaseInit(TIM2, &TIM_TimeBaseStructure);
TIM_TimeBaseInit(TIM3, &TIM_TimeBaseStructure);
  TIM_TimeBaseInit(TIM4, &TIM_TimeBaseStructure);
  /* ---------------------------------------------------------------------------
    TIM2 configuration: PWM Input mode
     The external signal is connected to TIM2 CH2 pin (PA.01)
     TIM2 CCR2 is used to compute the frequency value
     TIM2 CCR1 is used to compute the duty cycle value
    In this example TIM2 input clock (TIM2CLK) is set to 2*APB1 clock, since
    APB1 prescaler is set to 2.
      TIM2CLK = 2*PCLK1 = HCLK = SystemCoreClock
    External Signal Frequency = SystemCoreClock / TIM2_CCR2 in Hz.
    External Signal DutyCycle = (TIM2_CCR1*100)/(TIM2_CCR2) in %.
  Note:
  SystemCoreClock variable holds HCLK frequency and is defined in system_stm32f1xx.c file.
  Each time the core clock (HCLK) changes, user had to call SystemCoreClockUpdate()
  function to update SystemCoreClock variable value. Otherwise, any configuration
  based on this variable will be incorrect.
  --------------------------------------------------------------------------- */  
  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(TIM1, &TIM_ICInitStructure);
  TIM_PWMIConfig(TIM2, &TIM_ICInitStructure);
TIM_PWMIConfig(TIM3, &TIM_ICInitStructure);
  TIM_PWMIConfig(TIM4, &TIM_ICInitStructure);
  /* Select the TIM1 Input Trigger: TI2FP2 */
TIM_SelectInputTrigger(TIM1, TIM_TS_TI1FP1);
/* Select the slave Mode: Reset Mode */
TIM_SelectSlaveMode(TIM1, TIM_SlaveMode_Reset);
TIM_SelectMasterSlaveMode(TIM1,TIM_MasterSlaveMode_Enable);
/* TIM enable counter */
TIM_Cmd(TIM1, ENABLE);
/* Enable the CC2 Interrupt Request */
TIM_ITConfig(TIM1, TIM_IT_CC1, ENABLE);

   /* Select the TIM2 Input Trigger: TI2FP2 */
TIM_SelectInputTrigger(TIM2, TIM_TS_TI1FP1);
/* Select the slave Mode: Reset Mode */
TIM_SelectSlaveMode(TIM2, TIM_SlaveMode_Reset);
TIM_SelectMasterSlaveMode(TIM2,TIM_MasterSlaveMode_Enable);
/* TIM enable counter */
TIM_Cmd(TIM2, ENABLE);
/* Enable the CC2 Interrupt Request */
TIM_ITConfig(TIM2, TIM_IT_CC1, ENABLE);

   /* Select the TIM2 Input Trigger: TI2FP2 */
TIM_SelectInputTrigger(TIM3, TIM_TS_TI1FP1);
/* Select the slave Mode: Reset Mode */
TIM_SelectSlaveMode(TIM3, TIM_SlaveMode_Reset);
TIM_SelectMasterSlaveMode(TIM3,TIM_MasterSlaveMode_Enable);
/* TIM enable counter */
TIM_Cmd(TIM3, ENABLE);
/* Enable the CC2 Interrupt Request */
TIM_ITConfig(TIM3, TIM_IT_CC1, ENABLE);

/* Select the TIM2 Input Trigger: TI2FP2 */
TIM_SelectInputTrigger(TIM4, TIM_TS_TI1FP1);
/* Select the slave Mode: Reset Mode */
TIM_SelectSlaveMode(TIM4, TIM_SlaveMode_Reset);
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);
}

使用特权

评论回复
地板
mmuuss586|  楼主 | 2014-7-17 13:58 | 只看该作者
中断程序参考官方的修改即可;
/**
  * @brief  This function handles TIM3 global interrupt request.
  * @param  None
  * @retval None
  */
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;
  }
}

使用特权

评论回复
5
joneming| | 2014-12-2 16:24 | 只看该作者
版主:你好,打扰了,我是个新手,我看了你写的那篇《[STM32F1] STM32F1的定时器1~4的PWM输入捕获》,我想用stm32f1的PB13管脚的Tim1的ch1n来PWM输入捕获,这个PB13与你文中使用PA8的Tim1的ch1,仅仅只是在配置管脚时用PB13代替PA8就可以了么?还是有其它地方需要修改呀?

使用特权

评论回复
6
570wql570| | 2015-4-10 21:02 | 只看该作者
楼主大哥,我用 通用定时器做PWM输入捕获,完全没有问题。但是,用高级定时器TIM1做就不对了,用串口助手打印出来都是乱码,波特率可以确定说设置对了的。求指导...

QQ图片20150410205912.png (43.29 KB )

TIM1配置

TIM1配置

QQ图片20150410210329.png (24.08 KB )

串口助手打印乱码

串口助手打印乱码

使用特权

评论回复
7
570wql570| | 2015-4-10 21:04 | 只看该作者
用通用定时器完全正确...

QQ图片20150410210557.png (19.5 KB )

QQ图片20150410210557.png

使用特权

评论回复
8
570wql570| | 2015-4-10 21:17 | 只看该作者
楼主大哥,急求啊...

使用特权

评论回复
9
钢铁侠| | 2015-7-29 09:48 | 只看该作者
joneming 发表于 2014-12-2 16:24
版主:你好,打扰了,我是个新手,我看了你写的那篇《[STM32F1] STM32F1的定时器1~4的PWM输入捕获》,我想 ...

同问,如果我需要用到timer1中的CH1N通道,是否初始化的时候和配置CH1一样的只需修改GPIO端口就可以了,就是直接将PA.8直接换成PB.13就可以了呢

使用特权

评论回复
10
andypanfan| | 2016-1-6 22:36 | 只看该作者
LZ  解决了  没有  一样的问题呀  !!求指导!!

使用特权

评论回复
11
Demon、Yang| | 2017-6-22 11:34 | 只看该作者
570wql570 发表于 2015-4-10 21:04
用通用定时器完全正确...

同问,通用定时器可以使用  TIM1就不行了,四个通道的数值就乱了,求解决办法。

使用特权

评论回复
12
Demon、Yang| | 2017-6-22 11:35 | 只看该作者
570wql570 发表于 2015-4-10 21:04
用通用定时器完全正确...

同问,通用定时器可以使用  TIM1就不行了,四个通道的数值就乱了,求解决办法。

使用特权

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

本版积分规则

个人签名:欢迎进入21IC论坛 游名科技:提供直流无刷电机驱动整体解决方案

696

主题

32677

帖子

441

粉丝