(本文为记录学习时遇到的问题!)
为获取电机电角度偏移量,往往先上电给Ud赋值,使电机转子处于电角度零点,读取此时ABZ编码器的值,将此值作为初始电角度应用在FOC中。此种方式的麻烦之处在于,每次启动电机都需要先对齐零点。上电直接通过SPI读取编码器的绝对位置,获取电角度偏移量,解决校准电角度零点的问题。
编码器IO口:
MCU的IO口:
tle5012b编码器两种应用模式:
1. SPI模式,上电获取编码器的值,范围为0-360。
uint16_t tle5012(void)
{
HAL_GPIO_WritePin(GPIOA, GPIO_PIN_4, GPIO_PIN_RESET);
uint16_t ang_reg_v = 0x8021, data_v;
HAL_SPI_Transmit(&hspi1, (uint8_t *)(&ang_reg_v), 1, 0xff);
HAL_SPI_Receive(&hspi1, (uint8_t *)(&data_v), 1, 0xff);
data_v = data_v & 0x7fff;
uint16_t ang_v = data_v / (0x7fff / 360.0);
HAL_GPIO_WritePin(GPIOA, GPIO_PIN_4, GPIO_PIN_SET);
HAL_Delay(1);
return ang_v;
}
data_v取值0~32767;
angle_v取值0~359;
应用在电机领域:
int32_t angle = tle5012();
int16_t angle_offset = 0;
angle_offset = (angle%(360/MOTOR1_POLE_PAIR_NUM))*MOTOR1_POLE_PAIR_NUM;
motor->encoder.angle_offset = angle_offset;
360/MOTOR1_POLE_PAIR_NUM:一个电角度周期;
angle%(360/MOTOR1_POLE_PAIR_NUM):电角度零点偏移量;
(angle%(360/MOTOR1_POLE_PAIR_NUM))*MOTOR1_POLE_PAIR_NUM:编码器零点偏移量;
2. ABZ模式,统一范围为0~359。
//编码器原始值,0-16383
uint16_t Motor1_EncoderGetValue(void)
{
uint16_t cnt_value;
cnt_value = ENCODER_GET_VALUE; //0-16383
return cnt_value;
}
//机械角度,0-359
uint16_t Motor1_EncoderGetAngleM(void)
{
uint16_t angle_m;
angle_m = Motor1_EncoderGetValue()*360/16383;
return angle_m;
}
//电角度原始值,精度为极对数,
uint16_t Motor1_EncoderGetAngleEPri(void)
{
uint16_t angle_e;
angle_e = Motor1_EncoderGetAngleM()*MOTOR1_POLE_PAIR_NUM%360;
return angle_e;
}
//电角度
uint16_t Motor1_EncoderGetAngleE(MotorEncoder_st *encoder)
{
uint16_t angle_e;
angle_e = Motor1_EncoderGetAngleEPri();
if (angle_e >= encoder->angle_offset){
return angle_e - encoder->angle_offset;
}else{
return angle_e - encoder->angle_offset + 360;
}
}
上电获取编码的值为0,编码器从0开始计数,函数Motor1_EncoderGetAngleEPri()=0;函数Motor1_EncoderGetAngleE()=0-42+360=318,即假设42这个位置为一个电角度零点,电机闭环运行时,函数angle_e = Motor1_EncoderGetAngleEPri()是一个0~359的值。
电机闭环运行,motor->data.angle_e应用在Park变换和反Park变换中。
if (motor->data.state != 5) // 非开环模式
{
motor->data.angle_e = motor->encoder.angle_e;
}