野火电子论坛

 找回密码
 注册

QQ登录

只需一步,快速开始

查看: 13194|回复: 1

一个关于定时器输入捕获的问题

[复制链接]
发表于 2017-1-23 12:15:30 | 显示全部楼层 |阅读模式
设置通用定时器3进行4路PWM输出,高级定时器8通道1捕获任意一路PWM并且显示在串口上,捕获部分程序和火哥视频教程完全一样(除了GPIO端口不同),但在串口上显示的捕获值却随着高级定时器时基结构体周期的设置变化,而且测得的结果完全不合理!代码有点长,求大神帮看看,感激不尽

general_tim.h文件
#ifndef __GENERAL_TIM_H
#define __GENERAL_TIM_H
#include "stm32f4xx.h"
//通用定时器外设宏定义
#define           GENERAL_TIM                   TIM3
#define           GENERAL_TIM_CLK               RCC_APB1Periph_TIM3
#define           GENERAL_TIM_Period            1999
#define           GENERAL_TIM_Prescaler         899     

// TIM3 输出比较通道1
#define            GENERAL_TIM_CH1_GPIO_CLK      RCC_AHB1Periph_GPIOC
#define            GENERAL_TIM_CH1_PORT          GPIOC
#define            GENERAL_TIM_CH1_PIN           GPIO_Pin_6
#define            GENERAL_TIM_CH1_PINSOURCE   GPIO_PinSource6
#define            GENERAL_TIM_CH1_AF       GPIO_AF_TIM3
// TIM3 输出比较通道2
#define            GENERAL_TIM_CH2_GPIO_CLK      RCC_AHB1Periph_GPIOC
#define            GENERAL_TIM_CH2_PORT          GPIOC
#define            GENERAL_TIM_CH2_PIN           GPIO_Pin_7
#define            GENERAL_TIM_CH2_PINSOURCE   GPIO_PinSource7
#define            GENERAL_TIM_CH2_AF       GPIO_AF_TIM3
// TIM3 输出比较通道3
#define            GENERAL_TIM_CH3_GPIO_CLK      RCC_AHB1Periph_GPIOC
#define            GENERAL_TIM_CH3_PORT          GPIOC
#define            GENERAL_TIM_CH3_PIN           GPIO_Pin_8
#define            GENERAL_TIM_CH3_PINSOURCE   GPIO_PinSource8
#define            GENERAL_TIM_CH3_AF       GPIO_AF_TIM3
// TIM3 输出比较通道4
#define            GENERAL_TIM_CH4_GPIO_CLK      RCC_AHB1Periph_GPIOC
#define            GENERAL_TIM_CH4_PORT          GPIOC
#define            GENERAL_TIM_CH4_PIN           GPIO_Pin_9
#define            GENERAL_TIM_CH4_PINSOURCE   GPIO_PinSource9
#define            GENERAL_TIM_CH4_AF       GPIO_AF_TIM3
void GTIMx_Init(void);
#endif


general_tim.c文件
#include "general_tim.h"

//通用定时器GPIO引脚配置
static void GTIMx_GPIO_Config(void)
{
  //定义一个GPIO_InitTypeDef类型的结构体
GPIO_InitTypeDef GPIO_InitStructure;
//使能通用定时器四个通道的GPIO时钟
RCC_AHB1PeriphClockCmd (GENERAL_TIM_CH1_GPIO_CLK|GENERAL_TIM_CH2_GPIO_CLK|GENERAL_TIM_CH3_GPIO_CLK|GENERAL_TIM_CH4_GPIO_CLK,ENABLE);

//定时器复用引脚
GPIO_PinAFConfig(GENERAL_TIM_CH1_PORT,GENERAL_TIM_CH1_PINSOURCE,GENERAL_TIM_CH1_AF);
GPIO_PinAFConfig(GENERAL_TIM_CH2_PORT,GENERAL_TIM_CH2_PINSOURCE,GENERAL_TIM_CH2_AF);
GPIO_PinAFConfig(GENERAL_TIM_CH3_PORT,GENERAL_TIM_CH3_PINSOURCE,GENERAL_TIM_CH3_AF);
GPIO_PinAFConfig(GENERAL_TIM_CH4_PORT,GENERAL_TIM_CH4_PINSOURCE,GENERAL_TIM_CH4_AF);

//通用定时器PWM输出引脚配置                 
GPIO_InitStructure.GPIO_Pin = GENERAL_TIM_CH1_PIN;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;   
GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;
GPIO_Init(GENERAL_TIM_CH1_PORT, &GPIO_InitStructure);

GPIO_InitStructure.GPIO_Pin = GENERAL_TIM_CH2_PIN;
GPIO_Init(GENERAL_TIM_CH2_PORT, &GPIO_InitStructure);

GPIO_InitStructure.GPIO_Pin = GENERAL_TIM_CH3_PIN;
GPIO_Init(GENERAL_TIM_CH3_PORT, &GPIO_InitStructure);

GPIO_InitStructure.GPIO_Pin = GENERAL_TIM_CH4_PIN;
GPIO_Init(GENERAL_TIM_CH4_PORT, &GPIO_InitStructure);
}

//通用定时器模式配置
static void GTIMx_Mode_Config(void)
{
  // 开启定时器时钟,即内部时钟CK_INT=90M
RCC_APB1PeriphClockCmd(GENERAL_TIM_CLK,ENABLE);
  //时基结构体声明及输出比较结构体声明
  TIM_TimeBaseInitTypeDef  TIM_TimeBaseStructure;
TIM_OCInitTypeDef        TIM_OCInitStructure;

//时基结构体初始化
// 自动重装载寄存器的值,累计TIM_Period+1个频率后产生一个更新或者中断,这里配置频率为50Hz
TIM_TimeBaseStructure.TIM_Period=1999;
// 驱动CNT计数器的时钟 = Fck_int/(psc+1)
TIM_TimeBaseStructure.TIM_Prescaler= 899;
// 时钟分频因子 ,配置死区时间时需要用到
TIM_TimeBaseStructure.TIM_ClockDivision=TIM_CKD_DIV1;  
// 计数器计数模式,设置为向上计数
TIM_TimeBaseStructure.TIM_CounterMode=TIM_CounterMode_Up;
// 重复计数器的值,没用到不用管
//TIM_TimeBaseStructure.TIM_RepetitionCounter=0;
// 初始化定时器
TIM_TimeBaseInit(GENERAL_TIM, &TIM_TimeBaseStructure);

//通用定时器输出比较结构体初始化
// 占空比配置
uint16_t CCR1_Val = 150;
uint16_t CCR2_Val = 200;
uint16_t CCR3_Val = 250;
uint16_t CCR4_Val = 300;


// 配置为PWM模式1
TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1;
// 输出使能
TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;
// 输出通道电平极性配置
TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High;

// 输出比较通道 1
//TIM_OCInitStructure.TIM_Pulse = CCR1_Val;
TIM_OC1Init(GENERAL_TIM, &TIM_OCInitStructure);
TIM_OC1PreloadConfig(GENERAL_TIM, TIM_OCPreload_Enable);

// 输出比较通道 2
//TIM_OCInitStructure.TIM_Pulse = CCR2_Val;
TIM_OC2Init(GENERAL_TIM, &TIM_OCInitStructure);
TIM_OC2PreloadConfig(GENERAL_TIM, TIM_OCPreload_Enable);

// 输出比较通道 3
TIM_OCInitStructure.TIM_Pulse = CCR3_Val;
TIM_OC3Init(GENERAL_TIM, &TIM_OCInitStructure);
TIM_OC3PreloadConfig(GENERAL_TIM, TIM_OCPreload_Enable);

// 输出比较通道 4
TIM_OCInitStructure.TIM_Pulse = CCR4_Val;
TIM_OC4Init(GENERAL_TIM, &TIM_OCInitStructure);
TIM_OC4PreloadConfig(GENERAL_TIM, TIM_OCPreload_Enable);

// 使能计数器
TIM_Cmd(GENERAL_TIM, ENABLE);
}

//通用定时器初始化函数
void GTIMx_Init(void)
{
GTIMx_GPIO_Config();
GTIMx_Mode_Config();  
}


advance_tim.h文件
#ifndef __ADVANCE_TIM_H
#define __ADVANCE_TIM_H
#include "stm32f4xx.h"
/* 高级控制定时器PWM输入捕获 */
/* PWM输入捕获引脚 */
#define ADVANCE_ICPWM_PIN             GPIO_Pin_5           
#define ADVANCE_ICPWM_GPIO_PORT       GPIOI               
#define ADVANCE_ICPWM_GPIO_CLK        RCC_AHB1Periph_GPIOI
#define ADVANCE_ICPWM_PINSOURCE    GPIO_PinSource5
#define ADVANCE_ICPWM_AF       GPIO_AF_TIM8
#define ADVANCE_IC1PWM_CHANNEL        TIM_Channel_1
#define ADVANCE_IC2PWM_CHANNEL        TIM_Channel_2
/* 高级控制定时器 */
#define ADVANCE_TIM                 TIM8
#define ADVANCE_TIM_CLK             RCC_APB2Periph_TIM8
/* 捕获/比较中断 */
#define ADVANCE_TIM_IRQn         TIM8_CC_IRQn
#define ADVANCE_TIM_IRQHandler        TIM8_CC_IRQHandler

void ATIMx_Init(void);
#endif


advance_tim.c文件
#include "advance_tim.h"
//高级定时器GPIO配置函数
static void ATIMx_GPIO_Config(void)
{
//定义一个GPIO_InitTypeDef类型的结构体
GPIO_InitTypeDef GPIO_InitStructure;
//开启定时器相关的GPIO外设时钟
RCC_AHB1PeriphClockCmd (ADVANCE_ICPWM_GPIO_CLK, ENABLE);  
//定时器复用引脚
GPIO_PinAFConfig(ADVANCE_ICPWM_GPIO_PORT,ADVANCE_ICPWM_PINSOURCE,ADVANCE_ICPWM_AF);

//高级定时器PWM输入捕获引脚配置                  
GPIO_InitStructure.GPIO_Pin = ADVANCE_ICPWM_PIN;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;   
GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;
GPIO_Init(ADVANCE_ICPWM_GPIO_PORT, &GPIO_InitStructure);
}

//定时器中断优先级配置函数
static void TIMx_NVIC_Configuration(void)
{
    NVIC_InitTypeDef NVIC_InitStructure;
    // 设置中断组为0
    NVIC_PriorityGroupConfig(NVIC_PriorityGroup_0);  
  // 设置中断来源
    NVIC_InitStructure.NVIC_IRQChannel = ADVANCE_TIM_IRQn;  
  // 设置抢占优先级
    NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;  
   // 设置子优先级
    NVIC_InitStructure.NVIC_IRQChannelSubPriority = 3;
    NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
    NVIC_Init(&NVIC_InitStructure);
}


//高级定时器模式配置函数
static void ATIMx_Mode_Config(void)
{
TIM_TimeBaseInitTypeDef  TIM_TimeBaseStructure;
TIM_ICInitTypeDef  TIM_ICInitStructure;

// 开启TIMx_CLK,x[1,8]
  RCC_APB2PeriphClockCmd(ADVANCE_TIM_CLK, ENABLE);
  TIM_TimeBaseStructure.TIM_Period = 0xFFFF-1;  
// 高级控制定时器时钟源TIMxCLK = HCLK=180MHz
// 设定定时器频率为=TIMxCLK/(TIM_Prescaler+1)=100KHz
  TIM_TimeBaseStructure.TIM_Prescaler = 1800-1;
  // 计数方式
  TIM_TimeBaseStructure.TIM_CounterMode=TIM_CounterMode_Up;
// 初始化定时器TIMx, x[1,8]
TIM_TimeBaseInit(ADVANCE_TIM, &TIM_TimeBaseStructure);

/* IC1捕获:上升沿触发 TI1FP1 */
  TIM_ICInitStructure.TIM_Channel = ADVANCE_IC1PWM_CHANNEL;
  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(ADVANCE_TIM, &TIM_ICInitStructure);

/* IC2捕获:下降沿触发 TI1FP2
TIM_ICInitStructure.TIM_Channel = ADVANCE_IC2PWM_CHANNEL;
  TIM_ICInitStructure.TIM_ICPolarity = TIM_ICPolarity_Falling;
  TIM_ICInitStructure.TIM_ICSelection = TIM_ICSelection_IndirectTI;
  TIM_ICInitStructure.TIM_ICPrescaler = TIM_ICPSC_DIV1;
  TIM_ICInitStructure.TIM_ICFilter = 0x0;
  TIM_PWMIConfig(ADVANCE_TIM, &TIM_ICInitStructure);
*/
/* 选择定时器输入触发: TI1FP1 */
  TIM_SelectInputTrigger(ADVANCE_TIM, TIM_TS_TI1FP1);  
  /* 选择从模式: 复位模式   不知道有啥用处,但是必不可少*/
  TIM_SelectSlaveMode(ADVANCE_TIM, TIM_SlaveMode_Reset);
  TIM_SelectMasterSlaveMode(ADVANCE_TIM,TIM_MasterSlaveMode_Enable);
  /* 使能高级控制定时器 */
  TIM_Cmd(ADVANCE_TIM, ENABLE);
  /* 使能捕获/比较2中断请求 */
  TIM_ITConfig(ADVANCE_TIM, TIM_IT_CC1, ENABLE);
}

//定时器配置函数
void ATIMx_Init(void)
{
ATIMx_GPIO_Config();

TIMx_NVIC_Configuration();
  
ATIMx_Mode_Config();
}

中断函数
void  ADVANCE_TIM_IRQHandler (void)
{
  /* 清除定时器捕获/比较1中断 */
  TIM_ClearITPendingBit(ADVANCE_TIM, TIM_IT_CC1);
  /* 获取输入捕获值 */
  IC1Value = TIM_GetCapture1(ADVANCE_TIM)+1;
  IC2Value = TIM_GetCapture2(ADVANCE_TIM)+1;
//printf("IC1Value = %d  IC2Value = %d ",IC1Value,IC2Value);
  if (IC2backup!= IC2Value)
   {
   //printf("IC2backup=%d\n",IC2backup);
     printf("IC1Value = %d  IC2Value = %d ",IC1Value,IC2Value);
    IC2backup=IC2Value;
  }
  
  if (IC1Value != 0)
  {
      /* 占空比计算 */
    DutyCycle = (float)(IC2Value * 100) / IC1Value;
    /* 频率计算 */
    Frequency = 180000000/1800/(float)IC1Value;
  if(DutyCycle!=Dbackup)
  {
    printf("占空比:%0.2f%%   频率:%0.2fHz\n",DutyCycle,Frequency);
   //printf("Fbackup=%0.2fHz\n",Fbackup);
   Dbackup=DutyCycle;
  }
    }
  else
  {
    DutyCycle = 0;
    Frequency = 0;
  }
}


串口显示结果
C1Value = 61162  IC2Value = 48930 占空比:80.00%   频率:1.64Hz
IC1Value = 61162  IC2Value = 7862 占空比:12.85%   频率:1.64Hz
IC1Value = 61162  IC2Value = 33208 占空比:54.30%   频率:1.64Hz
IC1Value = 61162  IC2Value = 56794 占空比:92.86%   频率:1.64Hz
IC1Value = 61162  IC2Value = 33208 占空比:54.30%   频率:1.64Hz
IC1Value = 61162  IC2Value = 7862 占空比:12.85%   频率:1.64Hz
IC1Value = 61162  IC2Value = 48930 占空比:80.00%   频率:1.64Hz
IC1Value = 61162  IC2Value = 41072 占空比:67.15%   频率:1.64Hz
IC1Value = 61162  IC2Value = 48930 占空比:80.00%   频率:1.64Hz
IC1Value = 61162  IC2Value = 7862 占空比:12.85%   频率:1.64Hz
IC1Value = 61162  IC2Value = 33208 占空比:54.30%   频率:1.64Hz
IC1Value = 61162  IC2Value = 56794 占空比:92.86%   频率:1.64Hz
IC1Value = 61162  IC2Value = 33208 占空比:54.30%   频率:1.64Hz
IC1Value = 61162  IC2Value = 7862 占空比:12.85%   频率:1.64Hz


回复

使用道具 举报

发表于 2017-2-4 09:16:50 | 显示全部楼层
先用直接例程测试一下,例程也有问题的话就要换引脚
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 注册

本版积分规则

联系站长|手机版|野火电子官网|野火淘宝店铺|野火电子论坛 ( 粤ICP备14069197号 ) 大学生ARM嵌入式2群

GMT+8, 2024-11-23 04:16 , Processed in 0.026416 second(s), 23 queries , Gzip On.

Powered by Discuz! X3.4

Copyright © 2001-2021, Tencent Cloud.

快速回复 返回顶部 返回列表