查看: 4858|回复: 7

【定时器ATIM】输入捕获计数溢出时,如何得到溢出次数

[复制链接]

4

主题

11

帖子

118

积分

中级工程师

Rank: 2

积分
118
发表于 2021-9-29 20:25:16 | 显示全部楼层 |阅读模式
void ATIM_IRQHandler(void)
{

                if(FL_ATIM_IsActiveFlag_CC(ATIM, FL_ATIM_CHANNEL_1) == 1)         
                {
                        IC1Value = FL_ATIM_ReadCompareCH1(ATIM);
                        FL_ATIM_ClearFlag_CC(ATIM, FL_ATIM_CHANNEL_1);
                        count++;
                }
               
                if(FL_ATIM_IsActiveFlag_Update(ATIM)==1) //这难道不是溢出的标志位吗,为什么没有效果
                {
                                ATIM_Update_Cnt++;//溢出次数
                         FL_ATIM_ClearFlag_Update(ATIM);//清除标志位
                }
        
}
回复

使用道具 举报

155

主题

847

帖子

4665

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
4665
发表于 2021-10-9 08:16:31 | 显示全部楼层
你用的是捕获还是 定时?也有可能是你设置错误。 请参考定时例程。在例程中试。例程就是溢出的。
回复

使用道具 举报

4

主题

11

帖子

118

积分

中级工程师

Rank: 2

积分
118
 楼主| 发表于 2021-10-20 19:10:32 | 显示全部楼层
顾博文 发表于 2021-10-9 08:16
你用的是捕获还是 定时?也有可能是你设置错误。 请参考定时例程。在例程中试。例程就是溢出的。 ...

捕获中断
if((FL_ATIM_IsActiveFlag_Update(ATIM)) == 1)
  {

    FL_ATIM_ClearFlag_Update(ATIM);
    TIM3_Update_Cnt++;
  }

  if(FL_ATIM_IsActiveFlag_CCOverflow(ATIM, FL_ATIM_CHANNEL_1) == 1)
  {

    FL_ATIM_ClearFlag_CCOverflow(ATIM, FL_ATIM_CHANNEL_1);    //清除CC1捕捉标志
   
    if(CaptureNumber == 0)
    {
        FL_ATIM_WriteCounter(ATIM, 0);
        TIM3_Update_Cnt = 0;        // 需要特别注意,一定要在第一次捕获到的时候清零
        CaptureNumber = 1;
        FL_ATIM_OC_SetReverseChannelPolarity(ATIM,FL_ATIM_IC_POLARITY_NORMAL, FL_ATIM_CHANNEL_1);        // 配置为下降沿
    }
   
    else if(CaptureNumber == 1)
    {

      IC3ReadValue1 = FL_ATIM_ReadCompareCH1(ATIM) + 65536*TIM3_Update_Cnt;
      CaptureNumber = 2;
      FL_ATIM_OC_SetReverseChannelPolarity(ATIM,FL_ATIM_IC_POLARITY_INVERT, FL_ATIM_CHANNEL_1);        // 配置为上降沿
    }
   
    else if(CaptureNumber == 2)
    {
                       
      IC3ReadValue2 = FL_ATIM_ReadCompareCH1(ATIM) + 65536*TIM3_Update_Cnt;                
     // Frequency = (uint32_t) (SystemCoreClock * 1.0 / IC3ReadValue2 + 0.5);
      Frequency = (uint32_t) (1000000 / IC3ReadValue2); //频率 主时钟为8MHZ、8分频的计算公式
      
      TIM3Duty = (uint32_t) (IC3ReadValue1 * 100.0 / IC3ReadValue2 + 0.5);
      CaptureNumber = 0;
      }
  }  


捕获初始化
void ATIM_CAPTURE_Init(void)     //PWM输入捕获
{
    FL_ATIM_InitTypeDef        InitStructer1;
    FL_ATIM_IC_InitTypeDef     InitStructer2;
    FL_ATIM_SlaveInitTypeDef   InitStructer3;
    FL_GPIO_InitTypeDef         GPIO_InitStruct = {0};

    /*-----------------------------------GPIO初始化---------------------------------------GPIOB   FL_GPIO_PIN_4*/
    GPIO_InitStruct.pin = FL_GPIO_PIN_4;
    GPIO_InitStruct.mode = FL_GPIO_MODE_DIGITAL;
    GPIO_InitStruct.outputType = FL_GPIO_OUTPUT_PUSHPULL;
    GPIO_InitStruct.pull = FL_DISABLE;
    GPIO_InitStruct.remapPin = FL_ENABLE;
    FL_GPIO_Init(GPIOB, &GPIO_InitStruct); //CH1
               
    FL_GPIO_ResetOutputPin(GPIOB, FL_GPIO_PIN_4);


    /*-----------------------------时基结构体初始化----------------------------------------*/
    InitStructer1.clockSource           = FL_CMU_ATIM_CLK_SOURCE_APBCLK;//时钟源 APB2
    InitStructer1.prescaler             = 7;                                       //分频8000
    InitStructer1.counterMode           = FL_ATIM_COUNTER_DIR_UP;                  //向上计数
    InitStructer1.autoReload            = 65535;                                      //自动装载值65536
    InitStructer1.clockDivision         = FL_ATIM_CLK_DIVISION_DIV1;                 // 死区和数字滤波分频
    InitStructer1.repetitionCounter     = 0;                                          //重复计数0
    InitStructer1.autoReloadState       = FL_ENABLE;                                     //自动重装载ARPE使能
    FL_ATIM_Init(ATIM, &InitStructer1);

    /*----------------------------从模式结构体初始化--------------------------------------*/
    InitStructer3.slaveMode     = FL_ATIM_SLAVE_MODE_TRGI_RISE_RST;   //从机复位模式,用于配制PWM输入捕获
    InitStructer3.triggerSrc    = FL_ATIM_TRGI_TI1FP1;              //触发源选择 TI1FP1
    InitStructer3.triggerDelay  = FL_DISABLE;                            //TRGI延迟禁止
    FL_ATIM_SlaveMode_Init(ATIM, &InitStructer3);

    /*---------------------------输入捕获结构体初始化-------------------------------------*/
    InitStructer2.ICPolarity    = FL_ATIM_IC_POLARITY_NORMAL ;          //上升沿捕获
    InitStructer2.ICActiveInput = FL_ATIM_CHANNEL_MODE_INPUT_NORMAL;          //CC1配置为输入,IC1映射到TI1
    InitStructer2.ICPrescaler   = FL_ATIM_IC_PSC_DIV1;          //输入捕捉分频 捕捉到一个跳变沿即进入捕获中断
    InitStructer2.ICFilter      = FL_ATIM_IC_FILTER_DIV1;             //输入捕捉滤波配置
    InitStructer2.captureState  = FL_ENABLE;                              //使能CC1通道
    FL_ATIM_IC_Init(ATIM, FL_ATIM_CHANNEL_1, &InitStructer2);

    //InitStructer2.ICPolarity    = FL_ATIM_IC_POLARITY_INVERT;         //下降沿捕获
    //InitStructer2.ICActiveInput = FL_ATIM_CHANNEL_MODE_INPUT_CROSSOVER;          //CC2配置为输入,IC1映射到TI1
    //FL_ATIM_IC_Init(ATIM, FL_ATIM_CHANNEL_2, &InitStructer2);

    NVIC_DisableIRQ(ATIM_IRQn);
    NVIC_SetPriority(ATIM_IRQn, 1); //中断优先级配置
    NVIC_EnableIRQ(ATIM_IRQn);

    FL_ATIM_ClearFlag_CC(ATIM, FL_ATIM_CHANNEL_1);    //清除CC1捕捉标志
    FL_ATIM_EnableIT_CC(ATIM, FL_ATIM_CHANNEL_1);     //使能CC1捕捉中断

    //FL_ATIM_ClearFlag_CC(ATIM, FL_ATIM_CHANNEL_2);    //清除CC2捕捉标志
   // FL_ATIM_EnableIT_CC(ATIM, FL_ATIM_CHANNEL_2);     //使能CC2捕捉中断
               
                //FL_ATIM_EnableIT_Update(ATIM);
    FL_ATIM_Enable(ATIM); //使能定时器
}
回复

使用道具 举报

4

主题

11

帖子

118

积分

中级工程师

Rank: 2

积分
118
 楼主| 发表于 2021-10-20 19:12:00 | 显示全部楼层
顾博文 发表于 2021-10-9 08:16
你用的是捕获还是 定时?也有可能是你设置错误。 请参考定时例程。在例程中试。例程就是溢出的。 ...

这个问题还是没有解决,捕获的频率还是不准确,差的很多,请问版主能帮忙看一下什么问题吗
回复

使用道具 举报

155

主题

847

帖子

4665

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
4665
发表于 2021-10-21 09:10:36 | 显示全部楼层
6868668 发表于 2021-10-20 19:12
这个问题还是没有解决,捕获的频率还是不准确,差的很多,请问版主能帮忙看一下什么问题吗 ...

在中断中翻灯看吧,进入哪个分支翻哪个灯,同时用全局变量记录ATIM_CNT。 另外如果只是做一个捕获,推荐用lptimer 32位的,同时上升下降沿都可中断,不需要在中断中再配置沿。只要判断端口电平。 用16位,还要考虑多次溢出。
回复

使用道具 举报

4

主题

11

帖子

118

积分

中级工程师

Rank: 2

积分
118
 楼主| 发表于 2021-10-21 15:52:59 | 显示全部楼层
顾博文 发表于 2021-10-21 09:10
在中断中翻灯看吧,进入哪个分支翻哪个灯,同时用全局变量记录ATIM_CNT。 另外如果只是做一个捕获,推荐 ...

这次使用的LPTIM32,按照所给例程PC0应该输出一个1HZ的频率,使用PA8引脚输入捕获,原程序所设置的分频为8,所采集的捕获数为974,通过计算所得到的频率为8000 000/8/974=1027,所测的的频率依然不对。接着我使用STM32C8T6来测试FM33lg048的1hz频率,却可以准确测试到。接着我是用ATIM捕获例程例程进行测试,信号源提供3Khz频率,所测结果仍然不理想,请问这是哪里出了问题 1.png ]W~B}@5$[{_LRU2`[QZK}IF.png

回复

使用道具 举报

4

主题

11

帖子

118

积分

中级工程师

Rank: 2

积分
118
 楼主| 发表于 2021-10-31 11:27:12 | 显示全部楼层
顾博文 发表于 2021-10-21 09:10
在中断中翻灯看吧,进入哪个分支翻哪个灯,同时用全局变量记录ATIM_CNT。 另外如果只是做一个捕获,推荐 ...

请问一下,你说使用lptimer 32,lptimer 32使用的时钟是 LSCLK、 RCLP、 APBCLK、 RCLF_PSC、LPT32_ETR,那么捕获的频率是不是更加不准确。为什么我这边考虑的多次溢出,反而使捕获的频率不对了,请问我这边写的溢出次数不对,还是说这款芯片的溢出没有配置好
回复

使用道具 举报

155

主题

847

帖子

4665

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
4665
发表于 2021-11-1 08:40:08 | 显示全部楼层
6868668 发表于 2021-10-31 11:27
请问一下,你说使用lptimer 32,lptimer 32使用的时钟是 LSCLK、 RCLP、 APBCLK、 RCLF_PSC、LPT32_ETR, ...

32位lptimer还考虑溢出?apbclk没分频不就是主频么,为什么不准。 我没用过溢出的方式,估计是哪里没配对。 拿个示波器,翻个io。每次溢出翻一下。针对波形自己分析吧。
回复

使用道具 举报

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

本版积分规则

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