Tariky 2022-04-13 13:39 采纳率: 33.3%
浏览 991
已结题

STM32F407最小系统板HAL库定时器配置编码器模式CNT一直为0

问题遇到的现象和发生背景

STM32F407最小系统板HAL库定时器配置编码器模式CNT一直为0,编码器是AB相增量式霍尔编码器
定时器和IO口使用的是TIM3 CH1 CH2, PA6, PA7

问题相关代码,请勿粘贴截图

编码器初始化:

TIM_HandleTypeDef TIM3_Handler;
TIM_Encoder_InitTypeDef TIM3_Encoder_Handler;

void Encoder_Init(void) {
    
    TIM_Encoder_InitTypeDef sConfig = {0};
    TIM_MasterConfigTypeDef sMasterConfig = {0};

    /* USER CODE BEGIN TIM3_Init 1 */

    /* USER CODE END TIM3_Init 1 */
    TIM3_Handler.Instance = TIM3;
    TIM3_Handler.Instance->SMCR &= ~TIM_SMCR_SMS;
    TIM3_Handler.Init.Prescaler = 0;
    TIM3_Handler.Init.CounterMode = TIM_COUNTERMODE_UP;
    TIM3_Handler.Init.Period = 65535;
    TIM3_Handler.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1;
    TIM3_Handler.Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_ENABLE;
    sConfig.EncoderMode = TIM_ENCODERMODE_TI12;
    sConfig.IC1Polarity = TIM_ICPOLARITY_RISING;
    sConfig.IC1Selection = TIM_ICSELECTION_DIRECTTI;
    sConfig.IC1Prescaler = TIM_ICPSC_DIV1;
    sConfig.IC1Filter = 10;
    sConfig.IC2Polarity = TIM_ICPOLARITY_RISING;
    sConfig.IC2Selection = TIM_ICSELECTION_DIRECTTI;
    sConfig.IC2Prescaler = TIM_ICPSC_DIV1;
    sConfig.IC2Filter = 10;
    if (HAL_TIM_Encoder_Init(&TIM3_Handler, &sConfig) != HAL_OK) {
        
        printf("TIM3 Encoder Init Error!/r/n");
        
    }
    sMasterConfig.MasterOutputTrigger = TIM_TRGO_RESET;
    sMasterConfig.MasterSlaveMode = TIM_MASTERSLAVEMODE_DISABLE;
    if (HAL_TIMEx_MasterConfigSynchronization(&TIM3_Handler, &sMasterConfig) != HAL_OK) {
        
        printf("TIM3 Master Config Error!/r/n");
        
    }
//  /* 清零计数器 */
    __HAL_TIM_SET_COUNTER(&TIM3_Handler, 0);

//    /* 清零中断标志位 */
    __HAL_TIM_CLEAR_IT(&TIM3_Handler,TIM_IT_UPDATE);
//    /* 使能定时器的更新事件中断 */
//    __HAL_TIM_ENABLE_IT(&TIM3_Handler,TIM_IT_UPDATE);
//    /* 设置更新事件请求源为:计数器溢出 这个地方可能会忘记设置 */
//    __HAL_TIM_URS_ENABLE(&TIM3_Handler);

//    /* 设置中断优先级 */
//    HAL_NVIC_SetPriority(TIM3_IRQn, 1, 0);
//    /* 使能定时器中断 */
//    HAL_NVIC_EnableIRQ(TIM3_IRQn);

    HAL_TIM_Encoder_Start(&TIM3_Handler, TIM_CHANNEL_ALL);

}

void HAL_TIM_Encoder_MspInit(TIM_HandleTypeDef *htim) {
    
    if (htim->Instance == TIM3) {
        printf("TIM3 Encoder Msp Init\r\n");
        GPIO_InitTypeDef GPIO_Initure;
        __HAL_RCC_TIM3_CLK_ENABLE();
        __HAL_RCC_GPIOA_CLK_ENABLE();
        
        GPIO_Initure.Pin = GPIO_PIN_6 | GPIO_PIN_7;
        GPIO_Initure.Mode = GPIO_MODE_AF_PP;
        GPIO_Initure.Pull = GPIO_PULLUP;
        GPIO_Initure.Speed = GPIO_SPEED_FREQ_LOW;
        GPIO_Initure.Alternate = GPIO_AF2_TIM3;
        HAL_GPIO_Init(GPIOA, &GPIO_Initure);
        
//        HAL_NVIC_SetPriority(TIM3_IRQn, 0, 0);
//        HAL_NVIC_EnableIRQ(TIM3_IRQn);
        
    }
    
}

主循环代码:

Encoder_Init();
while (1) {
    CaptureNumber = ( int16_t )TIM3->CNT;
    printf("输入捕获值:%d \r\n", CaptureNumber);
    // 4 : 使用定时器编码器接口捕获AB相的上升沿和下降沿,一个脉冲*4.
    // 11:编码器线数(转速一圈输出脉冲数)
    // 34:电机减数比,内部电机转动圈数与电机输出轴转动圈数比,即减速齿轮比
    printf("电机实际转动速度:%0.2f(圈/s)\r\n",(float) CaptureNumber/4/11/34);
    TIM3->CNT = 0;
    delay_ms(200);
}
运行结果及报错内容

img

我的解答思路和尝试过的方法

网上大部分HAL库的都试过了

我想要达到的结果

能正常读取编码器数据就行

展开全部

  • 写回答

2条回答 默认 最新

  • ilmss 2022-04-14 06:16
    关注

    注意两个问题:一个是存在相位差的信号,二是两组方波信号
    定时器配置
    注:*这种测速的情况必须开启另一个定时器,用来表示在多少时间内测得的脉冲数。例如目前使用TIM1,设为1s进行计数。
    STM32Cube MX中进行定时器配置:定时器时钟频率为80MHz。
    定时器编码器模式设置
    使用TIM3设为编码器模式,可以对两路有相位差(90°或者270°)的方波信号进行脉冲计数和方向位测试。
    在主循环开始前

    HAL_TIM_Encoder_Start_IT(&htim3,TIM_CHANNEL_ALL);//打开编码器中断
    HAL_TIM_Base_Start_IT(&htim1);//开启1S定时中断
    __HAL_TIM_ENABLE_IT(&htim3,TIM_IT_UPDATE);//更新中断用于溢出计数
    
    在中断中
    void HAL_TIM_IC_CaptureCallback(TIM_HandleTypeDef *htim)//捕获中断中可以添加自己所需要的标志位
    {undefined
    if(htim3.Instance->CR1 == 0x01)//顺时针
    {}
    if(htim3.Instance->CR1 == 0x11)//逆时针
    {}
    }
    void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)
    {undefined
    if(TIM1 == htim->Instance)
    {undefined
    t200 = 1;
    }
    if(TIM3 == htim->Instance)
    {undefined
    TIM3UP++;
    __HAL_TIM_CLEAR_IT(&htim3,TIM_IT_UPDATE);
    if(htim3.Instance->CR1 == 0x01)//顺时针
    {undefined
    circle_count++;
    }
    if(htim3.Instance->CR1 == 0x11)//逆时针
    {undefined
    circle_count–;
    }
      }
       }
    

    在主循环中

    if(t200 == 1)
      {
          t200 = 0;
          HAL_TIM_Encoder_Stop(&htim3,TIM_CHANNEL_ALL);
          __HAL_TIM_DISABLE_IT(&htim3,TIM_IT_UPDATE);
    
          directuinA = __HAL_TIM_IS_TIM_COUNTING_DOWN(&htim3);//用来获取方向
          if(directuinA == 0)//顺时针,会从0开始向上计数,来一个脉冲,增加一个计数
          {
            CaptureNumberA = TIM3UP * 65535 + __HAL_TIM_GET_COUNTER(&htim3);
          }
          else if(directuinA == 1)//逆时针,会从65535开始向下计数,来一个脉冲,减去一个计数;TIM3UP 是为了计数溢出所添加的
          {
            CaptureNumberA = TIM3UP * 65535  - __HAL_TIM_GET_COUNTER(&htim3) + 1;
          }
          //除以4是由于四倍频的缘故,PULSE_CIRCLE是指一圈有多少脉冲,*60是为了换算成r/min
          T_SPEED = (CaptureNumberA / 4.0) / PULSE_CIRCLE * 60;
          
          HAL_TIM_Base_Stop(&htim3);
          __HAL_TIM_SET_COUNTER(&htim3,0);
          TIM3UP = 0;
          HAL_TIM_Base_Start(&htim3);
      }
    
    
    

    展开全部

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论
    Tariky 2022-04-14 07:51

    但现在电机还没转就捕捉到很大的脉冲数

    回复
    Tariky 2022-04-15 11:41

    测试了TIM8有用,应该是其他定时器的问题

    回复
    Loophole&Bug 回复 Tariky 2023-07-08 07:49

    题主找到具体问题出现在哪里了吗?我也是同样的问题,我的芯片型号是429,还有就是

    HAL_TIMEx_MasterConfigSynchronization(&TIM3_Handler, &sMasterConfig
    
    是必须要加的吗?
    谢谢
    
    

    ```

    回复
查看更多回答(1条)
编辑
预览

报告相同问题?

问题事件

  • 系统已结题 4月22日
  • 已采纳回答 4月15日
  • 赞助了问题酬金10元 4月14日
  • 修改了问题 4月13日
  • 展开全部

悬赏问题

  • ¥15 vs2022无法联网
  • ¥15 TCP的客户端和服务器的互联
  • ¥15 VB.NET操作免驱摄像头
  • ¥15 笔记本上移动热点开关状态查询
  • ¥85 类鸟群Boids——仿真鸟群避障的相关问题
  • ¥15 CFEDEM自带算例错误,如何解决?
  • ¥15 有没有会使用flac3d软件的家人
  • ¥20 360摄像头无法解绑使用,请教解绑当前账号绑定问题,
  • ¥15 docker实践项目
  • ¥15 利用pthon计算薄膜结构的光导纳
手机看
程序员都在用的中文IT技术交流社区

程序员都在用的中文IT技术交流社区

专业的中文 IT 技术社区,与千万技术人共成长

专业的中文 IT 技术社区,与千万技术人共成长

关注【CSDN】视频号,行业资讯、技术分享精彩不断,直播好礼送不停!

关注【CSDN】视频号,行业资讯、技术分享精彩不断,直播好礼送不停!

客服 返回
顶部