You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

FLIR Lepton 2无法向STM32F4传输帧数据的问题求助

FLIR Lepton 2与STM32F4 Discovery SPI读取帧数据异常问题

我正尝试将FLIR Lepton 2(搭配Lepton Breakout board v1.4)与STM32F4 Discovery开发板集成,实现通过SPI读取80×60的帧数据,再经UART发送至Flutter客户端。目前硬件连接正常,但读取Lepton帧数据环节出现问题,持续收到固定的缓冲数据,推测是错误信息而非有效图像帧,查阅 datasheet 未找到解决思路。

读取与处理帧数据的核心代码

ReadFrame函数(读取帧数据到缓冲区)

void ReadFrame(uint8_t *frameData)
{
    uint8_t *tmp = frameData;

    GPIO_PinState csState;
    uint8_t write_data = 0x0;

    csState = HAL_GPIO_ReadPin(CS_PORT, CS_PIN);
    if (csState == GPIO_PIN_SET)
    {
        HAL_GPIO_WritePin(CS_PORT, CS_PIN, GPIO_PIN_RESET);
        HAL_SPI_Transmit(&hspi1, &write_data, sizeof(write_data), HAL_MAX_DELAY);

        for (uint16_t i = 0; i < VOSPI_VIDEO_PACKETS_PER_FRAME; i++)
        {
            HAL_SPI_Receive(&hspi1, tmp, VOSPI_PACKET_LENGTH, HAL_MAX_DELAY);
            tmp += VOSPI_PACKET_LENGTH;
        }

        HAL_GPIO_WritePin(CS_PORT, CS_PIN, GPIO_PIN_SET);
    }
}

该函数负责将当前帧数据存入uint8_t*缓冲:先将CS引脚置为LOW,执行SPI请求,遍历读取每个数据包(对应帧的一行),最后将CS置为HIGH。

handleFrame函数(移除数据包Header)

根据datasheet说明,每个数据包包含4字节header和160字节payload(Raw14格式,每个像素占2字节),该函数用于移除数据包header:

void handleFrame(uint8_t *frameData, uint8_t *newFrameData)
{
    int packetCount = 0;

    for (int i = 0; i < VOSPI_PACKET_LENGTH * packetCount; i +=
        VOSPI_PACKET_LENGTH)
    {
        for (int j = 0; j < VOSPI_PACKET_LENGTH - VOSPI_HEADER_SIZE; j++)
        {
            newFrameData[(i / VOSPI_PACKET_LENGTH)
                * (VOSPI_PACKET_LENGTH - VOSPI_HEADER_SIZE) + j] =
                frameData[i + VOSPI_HEADER_SIZE + j];
        }
    }
}

主代码调用逻辑

uint8_t frameData[VOSPI_PACKET_LENGTH * VOSPI_VIDEO_PACKETS_PER_FRAME];
uint8_t newFrameData[COLS * ROWS * PIXEL_SIZE];

memset(frameData, 0, sizeof(frameData));
memset(newFrameData, 0, sizeof(newFrameData));

while(/* 连接状态判断 */)
{
    ReadFrame(frameData);
    handleFrame(frameData, newFrameData);

    // 通过UART发送newFrameData
}

异常现象

执行后得到的缓冲数据始终为:[83, 101, 114, 105, 97, 108, 32, 80, 111, 114, 116, 32, 84, 101, 115, ...](共9600字节)。

当前SPI配置

static void MX_SPI1_Init(void)
{
    /* SPI1 parameter configuration*/
    hspi1.Instance = SPI1;
    hspi1.Init.Mode = SPI_MODE_MASTER;
    hspi1.Init.Direction = SPI_DIRECTION_2LINES;
    hspi1.Init.DataSize = SPI_DATASIZE_16BIT;
    hspi1.Init.CLKPolarity = SPI_POLARITY_HIGH;
    hspi1.Init.CLKPhase = SPI_PHASE_2EDGE;
    hspi1.Init.NSS = SPI_NSS_SOFT;
    hspi1.Init.BaudRatePrescaler = SPI_BAUDRATEPRESCALER_2;
    hspi1.Init.FirstBit = SPI_FIRSTBIT_MSB;
    hspi1.Init.TIMode = SPI_TIMODE_DISABLE;
    hspi1.Init.CRCCalculation = SPI_CRCCALCULATION_ENABLE;
    hspi1.Init.CRCPolynomial = 10;

    if (HAL_SPI_Init(&hspi1) != HAL_OK)
    {
        Error_Handler();
    }
}

问题排查与修复建议

1. handleFrame函数致命错误

packetCount初始化为0,导致外层循环完全不执行,newFrameData始终保持memset后的全0状态。需将packetCount设置为实际的帧包数量VOSPI_VIDEO_PACKETS_PER_FRAME(对应60行,每行一个数据包)。修改后的函数:

void handleFrame(uint8_t *frameData, uint8_t *newFrameData)
{
    int packetCount = VOSPI_VIDEO_PACKETS_PER_FRAME; // 修正为实际包数量

    for (int i = 0; i < VOSPI_PACKET_LENGTH * packetCount; i += VOSPI_PACKET_LENGTH)
    {
        for (int j = 0; j < VOSPI_PACKET_LENGTH - VOSPI_HEADER_SIZE; j++)
        {
            newFrameData[(i / VOSPI_PACKET_LENGTH) * (VOSPI_PACKET_LENGTH - VOSPI_HEADER_SIZE) + j] =
                frameData[i + VOSPI_HEADER_SIZE + j];
        }
    }
}

2. SPI配置关键错误

Lepton 2的SPI通信有严格的参数要求,当前配置多处不符合:

  • 数据宽度:Lepton要求8位数据宽度,当前设置为SPI_DATASIZE_16BIT,需改为SPI_DATASIZE_8BIT。
  • CRC计算:Lepton默认不使用SPI CRC,当前SPI_CRCCALCULATION_ENABLE会额外发送CRC字节干扰通信,需改为SPI_CRCCALCULATION_DISABLE。
  • 波特率:Lepton 2的SPI最大支持20MHz,当前SPI_BAUDRATEPRESCALER_2对应主频168MHz下的84MHz,远超上限,需降低至SPI_BAUDRATEPRESCALER_16(对应10.5MHz)。

修改后的SPI初始化函数:

static void MX_SPI1_Init(void)
{
    /* SPI1 parameter configuration*/
    hspi1.Instance = SPI1;
    hspi1.Init.Mode = SPI_MODE_MASTER;
    hspi1.Init.Direction = SPI_DIRECTION_2LINES;
    hspi1.Init.DataSize = SPI_DATASIZE_8BIT; // 修正为8位
    hspi1.Init.CLKPolarity = SPI_POLARITY_HIGH;
    hspi1.Init.CLKPhase = SPI_PHASE_2EDGE;
    hspi1.Init.NSS = SPI_NSS_SOFT;
    hspi1.Init.BaudRatePrescaler = SPI_BAUDRATEPRESCALER_16; // 降低波特率到10.5MHz
    hspi1.Init.FirstBit = SPI_FIRSTBIT_MSB;
    hspi1.Init.TIMode = SPI_TIMODE_DISABLE;
    hspi1.Init.CRCCalculation = SPI_CRCCALCULATION_DISABLE; // 关闭CRC
    hspi1.Init.CRCPolynomial = 10;

    if (HAL_SPI_Init(&hspi1) != HAL_OK)
    {
        Error_Handler();
    }
}

3. ReadFrame函数优化

无需提前检查CS引脚状态,直接拉低CS即可开始传输,避免外部干扰导致的CS状态误判。此外,Lepton的SPI通信中主机发送的字节可以是任意值,但需确保每次接收前有足够的时钟触发,当前的HAL_SPI_Transmit逻辑保留即可。

4. 异常数据解析

你收到的[83,101,...]是ASCII字符串"Serial Port Test...",这是Lepton在SPI通信失败时返回的默认测试数据,说明当前SPI通信完全未建立,需优先解决上述SPI配置和handleFrame的致命错误。

内容的提问来源于stack exchange,提问作者progi15

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.20 18:24:57