0

我正在尝试通过 STM32 NUCLEO F446RE 上的 SPI 从AMS AS5050A磁性编码器读取值,但我无法让它工作。当我使用 HAL 库时,输出始终为 0。我对外围设备的设置是这样的:

hspi3.Instance = SPI3;
hspi3.Init.Mode = SPI_MODE_MASTER;
hspi3.Init.Direction = SPI_DIRECTION_2LINES;
hspi3.Init.DataSize = SPI_DATASIZE_16BIT;
hspi3.Init.CLKPolarity = SPI_POLARITY_LOW;
hspi3.Init.CLKPhase = SPI_PHASE_2EDGE;
hspi3.Init.NSS = SPI_NSS_SOFT;
hspi3.Init.BaudRatePrescaler = SPI_BAUDRATEPRESCALER_2;
hspi3.Init.FirstBit = SPI_FIRSTBIT_MSB;
hspi3.Init.TIMode = SPI_TIMODE_DISABLE;
hspi3.Init.CRCCalculation = SPI_CRCCALCULATION_DISABLE;
hspi3.Init.CRCPolynomial = 10;
if (HAL_SPI_Init(&hspi3) != HAL_OK)
{
    Error_Handler();
}

到目前为止,这是我的代码:

    HAL_StatusTypeDef ret = 0;
    short address = AMS_AS5050A_create_command(AMS_AS5050A_SPI_READ, 0x3FFF);

    // pull slave select pin low
    HAL_GPIO_WritePin(GPIOC, GPIO_PIN_6, GPIO_PIN_RESET);
    //transmit data
    ret = HAL_SPI_Transmit(&hspi3, (uint8_t *) &address, 2, HAL_MAX_DELAY);
    // pull slave select pin high
    HAL_GPIO_WritePin(GPIOC, GPIO_PIN_6, GPIO_PIN_SET);

    sprintf(buf, "[MAIN] test transmit returned code: %d\r\n", ret);
    UART_send(buf);

    HAL_Delay(50);

    uint16_t temp_data = 0;

    HAL_GPIO_WritePin(GPIOC, GPIO_PIN_6, GPIO_PIN_RESET);
    ret = HAL_SPI_Receive(&hspi3, (uint8_t*) &temp_data, 2,
    HAL_MAX_DELAY);
    HAL_GPIO_WritePin(GPIOC, GPIO_PIN_6, GPIO_PIN_SET);

    sprintf(buf, "[MAIN] test receive returned code: %d\r\n", ret);
    UART_send(buf);

    sprintf(buf, "[MAIN] test transmit and receive angle is: %d\r\n",
            temp_data);
    UART_send(buf);
    HAL_Delay(50);

当与它给出的命令一起使用时,该AMS_AS5050A_create_command函数向短路添加读/写位并添加奇偶校验位,这是正确的。它看起来像这样:0x3FFF0xFFFF

short AMS_AS5050A_create_command(uint8_t read_write, short address)
{

    short data = read_write << 15;
    data |= (address << 1);
    short res = data | calculate_parity(data);

    return res;
}

当我在 PuTTy 中查看输出时,输出始终为 0。这些函数没有给出任何错误代码,但 SPI 读取命令的输出始终为 0,即使我在它前面拿着一块磁铁:

[MAIN] test transmit returned code: 0
[MAIN] test receive returned code: 0
[MAIN] test transmit and receive angle is: 0
[MAIN] test transmit returned code: 0
[MAIN] test receive returned code: 0
[MAIN] test transmit and receive angle is: 0
[MAIN] test transmit returned code: 0
[MAIN] test receive returned code: 0
[MAIN] test transmit and receive angle is: 0
[MAIN] test transmit returned code: 0
[MAIN] test receive returned code: 0
[MAIN] test transmit and receive angle is: 0

有人知道我做错了什么吗?

4

1 回答 1

1

虽然有变化,但通常的顺序是:

  1. 启用设备
  2. 向设备写入命令以请求其状态
  3. 读取状态
  4. 如果忙,则循环回到步骤 2
  5. 编写请求最新数据的命令
  6. 写一个命令来读取状态
  7. 如果状态指示数据可用
  8. 然后写一个命令来读取数据
  9. 读取数据
  10. 禁用设备

但是,此特定设备有其自己的详细信息,您的代码没有考虑到这些详细信息。

一些评论:

而不是请求数据转换的状态,您可以(应该)使用来自设备的中断信号来触发数据的读取。

数据表的图 10 显示:“显示了如何将 AS5050A 连接到微控制器。SPI 接口是用于访问片上寄存器的从接口。INT/ 输出是用于通知主机的低电平有效中断当有新结果可用时,微控制器。” 您发布的代码没有考虑该信号

请阅读段落:“阅读角度”了解如何开始转换、如何识别何时转换完成等的详细信息

于 2021-12-01T16:55:13.340 回答