1.简介
本篇文章介绍了昆泰芯KTH78系列磁编码器通过SPI通信输出绝对角度+CRC,并给出对应实例代码。
KTH78系列芯片能够通过SPI读取12位绝对角度+CRC,且其SPI通信速率快,最高可支持10M,在保持高速率通信的同时保证数据传输的可靠性。
2.KTH78系列SPI输出 绝对角度+CRC
KTH78系列芯片使用四线SPI进行通信,其通信模式为 mode3(CPOL = 1 和 CPHA = 1)。注意KTH78系列在进行SPI通信时会在下一帧返回当前帧的结果。
SPI读取角度+CRC
KTH78系列芯片读取角度相关指令为 :
在读取角度指令的下一帧将返回角度+CRC,其输出帧格式为:
CRC校验的作用
CRC校验是一种常用的数据校验方法,用于检测数据传输过程中是否发生错误或数据损坏。它通过对数据进行计算得到一个校验值,发送方将该校验值附加在数据后一起发送给接收方,接收方再对接收到的数据进行计算,与接收到的校验值进行比较,以判断数据是否正确。
KTH78系列芯片的12bit角度数据提供了足够的精度,能满足大多数应用的需求,而4bit的CRC校验确保了数据的完整性和真实性。如果追求角度数据传输的可靠性,可以考虑使用带有CRC校验版本的KTH78系列芯片。
3.实例
接下来是获取12bit绝对角度并通过CRC进行校验的代码实现,使用的是STM32F303,配置代码还是利用STM32CubeMX自动生成
SPI配置为:
void MX_SPI1_Init(void)
{
/* USER CODE BEGIN SPI1_Init 0 */
/* USER CODE END SPI1_Init 0 */
/* USER CODE BEGIN SPI1_Init 1 */
/* USER CODE END SPI1_Init 1 */
hspi1.Instance = SPI1;
hspi1.Init.Mode = SPI_MODE_MASTER;
hspi1.Init.Direction = SPI_DIRECTION_2LINES;
hspi1.Init.DataSize = SPI_DATASIZE_8BIT;
hspi1.Init.CLKPolarity = SPI_POLARITY_HIGH; //CPOL = 1
hspi1.Init.CLKPhase = SPI_PHASE_2EDGE; //CPHA = 1
hspi1.Init.NSS = SPI_NSS_SOFT; //CS软件拉高拉低
hspi1.Init.BaudRatePrescaler = SPI_BAUDRATEPRESCALER_8;
hspi1.Init.FirstBit = SPI_FIRSTBIT_MSB;
hspi1.Init.TIMode = SPI_TIMODE_DISABLE;
hspi1.Init.CRCCalculation = SPI_CRCCALCULATION_DISABLE;
hspi1.Init.CRCPolynomial = 7;
hspi1.Init.CRCLength = SPI_CRC_LENGTH_DATASIZE;
hspi1.Init.NSSPMode = SPI_NSS_PULSE_DISABLE;
if (HAL_SPI_Init(&hspi1) != HAL_OK)
{
Error_Handler();
}
/* USER CODE BEGIN SPI1_Init 2 */
/* USER CODE END SPI1_Init 2 */
}
使用SPI读取角度并进行CRC校验:
uint16_t Angle = 0;
//计算CRC4
uint8_t CalCRC4(uint8_t* data, uint32_t length)
{
uint8_t i;
uint8_t crc = 0;
uint32_t index = 0;
while (length-- > 0)
{
crc ^= data[index];
index++;
for (i = 0; i < 8; i++)
{
if ((crc & 1) == 1) crc = (uint8_t)((crc >> 1) ^ 0x0C);
else crc = (uint8_t)(crc >> 1);
}
}
return crc;
}
//CRC校验
uint8_t KTH78_SPI_CheckCRC(void)
{
uint8_t temp[] = {Angle >> 12, Angle >> 4}; //处理数据为低位对齐的uint8_t数组
uint8_t crc4 = CalCRC4(temp, 2);
if (crc4 != (Angle & 0x0F)) //校验失败
{
return 0;
}
return 1;
}
//SPI发送接收
void KTH78_SPI_TransmitReceive(uint8_t *pTxData, uint8_t *pRxData, uint16_t Size)
{
HAL_GPIO_WritePin(SPI1_NSS_GPIO_Port,SPI1_NSS_Pin,GPIO_PIN_RESET);
HAL_SPI_TransmitReceive(&hspi1, pTxData, pRxData, 2, 0xFFFF);
HAL_GPIO_WritePin(SPI1_NSS_GPIO_Port,SPI1_NSS_Pin,GPIO_PIN_SET);
}
//SPI读取角度并校验
void KTH78_SPI_ReadAngleAndCheckCRC(void)
{
uint8_t spitx[2] = {0x00, 0x00}; //SPI指令
uint8_t spirx[2];
KTH78_SPI_TransmitReceive(spitx, spirx, 2);
KTH78_SPI_TransmitReceive(spitx, spirx, 2);
Angle = ((uint16_t)spirx[0] << 8) | spirx[1]; //返回结果处理
if (KTH78_SPI_CheckCRC() == 1) Angle >>= 4; //校验成功则处理为12bit角度
else Angle = 0; //校验失败则清零
}