1. 写本文是为了记录调试该模块所遇到的问题以及解决办法,同时是为了方便日后回顾。
2. SPI通信和SSC通信
TLE5012B编码器的通信方式为SSC通信,兼容SPI通信,网上已经有很多兼容配置方案,在这里不一一赘述了,链接1,链接2。
但是在这里,我使用的方案与上述方案不一样,我使用的是SPI的双线单工同步传输。STM32的SPI配置代码如下:重点在Direction。
hspi4.Instance = SPI4;
hspi4.Init.Mode = SPI_MODE_MASTER;
hspi4.Init.Direction = SPI_DIRECTION_1LINE;
hspi4.Init.DataSize = SPI_DATASIZE_16BIT;
hspi4.Init.CLKPolarity = SPI_POLARITY_LOW;
hspi4.Init.CLKPhase = SPI_PHASE_2EDGE;
hspi4.Init.NSS = SPI_NSS_SOFT;
hspi4.Init.BaudRatePrescaler = SPI_BAUDRATEPRESCALER_16;
hspi4.Init.FirstBit = SPI_FIRSTBIT_MSB;
hspi4.Init.TIMode = SPI_TIMODE_DISABLE;
hspi4.Init.CRCCalculation = SPI_CRCCALCULATION_DISABLE;
hspi4.Init.CRCPolynomial = 10;
无论哪种硬件配置,只要能通信成功即可。 通信成功的标志是收到的安全字为0xfxxx。安全字为什么是0xfxxx,是因为datasheet写明了。如下图所示
3. 从传输过来的数据解算对应的参数
3.1 角度解算
角度的解算比较简单,根据用户手册给出的公式即可解算出来。
所以解算的代码如下:
encoder_SPI_NS_L();
uint16_t ang_reg_v = READ_ANGLE_VALUE, data_v[2];
HAL_SPI_Transmit(&hspi4, (uint8_t *)(&ang_reg_v), 1, 0xff);
HAL_SPI_Receive(&hspi4, (uint8_t *)(&data_v), 2, 0xff);
encoder_SPI_NS_H();
data_v[1] = data_v[1] & 0x7fff;
float ang_v = (float)data_v[1] * 360.0 / (0x7fff);
3.2 角速度解算
角速度解算需要找一些参数,如下图
可以看出来,角速度的解算需要确定当前使用的角度范围以及t_upd的时间。查datasheet可以找到,t_upd在Autocalibration小节有一个解释,如下图。可以发现是取决于FIR_MD。
查找FIR_MD,如下图,其在mode1寄存器中,复位值基于导数,查找基于导数,猜测和磁编码器型号有关,至此找到FIR_MD,也就得到了t_upd。
再找角度范围,发现在mode2寄存器中,如下图,复位0x80,范围360°,至此已经可以解算角速度。但是在解算调试过程中发现解算数值一直不对,经过排查,传回来的15位数据是有符号类型的,还需要进行符号判断。
所以解算代码如下:
uint16_t speed_reg_v = READ_SPEED_VALUE , data_v[2];
encoder_SPI_NS_L();
HAL_SPI_Transmit(&hspi4, (uint8_t *)(&speed_reg_v), 1, 0xff);
HAL_SPI_Receive(&hspi4, (uint8_t *)(&data_v), 2, 0xff);
encoder_SPI_NS_H();
data_v[1] = (data_v[1] & 0x7fff);
uint16_t sign = data_v[1] & 0x4000;
if(sign == 0x4000) {
data_v[1] = data_v[1] | 0x8000;
}
int16_t speed = (int16_t)data_v[1];
speed = speed * 1000;
float tupd = 2.0 * 42.7 / 1000;
float speed_v = (float)(speed * 2 * 3.14) / 0x7fff; //rad/s
speed_v = speed_v / tupd;
printf("speed:%.3f, %x\n",speed_v, data_v[0]);