我通过 SPI(SSC)将 TLE5012B 与
STM32H503CB 微控制器配合使用。 我在这里找到了 Arduino 库
(https://github.com/Infineon/TLE5012-Magnetic-Angle-Sensor/tree/master) 我发现,通过实施平台抽象层,我可以在任何微控制器上实现相同的功能,因此我开始着手为上述微控制器设计平台抽象层。 首先,我实现了 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 func
tion 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如何连接到微控制器。 希望不会有什么令人兴奋的事情发生。
我想这就是所有相关内容了。