FLIR Lepton 2无法向STM32F4传输帧数据的问题求助
我正尝试将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

