F10x系列输入捕获,捕获到的PWM跟自己设置的不一样

2019-10-14 22:53发布

通过TIM1_CH4来产生一个PWM,通过TIM4_CH4来进行捕获。TIM1的设置如下:
//定時器配置函數(输入)
void TIM1_Configuration(void)
{
  TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;
  TIM_OCInitTypeDef TIM_OCInitStruct;
  
  TIM_TimeBaseStructure.TIM_Period = 900-1;
  TIM_TimeBaseStructure.TIM_Prescaler = 72-1;
  TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;
  TIM_TimeBaseStructure.TIM_ClockDivision = TIM_CKD_DIV1;
  TIM_TimeBaseInit(TIM1,&TIM_TimeBaseStructure);
  
  //PWM初始化
  TIM_OCInitStruct.TIM_OCMode = TIM_OCMode_PWM1;
  TIM_OCInitStruct.TIM_OutputState = TIM_OutputState_Enable;
  TIM_OCInitStruct.TIM_OCPolarity = TIM_OCPolarity_Low;
  TIM_OC4Init(TIM1,&TIM_OCInitStruct);//初始化通道4,通道选择在这里修改
  
  TIM_OC4PreloadConfig(TIM1,TIM_OCPreload_Enable);//使能TIM1在CCR4上的预装载寄存器
  
  TIM_ARRPreloadConfig(TIM1,ENABLE);//TIMX_ARR寄存器确定频率,TIMx_CRR寄存器确定占空比
  
  TIM_Cmd(TIM1,ENABLE);
}
TIM4的配置如下:
//定時器配置函數(捕获)
void TIM4_Configuration(void)
{
  TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;
  TIM_ICInitTypeDef  TIM4_ICInitStructure;
  
  TIM_TimeBaseStructure.TIM_Period = 0xffff;
  TIM_TimeBaseStructure.TIM_Prescaler = 72-1;//72M/72=1M
  TIM_TimeBaseStructure.TIM_ClockDivision = 0x0;//
  TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;
  TIM_TimeBaseInit(TIM4,&TIM_TimeBaseStructure);
  
  //初始化TIM4输入捕获
  TIM4_ICInitStructure.TIM_Channel = TIM_Channel_4; //  CC4S=01 选择输入端IC4映射到TI4上
  TIM4_ICInitStructure.TIM_ICPolarity = TIM_ICPolarity_Rising;    //上升沿捕获
  TIM4_ICInitStructure.TIM_ICSelection = TIM_ICSelection_DirectTI; //映射到TI4上
  TIM4_ICInitStructure.TIM_ICPrescaler = TIM_ICPSC_DIV1;     //配置输入分频,不分频
  TIM4_ICInitStructure.TIM_ICFilter = 0x00;//配置输入滤波器 不滤波
  TIM_ICInit(TIM4, &TIM4_ICInitStructure);//初始化通道4,通道选择在这里修改
  
  TIM_ITConfig(TIM4,TIM_IT_Update|TIM_IT_CC4,ENABLE);//允许更新中断,允许CC4输入捕获中断
  
  TIM_Cmd(TIM4,ENABLE);
}
中断服务函数是参照原子哥的代码(写的很经典自己就哪来用了):
void TIM4_IRQHandler(void)
{
  if((TIM4CH4_CAPTURE_STA&0X80)==0)//还未成功捕获   
  {
    if(TIM_GetITStatus(TIM4, TIM_IT_Update) != RESET)//溢出
    {         
      if(TIM4CH4_CAPTURE_STA&0X40)//已经捕获到高电平
      {
        if((TIM4CH4_CAPTURE_STA&0X3F)==0X3F)//高电平太长了
        {
                TIM4CH4_CAPTURE_STA|=0X80;        //标记成功捕获了一次
                TIM4CH4_CAPTURE_VAL=0XFFFF;
        }else TIM4CH4_CAPTURE_STA++;
      }     
    }
    if(TIM_GetITStatus(TIM4, TIM_IT_CC4) != RESET)//捕获1发生捕获时间
    {   
      if(TIM4CH4_CAPTURE_STA&0X40)        //捕获到一个下降沿        
      {                  
        TIM4CH4_CAPTURE_STA|=0X80;        //标记成功捕获到一次高电平脉冲
        TIM4CH4_CAPTURE_VAL=TIM_GetCapture4(TIM4);//获取当前的捕获值
        TIM_OC4PolarityConfig(TIM4,TIM_ICPolarity_Rising); //CC1P=0 设置为上升沿捕获
      }else                                  //还未开始,第一次捕获上升沿
      {
        TIM4CH4_CAPTURE_STA=0;            //清空
        TIM4CH4_CAPTURE_VAL=0;
        TIM4CH4_CAPTURE_STA|=0X40;        //标记捕获到了上升沿
        TIM_Cmd(TIM4,ENABLE );     //使能定时器3
        TIM_SetCounter(TIM4,0);//设置寄存器值为0
        TIM_OC4PolarityConfig(TIM4,TIM_ICPolarity_Falling);        //CC1P=1设置为下降沿捕获
        TIM_Cmd(TIM4,ENABLE );     //使能定时器3
      }            
    }                                                
  }
  TIM_ClearITPendingBit(TIM4, TIM_IT_CC4|TIM_IT_Update); //清除中断标志位
}
主函数的处理函数为:
while(1)
    {
      delay_ms(10);
      TIM_SetCompare4(TIM1,0); //设置TIM1捕获比较4寄存器的值
      if(TIM4CH4_CAPTURE_STA&0x80)//成功捕获到一次高电平
      {
        temp = TIM4CH4_CAPTURE_STA&0x3f;
        temp *= (0xffff);
        temp += TIM4CH4_CAPTURE_VAL;
        TIM4CH4_CAPTURE_STA = 0;
      }
      
    }
以上就是关键代码,自己再跟踪调试的时候,发现TIM4CH4_CAPTURE_VA的值是在7000左右变动。但自己设置产生的PWM应该为900的呀。为什么会相差这么大。还是自己哪里忽略掉了。求大神解答。
友情提示: 此问题已得到解决,问题已经关闭,关闭后问题禁止继续编辑,回答。
该问题目前已经被作者或者管理员关闭, 无法添加新回复
4条回答
TGuest
1楼-- · 2019-10-15 03:01
 精彩回答 2  元偷偷看……
TGuest
2楼-- · 2019-10-15 05:15
尴尬了,改变占空比获得的数据还是7000左右,那程序的逻辑肯定哪里出问题了。继续跟踪。
TGuest
3楼-- · 2019-10-15 06:13
又发现问题了,跟踪调试的数值和串口打印的数值是不一样的。
TGuest
4楼-- · 2019-10-15 07:37
端口设置如果我不设置端口能捕捉到高低电平,但设置后就捕捉不到了,PWM端口设置为复用推完输出,输入捕获端口设置为下拉输入。

一周热门 更多>