1.简介
本篇文章介绍了昆泰芯KTH7823磁编码器的PWM输出,并给出对应实例代码。
KTH7823能够提供单线 14bit 绝对值的 PWM 输出,频率为910Hz。
2.KTH7823的PWM输出
KTH7823 PWM 输出的逻辑信号占空比与磁场角度成正比,输出时序如下:
通过KTH7823输出PWM的占空比可以计算出绝对角度。其中,PWM分辨率为 16384,占空比为32/(16384 + 64) 时对应角度为 0°,占空比为 (16384 + 32)/(16384 + 64) 时对应角度为 360°,任意角度计算公式为:
3.实例
以捕获PWM占空比计算绝对角度信息为例。
接下来是相应的代码实现,使用的是STM32F103,利用定时器的输入捕获实现,配置代码用STM32CubeMX自动生成。
定时器基本参数配置如下:
记得开启定时器中断:
void MX_TIM3_Init(void)
{
/* USER CODE BEGIN TIM3_Init 0 */
/* USER CODE END TIM3_Init 0 */
TIM_SlaveConfigTypeDef sSlaveConfig = {0};
TIM_IC_InitTypeDef sConfigIC = {0};
TIM_MasterConfigTypeDef sMasterConfig = {0};
/* USER CODE BEGIN TIM3_Init 1 */
/* USER CODE END TIM3_Init 1 */
htim3.Instance = TIM3;
htim3.Init.Prescaler = 71; //分频系数
htim3.Init.CounterMode = TIM_COUNTERMODE_UP;
htim3.Init.Period = 65535; //计数重装载值
htim3.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1;
htim3.Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_ENABLE;
if (HAL_TIM_IC_Init(&htim3) != HAL_OK)
{
Error_Handler();
}
sSlaveConfig.SlaveMode = TIM_SLAVEMODE_RESET;
sSlaveConfig.InputTrigger = TIM_TS_TI1FP1;
sSlaveConfig.TriggerPolarity = TIM_INPUTCHANNELPOLARITY_RISING;
sSlaveConfig.TriggerPrescaler = TIM_ICPSC_DIV1;
sSlaveConfig.TriggerFilter = 0;
if (HAL_TIM_SlaveConfigSynchro(&htim3, &sSlaveConfig) != HAL_OK)
{
Error_Handler();
}
sConfigIC.ICPolarity = TIM_INPUTCHANNELPOLARITY_RISING;
sConfigIC.ICSelection = TIM_ICSELECTION_DIRECTTI;
sConfigIC.ICPrescaler = TIM_ICPSC_DIV1;
sConfigIC.ICFilter = 0;
if (HAL_TIM_IC_ConfigChannel(&htim3, &sConfigIC, TIM_CHANNEL_1) != HAL_OK)
{
Error_Handler();
}
sConfigIC.ICPolarity = TIM_INPUTCHANNELPOLARITY_FALLING;
sConfigIC.ICSelection = TIM_ICSELECTION_INDIRECTTI;
if (HAL_TIM_IC_ConfigChannel(&htim3, &sConfigIC, TIM_CHANNEL_2) != HAL_OK)
{
Error_Handler();
}
sMasterConfig.MasterOutputTrigger = TIM_TRGO_RESET;
sMasterConfig.MasterSlaveMode = TIM_MASTERSLAVEMODE_DISABLE;
if (HAL_TIMEx_MasterConfigSynchronization(&htim3, &sMasterConfig) != HAL_OK)
{
Error_Handler();
}
/* USER CODE BEGIN TIM3_Init 2 */
HAL_TIM_IC_Start_IT(&htim3,TIM_CHANNEL_1);
HAL_TIM_IC_Start_IT(&htim3,TIM_CHANNEL_2);
/* USER CODE END TIM3_Init 2 */
}
其中,分频系数和计数重装载值需要结合PWM的频率进行设置。如当前所使用的MCU主频为72MHz,设置分频系数为72 - 1 表示计数频率为72 / 72 = 1MHz,也就是1us计数一次,而PWM频率为910Hz,也就是说PWM一个周期大概是1099us,那么计数重装载值必须设置成大于1099,避免在一个PWM周期中计数重装载导致数据有误。
最后,在输入捕获中断中获取PWM占空比并计算绝对角度:
uint32_t CCR1 = 0;
uint32_t CCR2 = 0;
float Duty = 0;
float PWMAngle = 0;
void HAL_TIM_IC_CaptureCallback(TIM_HandleTypeDef *htim)
{
CCR1 = HAL_TIM_ReadCapturedValue(&htim3, TIM_CHANNEL_1); //周期测量计数
if(CCR1 != 0)
{
CCR2 = HAL_TIM_ReadCapturedValue(&htim3, TIM_CHANNEL_2); //脉冲宽度测量计数
Duty = (float)(CCR2 + 1)/(CCR1 + 1); //计算占空比
PWMAngle = (Duty * (16384 + 64) - 32) / 16384 * 360; //计算绝对角度
}
}