OpenEdv-开源电子网

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

用霍尔传感器模式计算转速有误差,如何解决

[复制链接]

4

主题

30

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
354
金钱
354
注册时间
2019-5-9
在线时间
121 小时
发表于 2021-3-29 16:05:43 | 显示全部楼层 |阅读模式
1金钱
霍尔有上拉5V,测出转速有误差,代码如下

//这是高级定时器16路PWM输出,这个换相直接在定时器1中进行换相,没有在霍尔捕获中断中进行换相:
static void MX_TIM1_Init(void)
{

  /* USER CODE BEGIN TIM1_Init 0 */

  /* USER CODE END TIM1_Init 0 */

  TIM_ClockConfigTypeDef sClockSourceConfig = {0};
  TIM_MasterConfigTypeDef sMasterConfig = {0};
  TIM_OC_InitTypeDef sConfigOC = {0};
  TIM_BreakDeadTimeConfigTypeDef sBreakDeadTimeConfig = {0};

  /* USER CODE BEGIN TIM1_Init 1 */

  /* USER CODE END TIM1_Init 1 */
  htim1.Instance = TIM1;
  htim1.Init.Prescaler = 3;
  htim1.Init.CounterMode = TIM_COUNTERMODE_CENTERALIGNED1;
  htim1.Init.Period = 499;
  htim1.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1;
  htim1.Init.RepetitionCounter = 0;
  htim1.Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_ENABLE;
  if (HAL_TIM_Base_Init(&htim1) != HAL_OK)
  {
    Error_Handler();
  }
  sClockSourceConfig.ClockSource = TIM_CLOCKSOURCE_INTERNAL;
  if (HAL_TIM_ConfigClockSource(&htim1, &sClockSourceConfig) != HAL_OK)
  {
    Error_Handler();
  }
  if (HAL_TIM_PWM_Init(&htim1) != HAL_OK)
  {
    Error_Handler();
  }
  sMasterConfig.MasterOutputTrigger = TIM_TRGO_RESET;
  sMasterConfig.MasterSlaveMode = TIM_MASTERSLAVEMODE_DISABLE;
  if (HAL_TIMEx_MasterConfigSynchronization(&htim1, &sMasterConfig) != HAL_OK)
  {
    Error_Handler();
  }
  sConfigOC.OCMode = TIM_OCMODE_PWM1;
  sConfigOC.Pulse = 0;
  sConfigOC.OCPolarity = TIM_OCPOLARITY_HIGH;
  sConfigOC.OCNPolarity = TIM_OCNPOLARITY_HIGH;
  sConfigOC.OCFastMode = TIM_OCFAST_DISABLE;
  sConfigOC.OCIdleState = TIM_OCIDLESTATE_RESET;
  sConfigOC.OCNIdleState = TIM_OCNIDLESTATE_RESET;
  if (HAL_TIM_PWM_ConfigChannel(&htim1, &sConfigOC, TIM_CHANNEL_1) != HAL_OK)
  {
    Error_Handler();
  }
  if (HAL_TIM_PWM_ConfigChannel(&htim1, &sConfigOC, TIM_CHANNEL_2) != HAL_OK)
  {
    Error_Handler();
  }
  if (HAL_TIM_PWM_ConfigChannel(&htim1, &sConfigOC, TIM_CHANNEL_3) != HAL_OK)
  {
    Error_Handler();
  }
  sBreakDeadTimeConfig.OffStateRunMode = TIM_OSSR_ENABLE;
  sBreakDeadTimeConfig.OffStateIDLEMode = TIM_OSSI_ENABLE;
  sBreakDeadTimeConfig.LockLevel = TIM_LOCKLEVEL_OFF;
  sBreakDeadTimeConfig.DeadTime = 50;
  sBreakDeadTimeConfig.BreakState = TIM_BREAK_DISABLE;
  sBreakDeadTimeConfig.BreakPolarity = TIM_BREAKPOLARITY_HIGH;
  sBreakDeadTimeConfig.AutomaticOutput = TIM_AUTOMATICOUTPUT_DISABLE;
  if (HAL_TIMEx_ConfigBreakDeadTime(&htim1, &sBreakDeadTimeConfig) != HAL_OK)
  {
    Error_Handler();
  }
  /* USER CODE BEGIN TIM1_Init 2 */
        
  HAL_TIM_PWM_Start(&htim1,TIM_CHANNEL_1);      
  HAL_TIM_PWM_Start(&htim1,TIM_CHANNEL_2);                     
  HAL_TIM_PWM_Start(&htim1,TIM_CHANNEL_3);
  HAL_TIM_Base_Start_IT(&htim1);
        
  /* USER CODE END TIM1_Init 2 */
  HAL_TIM_MspPostInit(&htim1);

}


//这是定时器3的霍尔功能
static void MX_TIM3_Init(void)
{

  /* USER CODE BEGIN TIM3_Init 0 */

  /* USER CODE END TIM3_Init 0 */

  TIM_ClockConfigTypeDef sClockSourceConfig = {0};
  TIM_HallSensor_InitTypeDef sConfig = {0};
  TIM_MasterConfigTypeDef sMasterConfig = {0};

  /* USER CODE BEGIN TIM3_Init 1 */

  /* USER CODE END TIM3_Init 1 */
  htim3.Instance = TIM3;
  htim3.Init.Prescaler = 47;
  htim3.Init.CounterMode = TIM_COUNTERMODE_CENTERALIGNED1;
  htim3.Init.Period = 59999;
  htim3.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1;
  htim3.Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_ENABLE;
  if (HAL_TIM_Base_Init(&htim3) != HAL_OK)
  {
    Error_Handler();
  }
  sClockSourceConfig.ClockSource = TIM_CLOCKSOURCE_INTERNAL;
  if (HAL_TIM_ConfigClockSource(&htim3, &sClockSourceConfig) != HAL_OK)
  {
    Error_Handler();
  }
  sConfig.IC1Polarity = TIM_ICPOLARITY_RISING;
  sConfig.IC1Prescaler = TIM_ICPSC_DIV1;
  sConfig.IC1Filter = 0;
  sConfig.Commutation_Delay = 1;
  if (HAL_TIMEx_HallSensor_Init(&htim3, &sConfig) != HAL_OK)
  {
    Error_Handler();
  }
  sMasterConfig.MasterOutputTrigger = TIM_TRGO_OC2REF;
  sMasterConfig.MasterSlaveMode = TIM_MASTERSLAVEMODE_DISABLE;
  if (HAL_TIMEx_MasterConfigSynchronization(&htim3, &sMasterConfig) != HAL_OK)
  {
    Error_Handler();
  }
  /* USER CODE BEGIN TIM3_Init 2 */
        
  HAL_TIMEx_HallSensor_Start_IT(&htim3);
        
  /* USER CODE END TIM3_Init 2 */

}


//这个计算转速的公式,2对极,一圈霍尔变化12次
void GetBldcSpeed(uint16_t tus)
{        
        if((time_speed + tus) > 1000000000)
        {
                time_speed = 1000000000;
        }
        else
        {
                time_speed += tus;
        }
        
        if(hall_number >= 12)
        {
                speed_value = 60000000/time_speed;
               
                hall_number = 0;
                time_speed = 0;
        }
}


//这个是霍尔捕获中断
uint32_t time_temp = 0;
void HAL_TIM_IC_CaptureCallback(TIM_HandleTypeDef *htim)
{
  time_temp = __HAL_TIM_GET_COMPARE(&htim3,TIM_CHANNEL_1);
  hall_number++;
  GetBldcSpeed(time_temp);
}有没有大神帮忙看一下,工程是直接用STM32cubeMX生成的,48MHz





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

使用道具 举报

4

主题

30

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
354
金钱
354
注册时间
2019-5-9
在线时间
121 小时
 楼主| 发表于 2021-3-29 16:21:42 | 显示全部楼层
回复

使用道具 举报

2

主题

369

帖子

0

精华

论坛元老

Rank: 8Rank: 8

积分
4241
金钱
4241
注册时间
2020-7-24
在线时间
714 小时
发表于 2021-3-29 17:06:22 | 显示全部楼层
帮顶  
回复

使用道具 举报

12

主题

3389

帖子

1

精华

论坛元老

Rank: 8Rank: 8

积分
8646
金钱
8646
注册时间
2020-5-11
在线时间
4103 小时
发表于 2021-3-30 09:30:18 | 显示全部楼层
差多少?
滤波没?
有数据?
专治疑难杂症
回复

使用道具 举报

4

主题

30

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
354
金钱
354
注册时间
2019-5-9
在线时间
121 小时
 楼主| 发表于 2021-3-30 10:09:26 | 显示全部楼层
LcwSwust 发表于 2021-3-30 09:30
差多少?
滤波没?
有数据?

没滤波,用转速表测3000转的时候硬件仿真速度是3014转左右,我还有另外一块板,用它来测发现转速表3000转的时候,仿真数据有3040左右,数据很稳定的,就是不准
回复

使用道具 举报

12

主题

3389

帖子

1

精华

论坛元老

Rank: 8Rank: 8

积分
8646
金钱
8646
注册时间
2020-5-11
在线时间
4103 小时
发表于 2021-3-30 10:48:08 | 显示全部楼层
本帖最后由 LcwSwust 于 2021-3-30 10:50 编辑
吖基哈 发表于 2021-3-30 10:09
没滤波,用转速表测3000转的时候硬件仿真速度是3014转左右,我还有另外一块板,用它来测发现转速表3000转 ...

我不了解定时器的霍尔功能,看样子每次捕获都能得到时间差,与普通定时器的捕获功能不同。
由于每次捕获都可能有+1、-1的误差,所以12次累积之后就有可能出现+12、-12的误差。
想要更精准,建议换个方式,比如霍尔信号中断计数,定时1秒读一次计数值除以12即为转速。
另建议测试一下分频与周期是否存在偏差,比如htim3.Init.Prescaler = 47到底是47分频还是48分频。
专治疑难杂症
回复

使用道具 举报

4

主题

30

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
354
金钱
354
注册时间
2019-5-9
在线时间
121 小时
 楼主| 发表于 2021-3-30 11:14:55 | 显示全部楼层
LcwSwust 发表于 2021-3-30 10:48
我不了解定时器的霍尔功能,看样子每次捕获都能得到时间差,与普通定时器的捕获功能不同。
由于每次捕获 ...

之前试过50ms计算捕获次数和捕获的CCR1累加值,最后进行平均值计算发现还是有误差,怀疑是我用cube的配置没配好,网上这方面的资料也比较少
回复

使用道具 举报

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

本版积分规则



关闭

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

正点原子公众号

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

GMT+8, 2025-5-26 07:44

Powered by OpenEdv-开源电子网

© 2001-2030 OpenEdv-开源电子网

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