Rubinqi 2023-11-04 13:50 采纳率: 0%
浏览 52

stm32f103c8t6的定时器4设为输入捕获模式,但无法正确都读电机编码器的值

stm32f103c8t6的定时器4设为输入捕获模式,但无法正确都读电机编码器的值,只有0和1,怎么办?
tim2的设置和tim4完全一样,tim2可以正常读取

Ecoder.c

void Encoder_TIM2_Init(void)   //定时器3编码器初始化
{
    RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2,ENABLE);
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE);
    
    GPIO_InitTypeDef GPIO_InitStructure;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0 | GPIO_Pin_1;
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_Init(GPIOA,&GPIO_InitStructure);        
    
    
    TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStructure;
    TIM_TimeBaseInitStructure.TIM_ClockDivision = TIM_CKD_DIV1;
    TIM_TimeBaseInitStructure.TIM_CounterMode = TIM_CounterMode_Up;  //向上计数
    TIM_TimeBaseInitStructure.TIM_Period = 65535;    //ARR(0~65535)      1s
    TIM_TimeBaseInitStructure.TIM_Prescaler = 0;  //PSC(0~65535)      定时频率=72M/(PSC+1)/(ARR+1)
    TIM_TimeBaseInitStructure.TIM_RepetitionCounter = 0;   //重复计数器(高级计数器特有)    
    TIM_TimeBaseInit(TIM2,&TIM_TimeBaseInitStructure);
    
    TIM_EncoderInterfaceConfig(TIM2,TIM_EncoderMode_TI12,TIM_ICPolarity_Rising,TIM_ICPolarity_Rising);//配置编码器模式
    
    TIM_ICInitTypeDef TIM_ICInitStructure;
    TIM_ICStructInit(&TIM_ICInitStructure);//初始化输入捕获
    TIM_ICInitStructure.TIM_ICFilter=10;
    TIM_ICInit(TIM2,&TIM_ICInitStructure);
    
    TIM_ITConfig(TIM2,TIM_IT_Update,ENABLE);//配置溢出更新中断标志位
    TIM_SetCounter(TIM2,0);//清零定时器计数值
    
    TIM_Cmd(TIM2,ENABLE);
}

void Encoder_TIM4_Init(void)    //定时器4编码器初始化
{
    RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM4,ENABLE);
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB,ENABLE);
    
    GPIO_InitTypeDef GPIO_InitStructure;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6 | GPIO_Pin_7;
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_Init(GPIOB,&GPIO_InitStructure);        
    
    TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStructure;
    TIM_TimeBaseInitStructure.TIM_ClockDivision = TIM_CKD_DIV1;
    TIM_TimeBaseInitStructure.TIM_CounterMode = TIM_CounterMode_Up;  //向上计数
    TIM_TimeBaseInitStructure.TIM_Period = 65535;    //ARR(0~65535)      1s
    TIM_TimeBaseInitStructure.TIM_Prescaler = 0;  //PSC(0~65535)      定时频率=72M/(PSC+1)/(ARR+1)
    TIM_TimeBaseInitStructure.TIM_RepetitionCounter = 0;   //重复计数器(高级计数器特有)    
    TIM_TimeBaseInit(TIM4,&TIM_TimeBaseInitStructure);
    
    TIM_EncoderInterfaceConfig(TIM4,TIM_EncoderMode_TI12,TIM_ICPolarity_Rising,TIM_ICPolarity_Rising);//配置编码器模式
    
    TIM_ICInitTypeDef TIM_ICInitStructure;
    TIM_ICStructInit(&TIM_ICInitStructure);//初始化输入捕获
    TIM_ICInitStructure.TIM_ICFilter=10;
    TIM_ICInit(TIM4,&TIM_ICInitStructure);
    
    TIM_ITConfig(TIM4,TIM_IT_Update,ENABLE);//配置溢出更新中断标志位
    TIM_SetCounter(TIM4,0);//清零定时器计数值
    
    TIM_Cmd(TIM4,ENABLE);

}

/**********************
编码器
速度读取函数
入口参数:定时器
**********************/
int Read_Speed(int TIMx)
{
    int value_1;    
   switch(TIMx)
     {
       case 2:  value_1= (short)TIM_GetCounter(TIM2);TIM_SetCounter(TIM2,0);break;
         case 4:  value_1= (short)TIM_GetCounter(TIM4);TIM_SetCounter(TIM4,0);break;
     }
        return value_1;

}

void TIM2_IRQHandler(void)
{
    if(TIM_GetITStatus(TIM2,TIM_IT_Update) == SET)
    {
        
        TIM_ClearITPendingBit(TIM2,TIM_IT_Update);
    }
}

void TIM4_IRQHandler(void)
{
    if(TIM_GetITStatus(TIM4,TIM_IT_Update) == SET)
    {
        
        TIM_ClearITPendingBit(TIM4,TIM_IT_Update);
    }
}


  • 写回答

1条回答 默认 最新

  • CSDN-Ada助手 CSDN-AI 官方账号 2023-11-04 16:05
    关注

    【相关推荐】



    • 帮你找了个相似的问题, 你可以看下: https://ask.csdn.net/questions/7760847
    • 我还给你找了一篇非常好的博客,你可以看看是否有帮助,链接:stm32f0设置tim2单脉冲模式-tim1内部触发
    • 除此之外, 这篇博客: STM32F4深入学习【定时器】(下)中的 高级定时器(TIM1、TIM8)的特殊控制库函数 部分也许能够解决你的问题, 你可以仔细阅读以下内容或跳转源博客中阅读:

      STM32F4中具有两个高级定时器,ST也为它们提供了库函数

      下面是基本使用方法

      1. 使用输出比较模式配置定时器通道
      2. 使用TIM_BDTRInitStruct结构体设置时钟断点极性、死区时间、锁定等级、OSSI/OSSR状态和AOE(自动输出使能)模式
      3. 使用TIM_BDTRConfig(TIMx, &TIM_BDTRInitStruct)配置定时器的高级功能
      4. 使用TIM_CtrlPWMOutputs(TIM1, ENABLE)函数使能主输出
      5. 一旦断点发生,定时器的输出信号就会被置于重置或某个经过TIM_BDTRConfig()设定的状态
      • 配置断点输入(Break input)、死区时间、锁定等级、OSSI、OSSR状态、AOE(自动输入使能)
      void TIM_BDTRConfig(TIM_TypeDef* TIMx, TIM_BDTRInitTypeDef *TIM_BDTRInitStruct)
      {
        /* Check the parameters */
        assert_param(IS_TIM_LIST4_PERIPH(TIMx));
        assert_param(IS_TIM_OSSR_STATE(TIM_BDTRInitStruct->TIM_OSSRState));
        assert_param(IS_TIM_OSSI_STATE(TIM_BDTRInitStruct->TIM_OSSIState));
        assert_param(IS_TIM_LOCK_LEVEL(TIM_BDTRInitStruct->TIM_LOCKLevel));
        assert_param(IS_TIM_BREAK_STATE(TIM_BDTRInitStruct->TIM_Break));
        assert_param(IS_TIM_BREAK_POLARITY(TIM_BDTRInitStruct->TIM_BreakPolarity));
        assert_param(IS_TIM_AUTOMATIC_OUTPUT_STATE(TIM_BDTRInitStruct->TIM_AutomaticOutput));
      
        /* Set the Lock level, the Break enable Bit and the Polarity, the OSSR State,
           the OSSI State, the dead time value and the Automatic Output Enable Bit */
        TIMx->BDTR = (uint32_t)TIM_BDTRInitStruct->TIM_OSSRState | TIM_BDTRInitStruct->TIM_OSSIState |
                   TIM_BDTRInitStruct->TIM_LOCKLevel | TIM_BDTRInitStruct->TIM_DeadTime |
                   TIM_BDTRInitStruct->TIM_Break | TIM_BDTRInitStruct->TIM_BreakPolarity |
                   TIM_BDTRInitStruct->TIM_AutomaticOutput;
      }
      
      //使用初始化结构体默认设置
      void TIM_BDTRStructInit(TIM_BDTRInitTypeDef* TIM_BDTRInitStruct)
      {
        /* Set the default configuration */
        TIM_BDTRInitStruct->TIM_OSSRState = TIM_OSSRState_Disable;
        TIM_BDTRInitStruct->TIM_OSSIState = TIM_OSSIState_Disable;
        TIM_BDTRInitStruct->TIM_LOCKLevel = TIM_LOCKLevel_OFF;
        TIM_BDTRInitStruct->TIM_DeadTime = 0x00;
        TIM_BDTRInitStruct->TIM_Break = TIM_Break_Disable;
        TIM_BDTRInitStruct->TIM_BreakPolarity = TIM_BreakPolarity_Low;
        TIM_BDTRInitStruct->TIM_AutomaticOutput = TIM_AutomaticOutput_Disable;
      }
      
      • 使能/失能定时器外设主输出
      void TIM_CtrlPWMOutputs(TIM_TypeDef* TIMx, FunctionalState NewState)
      {
        /* Check the parameters */
        assert_param(IS_TIM_LIST4_PERIPH(TIMx));
        assert_param(IS_FUNCTIONAL_STATE(NewState));
      
        if (NewState != DISABLE)
        {
          /* Enable the TIM Main Output */
          TIMx->BDTR |= TIM_BDTR_MOE;
        }
        else
        {
          /* Disable the TIM Main Output */
          TIMx->BDTR &= (uint16_t)~TIM_BDTR_MOE;
        }  
      }
      
      • 选择通讯事件
      //选择通信事件
      void TIM_SelectCOM(TIM_TypeDef* TIMx, FunctionalState NewState)
      {
        /* Check the parameters */
        assert_param(IS_TIM_LIST4_PERIPH(TIMx));
        assert_param(IS_FUNCTIONAL_STATE(NewState));
      
        if (NewState != DISABLE)
        {
          /* Set the COM Bit */
          TIMx->CR2 |= TIM_CR2_CCUS;
        }
        else
        {
          /* Reset the COM Bit */
          TIMx->CR2 &= (uint16_t)~TIM_CR2_CCUS;
        }
      }
      
      • 设置/重置捕获比较预装载控制位
      //设置捕获比较预装载控制位
      void TIM_CCPreloadControl(TIM_TypeDef* TIMx, FunctionalState NewState)
      { 
        /* Check the parameters */
        assert_param(IS_TIM_LIST4_PERIPH(TIMx));
        assert_param(IS_FUNCTIONAL_STATE(NewState));
        if (NewState != DISABLE)
        {
          /* Set the CCPC Bit */
          TIMx->CR2 |= TIM_CR2_CCPC;
        }
        else
        {
          /* Reset the CCPC Bit */
          TIMx->CR2 &= (uint16_t)~TIM_CR2_CCPC;
        }
      }
      

    如果你已经解决了该问题, 非常希望你能够分享一下解决方案, 写成博客, 将相关链接放在评论区, 以帮助更多的人 ^-^
    评论

报告相同问题?

问题事件

  • 创建了问题 11月4日