OpenEdv-开源电子网

 找回密码
 立即注册
正点原子全套STM32/Linux/FPGA开发资料,上千讲STM32视频教程免费下载...
查看: 6890|回复: 3

救命!关于输入捕获测频率失败的问题

[复制链接]

1

主题

1

帖子

0

精华

新手上路

积分
23
金钱
23
注册时间
2021-5-12
在线时间
4 小时
发表于 2021-7-14 13:00:29 | 显示全部楼层 |阅读模式
1金钱
仿照很多教程的输入捕获测频率的代码,结果都失败了,实在是不知道到底哪里配置出了问题。
用探索者的板子测量自己PWM输出的频率。
#ifndef __TIMER_H
#define __TIMER_H

#include "stm32f4xx.h"
#include "sys.h"

void TIMx_NVIC_Configuration(void);
void TIM_PWMINPUT_Config(void);
void TIM_PWMOUTPUT_Config(void);
void TIMx_GPIO_Config(void);

#endif

上面是定时器头文件


#include "timer.h"


void TIMx_GPIO_Config(void)
{
        /*定义一个GPIO_InitTypeDef类型的结构体*/
        GPIO_InitTypeDef GPIO_InitStructure;

        /*开启LED相关的GPIO外设时钟*/
        RCC_AHB1PeriphClockCmd (RCC_AHB1Periph_GPIOA, ENABLE);
        RCC_AHB1PeriphClockCmd (RCC_AHB1Periph_GPIOC, ENABLE);        

        /* 定时器复用引脚 */
        GPIO_PinAFConfig(GPIOA,GPIO_PinSource5,GPIO_AF_TIM2);
        GPIO_PinAFConfig(GPIOC,GPIO_PinSource6,GPIO_AF_TIM8);
       
        /* 通用定时器PWM输出引脚 */                                                                                                                          
        GPIO_InitStructure.GPIO_Pin = GPIO_Pin_5;       
        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(GPIOA, &GPIO_InitStructure);
       
        /* 高级控制定时器PWM输入捕获引脚 */
        GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6;       
        GPIO_Init(GPIOC, &GPIO_InitStructure);
}

/*
* 注意:TIM_TimeBaseInitTypeDef结构体里面有5个成员,TIM6和TIM7的寄存器里面只有
* TIM_Prescaler和TIM_Period,所以使用TIM6和TIM7的时候只需初始化这两个成员即可,
* 另外三个成员是通用定时器和高级定时器才有.
*-----------------------------------------------------------------------------
* TIM_Prescaler         都有
* TIM_CounterMode                         TIMx,x[6,7]没有,其他都有(基本定时器)
* TIM_Period            都有
* TIM_ClockDivision     TIMx,x[6,7]没有,其他都有(基本定时器)
* TIM_RepetitionCounter TIMx,x[1,8]才有(高级定时器)
*-----------------------------------------------------------------------------
*/
void TIM_PWMOUTPUT_Config(void)
{
  TIM_TimeBaseInitTypeDef  TIM_TimeBaseStructure;
  TIM_OCInitTypeDef  TIM_OCInitStructure;
       
        // 开启TIMx_CLK,x[2,3,4,5,12,13,14]
  RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE);

  /* 累计 TIM_Period个后产生一个更新或者中断*/               
  //当定时器从0计数到9999,即为10000次,为一个定时周期
  TIM_TimeBaseStructure.TIM_Period = 10-1;      
       
        // 通用定时器2时钟源TIMxCLK = HCLK/2=84MHz
        // 设定定时器频率为=TIMxCLK/(TIM_Prescaler+1)=100KHz
  TIM_TimeBaseStructure.TIM_Prescaler = 84-1;       
  // 采样时钟分频
  TIM_TimeBaseStructure.TIM_ClockDivision=TIM_CKD_DIV1;
  // 计数方式
  TIM_TimeBaseStructure.TIM_CounterMode=TIM_CounterMode_Up;
       
        // 初始化定时器TIMx, x[1,8]
  TIM_TimeBaseInit(TIM2, &TIM_TimeBaseStructure);
       
        /* PWM输出模式配置 */
        /* 配置为PWM模式1 */
  TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1;            
  TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;       
        /* PWM脉冲宽度 */
  TIM_OCInitStructure.TIM_Pulse = 5;
  TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High;
        /* 使能通道1 */
  TIM_OC1Init(TIM2, &TIM_OCInitStructure);       
        /*使能通道1重载*/
        TIM_OC1PreloadConfig(TIM2, TIM_OCPreload_Enable);
        // 使能定时器
        TIM_Cmd(TIM2, ENABLE);       
}


void TIM_PWMINPUT_Config(void)
{
        TIM_TimeBaseInitTypeDef  TIM_TimeBaseStructure;
        TIM_ICInitTypeDef  TIM_ICInitStructure;
       
        // 开启TIMx_CLK,x[1,8]
  RCC_APB2PeriphClockCmd(RCC_APB2Periph_TIM8, ENABLE);

  TIM_TimeBaseStructure.TIM_Period = 1000-1;        
        // 高级控制定时器时钟源TIMxCLK = HCLK=168MHz
        // 设定定时器频率为=TIMxCLK/(TIM_Prescaler+1)=100KHz
  TIM_TimeBaseStructure.TIM_Prescaler = 168-1;       
  // 计数方式
  TIM_TimeBaseStructure.TIM_CounterMode=TIM_CounterMode_Up;       
        // 初始化定时器TIMx, x[1,8]
        TIM_TimeBaseInit(TIM8, &TIM_TimeBaseStructure);
       
        /* IC1捕获:上升沿触发 TI1FP1 */
  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(TIM8, &TIM_ICInitStructure);
       
        /* IC2捕获:下降沿触发 TI1FP2 */       
        TIM_ICInitStructure.TIM_Channel = TIM_Channel_2;
  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(TIM8, &TIM_ICInitStructure);
       
        /* 选择定时器输入触发: TI1FP1 */
  TIM_SelectInputTrigger(TIM8, TIM_TS_TI1FP1);               

  /* 选择从模式: 复位模式 */
  TIM_SelectSlaveMode(TIM8, TIM_SlaveMode_Reset);
  TIM_SelectMasterSlaveMode(TIM8,TIM_MasterSlaveMode_Enable);

  /* 使能高级控制定时器 */
  TIM_Cmd(TIM8, ENABLE);

  /* 使能捕获/比较2中断请求 */
  TIM_ITConfig(TIM8, TIM_IT_CC1, ENABLE);
}


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

感觉配置没什么问题



__IO uint16_t IC2Value = 0;
__IO uint16_t IC1Value = 0;
__IO float DutyCycle = 0;
__IO float Frequency = 0;

void TIM8_CC_IRQHandler(void)
{
  /* 清除定时器捕获/比较1中断 */
  TIM_ClearITPendingBit(TIM8, TIM_IT_CC1);

  /* 获取输入捕获值 */
  IC1Value = TIM_GetCapture1(TIM8);
  IC2Value = TIM_GetCapture2(TIM8);       
       
  if (IC1Value != 0)
  {
    /* 占空比计算 */
    DutyCycle = (float)(IC2Value * 100) / IC1Value;

    /* 频率计算 */
    Frequency = 168000000/168/(float)IC1Value;
        printf("占空比:%0.2f%%   频率:%0.2fHz\r\n",DutyCycle,Frequency);
  }
  else
  {
    DutyCycle = 0;
    Frequency = 0;
  }
}



int main(void)
{
        uart_init(115200);
        delay_init(84);
    TIMx_GPIO_Config();
    TIMx_NVIC_Configuration();
    TIM_PWMOUTPUT_Config();
    TIM_PWMINPUT_Config();
        printf("\r\n这是一个定时器输入捕获例程\r\n");
    while(1)
    {

    }
}

实在不知道还有什么要配置的,求大佬帮忙看看

频率测量.zip

10.72 MB, 下载次数: 4

正点原子逻辑分析仪DL16劲爆上市
回复

使用道具 举报

0

主题

1

帖子

0

精华

初级会员

Rank: 2

积分
81
金钱
81
注册时间
2020-9-11
在线时间
40 小时
发表于 2021-7-14 18:10:32 | 显示全部楼层
回复

使用道具 举报

15

主题

1061

帖子

0

精华

资深版主

Rank: 8Rank: 8

积分
3625
金钱
3625
注册时间
2019-8-14
在线时间
1054 小时
发表于 2021-7-14 19:51:43 | 显示全部楼层
帮顶  
回复

使用道具 举报

1

主题

2

帖子

0

精华

新手上路

积分
34
金钱
34
注册时间
2021-7-6
在线时间
8 小时
发表于 2021-7-31 17:29:36 | 显示全部楼层
兄弟 这个问题解决了吗?我也遇到了这个问题,捕获到的数据一直乱跳,解决了分享下可以不,412931312@qq.com
回复

使用道具 举报

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

本版积分规则



关闭

原子哥极力推荐上一条 /2 下一条

正点原子公众号

QQ|手机版|OpenEdv-开源电子网 ( 粤ICP备12000418号-1 )

GMT+8, 2025-5-25 21:52

Powered by OpenEdv-开源电子网

© 2001-2030 OpenEdv-开源电子网

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