我通过 SPI(SSC)将 TLE5012B 与 STM32H503CB 微控制器配合使用。
我发现,通过实施平台抽象层,我可以在任何微控制器上实现相同的功能,因此我开始着手为上述微控制器设计平台抽象层。 首先,我实现了 SPI
sendReceive
函数,并测试了我是否可以正确获取角度,因为我使用磁铁将EVAL_PASCO2_SENSOR安装在WM_MOTOR_CONTROL_01的背面,并验证了旋转磁铁可以使我获得相当准确的读数(大约
0.1 度)。
我的问题出在 CRC 和安全字上,但在担心 CRC 之前,我注意到返回的 STAT nibble 并不全是 1,而数据手册上应该是这样。 程序库将此称为 INVALID_ANGLE_ERROR,但谁知道问题是否出在这里。
我尝试了一个比读取角度更确定的例子,并完全按照 CRC 上 5.2.4 中给出的例子尝试启用预测。 这包括发送命令"写入 mod 2"
,即0x5081,然后发送数据"启用预测" ,即0x0804。 我只希望得到一个安全的字眼作为回应。 我得到了以下安全字:0xef13,或
0b1110111100010011。现在请注意,前三位都是 1,但第四位是 0,因此出现了 INVALID_ANGLE_ERROR
响应。您可能还会注意到 CRC 是错误的(它应该是 0x89,而不是 0x13)。
这让我很困惑,因为从所有指标来看,角度读数都非常准确。 我有证据表明我可以向芯片写入数据,因为我可以在 MOD1 中设置滤波器,并注意到差值(不移动磁铁时的最小-最大值)明显减小。
为了完整起见,我附上了我的整个 stm32 项目,但我会尽量把我认为最相关的信息放在这里。
下面是我的“sendReceive”函数,它是库用来与EVAL_PASCO2_SENSOR进行 SSC 对话的核心函数。
// This function
is used by the library (and me) to talk to the TLE5012B over SSC. It
sends sent_data and waits for the sensor 130ns and then receives a
response of a given length.SPIC::Error_t SPIC::sendReceive(uint16_t*
sent_data, uint16_t size_of_sent_data, uint16_t* received_data, uint16_t
size_of_received_data){ uint8_t
conv_sent_data[2*size_of_sent_data]; uint8_t
conv_received_data[2*size_of_received_data]; for (int i = 0; i <
size_of_sent_data; i++) { conv_sent_data[i * 2] =
(uint8_t)sent_data 0xFF; // Low byte conv_sent_data[i * 2 + 1] = ((uint8_t) (sent_data
>> 8)) 0xFF; // High byte }
HAL_GPIO_WritePin(GPIOB, GPIO_PIN_0, GPIO_PIN_RESET);
HAL_SPI_Transmit(this->spi, conv_sent_data, size_of_sent_data,
100); // Wait the required t_wr period for (int i = 0; i
< 32; i++){ asm("NOP"); }
HAL_SPI_Receive(this->spi, conv_received_data,
size_of_received_data, 100); HAL_GPIO_WritePin(GPIOB, GPIO_PIN_0,
GPIO_PIN_SET); for (int i = 0; i < size_of_received_data;
i++) { received_data = (conv_received_data[i * 2 + 1] << | conv_received_data[i * 2]; } return OK;}在这里,我试图复制数据表中的安全字响应:
// This is copied from the user manual, 5.2.4uint16_t write_to_mod2 =
0x5081; // Write to the mod2 registeruint16_t enable_prediction =
0x0804;uint16_t set_prediction_data[2] = {write_to_mod2,
enable_prediction};uint16_t
get_prediction_safety;spic.sendReceive(set_prediction_data,
2, get_prediction_safety, 1);// The result, placed in
get_prediction_safety, here has the wrong status and CRC values.//
Result here: 0xEF13// Expected result: 0xFE89下面是我的 SPI 初始化函数。
我认为这一切都很好,因为我可以从EVAL_PASCO2_SENSOR读取角度,但也许我在这里配置了一些错误?
/** * @brief SPI2 Initialization Function * @param None * @retval
None */static void MX_SPI2_Init(void){ /* USER CODE BEGIN SPI2_Init 0
*/ /* USER CODE END SPI2_Init 0 */ /* USER CODE BEGIN SPI2_Init 1
*/ /* USER CODE END SPI2_Init 1 */ /* SPI2 parameter
configuration*/ hspi2.Instance = SPI2; hspi2.Init.Mode =
SPI_MODE_MASTER; hspi2.Init.Direction =
SPI_DIRECTION_1LINE; hspi2.Init.DataSize =
SPI_DATASIZE_16BIT; hspi2.Init.CLKPolarity =
SPI_POLARITY_HIGH; hspi2.Init.CLKPhase =
SPI_PHASE_1EDGE; hspi2.Init.NSS =
SPI_NSS_SOFT; hspi2.Init.BaudRatePrescaler =
SPI_BAUDRATEPRESCALER_32; hspi2.Init.FirstBit =
SPI_FIRSTBIT_MSB; hspi2.Init.TIMode =
SPI_TIMODE_DISABLE; hspi2.Init.CRCCalculation =
SPI_CRCCALCULATION_DISABLE; hspi2.Init.CRCPolynomial =
0x7; hspi2.Init.NSSPMode =
SPI_NSS_PULSE_DISABLE; hspi2.Init.NSSPolarity =
SPI_NSS_POLARITY_LOW; hspi2.Init.FifoThreshold =
SPI_FIFO_THRESHOLD_01DATA; hspi2.Init.MasterSSIdleness =
SPI_MASTER_SS_IDLENESS_00CYCLE; hspi2.Init.MasterInterDataIdleness =
SPI_MASTER_INTERDATA_IDLENESS_00CYCLE; hspi2.Init.MasterReceiverAutoSusp
= SPI_MASTER_RX_AUTOSUSP_DISABLE; hspi2.Init.MasterKeepIOState =
SPI_MASTER_KEEP_IO_STATE_DISABLE; hspi2.Init.IOSwap =
SPI_IO_SWAP_DISABLE; hspi2.Init.ReadyMasterManagement =
SPI_RDY_MASTER_MANAGEMENT_INTERNALLY; hspi2.Init.ReadyPolarity =
SPI_RDY_POLARITY_HIGH; if (HAL_SPI_Init( hspi2) != HAL_OK) {
Error_Handler(); } /* USER CODE BEGIN SPI2_Init 2 */ /* USER CODE END
SPI2_Init 2 */}下面是相关原理图片段,基本上仅显示EVAL_PASCO2_SENSOR如何连接到微控制器。
希望不会有什么令人兴奋的事情发生。