Curiousbaby_boy 2024-04-19 14:24 采纳率: 0%
浏览 18

stm32如何接收bmp图片数据存入一个数组中?

本来想用openmv发送图片给我的stm32进行处理?瞎搞了一天多了一点都不会。

  • 写回答

4条回答 默认 最新

  • 专家-赤兔[在线] 全栈领域优质创作者 2024-04-19 14:24
    关注

    引自免费微信小程序:皆我百晓生

    要在STM32上接收并存储BMP图片数据到数组中,你需要完成以下几个步骤:

    1. 理解BMP文件格式: BMP文件是一种位图文件格式,它包含文件头、信息头和像素数据三部分。

      • 文件头(14字节):包括文件类型标志("BM"),文件大小,剩余两个字段通常为0。
      • 信息头(40字节):包括图像宽度、高度、颜色深度等信息。
      • 像素数据:根据颜色深度不同,每个像素可能占用1、2、4或8个字节。
    2. STM32硬件配置: 确保你的STM32板子有串口通信功能,可以是USART、SPI或I2C等。这里我们以USART为例,配置串口以匹配OpenMV的波特率和数据格式。

    3. STM32软件实现

      • 编写STM32代码来接收来自OpenMV的数据,并解析BMP文件头和信息头。
      • 分配内存用于存储像素数据。
      • 根据信息头中的宽度、高度和颜色深度读取像素数据,并存储到数组中。

    下面是一个简化的示例代码,展示了如何在STM32F103C8T6上通过USART接收BMP数据并存储到数组中。注意,这个例子仅适用于1bpp的黑白BMP图像,如果你的BMP是其他颜色深度,需要相应地调整代码。

    首先,包含必要的库文件,并定义一些常量:

    #include "stm32f1xx_hal.h"
    #include "usart.h"
    
    #define USARTx GPIOA
    #define USART_PIN_TX GPIO_PIN_9
    #define USART_PIN_RX GPIO_PIN_10
    
    #define BAUDRATE 115200
    #define PARITY_NONE UART_PARITY_NONE
    #define STOPBITS_1 UART_STOPBITS_1
    #define WORDLENGTH_8BIT UART_WORDLENGTH_8B
    

    接下来,设置串口参数和中断回调函数:

    void MX_USART1_UART_Init(void)
    {
        GPIO_InitTypeDef GPIO_InitStruct = {0};
        USART_InitTypeDef USART_InitStruct = {0};
    
        /* Enable GPIO clock */
        __HAL_RCC_GPIOA_CLK_ENABLE();
    
        /* Configure GPIO pins */
        GPIO_InitStruct.Pin = GPIO_PIN_9 | GPIO_PIN_10;
        GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
        GPIO_InitStruct.Pull = GPIO_NOPULL;
        GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
        GPIO_InitStruct.Alternate = GPIO_AF7_USART1;
        HAL_GPIO_Init(USARTx, &GPIO_InitStruct);
    
        /* USART1 clock enable */
        __HAL_RCC_USART1_CLK_ENABLE();
    
        /* USART1 GPIO Configuration */
        HAL_NVIC_SetPriority(USART1_IRQn, 0, 0);
        HAL_NVIC_EnableIRQ(USART1_IRQn);
    
        /* USART1 Initialization */
        USART_InitStruct.BaudRate = BAUDRATE;
        USART_InitStruct.Parity = PARITY_NONE;
        USART_InitStruct.StopBits = STOPBITS_1;
        USART_InitStruct.WordLength = WORDLENGTH_8BIT;
        USART_InitStruct.HardwareFlowControl = UART_HWCONTROL_NONE;
        USART_InitStruct.Mode = UART_MODE_TX_RX;
        HAL_UART_Init(UART_HandleTypeDef.Instance, &USART_InitStruct);
    
        /* Enable USART Receive interrupt */
        __HAL_UART_ENABLE_IT(&UART_HandleTypeDef, UART_IT_RXNE);
    }
    
    extern UART_HandleTypeDef UART_HandleTypeDef;
    
    void USART_IRQHandler(void)
    {
        if (UART_HandleTypeDef.Instance->SR & UART_FLAG_RXNE) {
            uint8_t data = UART_HandleTypeDef.Instance->RDR;
            handle_data(data); // 在此处处理接收到的数据
        }
    }
    

    然后,编写一个函数来解析文件头和信息头,并分配内存:

    // 假设已经初始化了全局变量:uint8_t *bmpData; int width, height, colorDepth;
    void parse_bmp_header(uint8_t *data)
    {
        // 解析文件头(14字节)
        // ...
    
        // 解析信息头(40字节)
        // ...
        
        // 计算像素数据大小并分配内存
        bmpData = malloc(width * height * (colorDepth / 8));
    }
    

    最后,在handle_data()函数中接收和处理每一帧数据:

    void handle_data(uint8_t data)
    {
        static int byte_count = 0;
        static bool in_pixel_data = false;
    
        if (!in_pixel_data && byte_count < 54) { // 文件头和信息头共54字节
            parse_bmp_header(&data);
            in_pixel_data = true;
            return;
        }
    
        if (in_pixel_data) {
            bmpData[byte_count++] = data;
            if (byte_count >= width * height * (colorDepth / 8)) {
                in_pixel_data = false;
                byte_count = 0;
                process_image(bmpData, width, height, colorDepth); // 处理已接收的图像数据
            }
        }
    }
    

    这只是一个基本的框架,实际应用中可能需要更复杂的错误检查和处理。为了将完整的BMP图像从OpenMV发送到STM32,你需要在OpenMV端将BMP数据按照上面描述的格式打包成序列化的数据流,并通过串口发送出去。

    确保两边的波特率、停止位、数据位和校验位设置一致,这样STM32才能正确地接收和解析数据。在STM32上运行这段代码后,你应该能成功接收并存储BMP图片数据到数组中。根据你的具体需求,可以进一步优化和扩展代码,例如支持彩色BMP或更大尺寸的图像。

    评论 编辑记录

报告相同问题?

问题事件

  • 创建了问题 4月19日

悬赏问题

  • ¥15 校内二手商品转让网站
  • ¥20 高德地图聚合图层MarkerCluster聚合多个点,但是ClusterData只有其中部分数据,原因应该是有经纬度重合的地方点,现在我想让ClusterData显示所有点的信息,如何实现?
  • ¥100 求Web版SPC控制图程序包调式
  • ¥20 指导如何跑通以下两个Github代码
  • ¥15 大家知道这个后备文件怎么删吗,为啥这些文件我只看到一份,没有后备呀
  • ¥15 C++为什么这个代码没报错运行不出来啊
  • ¥15 一道ban了很多东西的pyjail题
  • ¥15 关于#r语言#的问题:如何将生成的四幅图排在一起,且对变量的赋值进行更改,让组合的图漂亮、美观@(相关搜索:森林图)
  • ¥15 C++识别堆叠物体异常
  • ¥15 微软硬件驱动认证账号申请