STM32H750 怎么接收640*480*2的RGB565的数据并且硬件压缩为一张JPEG图片

2019-07-20 01:01发布

我现在想使用STM32H750的DCMI从前端接收RGB565的数据,分辨率为640*480,并且将接收到的RGB565数据转为YUV并使用硬件JPEG压缩为JPEG图片,但由于SRAM不够,不能定义640*480*2的数组,于是我想这样,定一个640*32*2的数组,每次接收DCMI的RGB565的数据大小为640*480*32,并且接收完后再进行压缩,压缩完后再进行接收,但是问题是前端的时序是连续的,在32行后立刻就是第33行了,还没等我压缩完前32行的数据,33行的数据就已经到了。于是我想用两个640*32*2的buf,一个rgbbuf1[640*320*2],一个rgbbuf2[640*480*2],当接收完rgbbuf1的时候启动接收rgbbuf2,此时进行压缩rgbbuf1,等到rgbbuf1压缩完了,然后rgbbuf2接收完了(可能是rgbbuf1先压缩完,rgbbuf2才接收完,没验证),再重新启动接收rgbbuf1,并同时压缩rgbbuf2,这样乒乓操作直到整个图像压缩完,停止接收buf,这里我每次重新启动的函数分别是HAL_DCMI_Start_DMA(&hdcmi, DCMI_MODE_CONTINUOUS, (uint32_t)rgbbuf2, 640*32/2);和HAL_DCMI_Start_DMA(&hdcmi, DCMI_MODE_CONTINUOUS, (uint32_t)rgbbuf1, 640*32/2);但是好像每次HAL_DCMI_Start_DMA()函数之后都是从帧头开始接收的,而我是想从每次中断的地方开始接收,比如第32+1行,第64+1行,..开始接收,这个该怎么实现呢?
附上主要代码片段

/*****************************************************************************/
void HAL_DCMI_LineEventCallback(DCMI_HandleTypeDef *hdcmi)
{        
  Hs_count++;
        if(Hs_count == 32)
        {
                        Hs_count = 0;
                        Hs_32_ok = 1;
        }
        else
        {
                        Hs_32_ok = 0;
        }
}



/*****************************************************************************/
void save_pic(void)
{
        FATFS SDFatFs;  /* File system object for SD card logical drive */
        int res = 55;

        char filename[32];

        uint32_t bytesWritefile = 0;
        uint32_t JpegEncodeProcessing_End = 0;
       
        if(Usb_Connected == 1)
        {
                        return;
        }
       
        sprintf(filename, "0:/DCIM/PICTURE/IMG%05d.jpg", filesn);
        filenum++;
       
        FIL *pJpegFile;
        pJpegFile = &JPEG_File;
       

        if(f_mount(&SDFatFs, SDPath, 0) == FR_OK)
  {               
                        get_filenum();
                        get_freecap();
                 res = f_mkdir("0:/DCIM");
                 if(res == 0 )
                 {
                                HAL_GPIO_WritePin(GPIOB, GPIO_PIN_14,GPIO_PIN_SET);//sd debug
                 }
                 
     res = f_mkdir("0:/DCIM/PICTURE");
                 if(res == 0 )
                 {
                                HAL_GPIO_WritePin(GPIOB, GPIO_PIN_14,GPIO_PIN_SET);//sd debug
                 }
                if(f_open(&JPEG_File, filename, FA_CREATE_ALWAYS | FA_WRITE) == FR_OK)
                {                       
                        JPEG_Encode_DMA(&hjpeg, &JPEG_File);
                       
                        do
                        {
                                JPEG_EncodeInputHandler(&hjpeg);
                                JpegEncodeProcessing_End = JPEG_EncodeOutputHandler(&hjpeg);
                               
                        }while(JpegEncodeProcessing_End == 0);

                        f_close(&JPEG_File);
                }
        }
}


/*****************************************************************************/
uint32_t JPEG_Encode_DMA(JPEG_HandleTypeDef *hjpeg, FIL *jpgfile)
{
  pJpegFile = jpgfile;


  /* Reset all Global variables */
  MCU_TotalNb                = 0;
  MCU_BlockIndex             = 0;
  Jpeg_HWEncodingEnd         = 0;
  Output_Is_Paused           = 0;
  Input_Is_Paused            = 0;
  CurrentLine                = 1;


   SetImgInfo(&Conf);//++0603
       
  JPEG_GetEncodeColorConvertFunc(&Conf, &pRGBToYCbCr_Convert_Function, &MCU_TotalNb);

  /* Clear Output Buffer */
  Jpeg_OUT_BufferTab.DataBufferSize = 640*32*2;//--0622 0
  Jpeg_OUT_BufferTab.State = JPEG_BUFFER_EMPTY;

        HAL_DCMI_Start_DMA(&hdcmi, DCMI_MODE_CONTINUOUS, (uint32_t)rgbbuf, 640*32/2);//++0630 DCMI_MODE_CONTINUOUS
        while(Hs_32_ok == 0)
                ;
        rgbbuf_num = 0;
        switch (rgbbuf_num)
        {
                        case 0:
                        {
                                        rgbbuf_num = 1;
                                        HAL_DCMI_Stop(&hdcmi);
                                        HAL_DCMI_Start_DMA(&hdcmi, DCMI_MODE_CONTINUOUS, (uint32_t)rgbbuf2, 640*32/2);//++0630 DCMI_MODE_CONTINUOUS
       
                                        MCU_BlockIndex += pRGBToYCbCr_Convert_Function(rgbbuf, Jpeg_IN_BufferTab.DataBuffer, 0, 640*32*2,(uint32_t*)(&Jpeg_IN_BufferTab.DataBufferSize));
                                        break;
                        }
                        case 1:
                        {
                                        rgbbuf_num = 0;
                                        HAL_DCMI_Stop(&hdcmi);
                                        HAL_DCMI_Start_DMA(&hdcmi, DCMI_MODE_CONTINUOUS, (uint32_t)rgbbuf, 640*32/2);//++0630 DCMI_MODE_CONTINUOUS
                               
                                        MCU_BlockIndex += pRGBToYCbCr_Convert_Function(rgbbuf2, Jpeg_IN_BufferTab.DataBuffer, 0, 640*32*2,(uint32_t*)(&Jpeg_IN_BufferTab.DataBufferSize));
                                        break;
                        }
        }
       
        Jpeg_IN_BufferTab.State = JPEG_BUFFER_FULL;

        /* Fill Encoding Params */
        HAL_JPEG_ConfigEncoding(hjpeg, &Conf);

        /* Start JPEG encoding with DMA method */
        HAL_JPEG_Encode_DMA(hjpeg ,Jpeg_IN_BufferTab.DataBuffer ,Jpeg_IN_BufferTab.DataBufferSize ,Jpeg_OUT_BufferTab.DataBuffer ,CHUNK_SIZE_OUT);
       


  return 0;
}


/*****************************************************************************/
void JPEG_EncodeInputHandler(JPEG_HandleTypeDef *hjpeg)
{
  uint32_t dataBufferSize = 0;

  if((Jpeg_IN_BufferTab.State == JPEG_BUFFER_EMPTY) && (MCU_BlockIndex <= MCU_TotalNb))   
  {


                        while(Hs_32_ok ==0)
                                ;
                        Hs_32_ok = 0;
                        switch (rgbbuf_num)
                        {
                                        case 0:
                                        {
                                                        rgbbuf_num = 1;
                                                        HAL_DCMI_Stop(&hdcmi);
                                                        HAL_DCMI_Start_DMA(&hdcmi, DCMI_MODE_CONTINUOUS, (uint32_t)rgbbuf2, 640*32/2);//++0630 DCMI_MODE_CONTINUOUS
                       
                                                        MCU_BlockIndex += pRGBToYCbCr_Convert_Function(rgbbuf, Jpeg_IN_BufferTab.DataBuffer, 0, 640*32*2,(uint32_t*)(&Jpeg_IN_BufferTab.DataBufferSize));
                                                        break;
                                        }
                                        case 1:
                                        {
                                                        rgbbuf_num = 0;
                                                        HAL_DCMI_Stop(&hdcmi);
                                                        HAL_DCMI_Start_DMA(&hdcmi, DCMI_MODE_CONTINUOUS, (uint32_t)rgbbuf, 640*32/2);//++0630 DCMI_MODE_CONTINUOUS
                                               
                                                        MCU_BlockIndex += pRGBToYCbCr_Convert_Function(rgbbuf2, Jpeg_IN_BufferTab.DataBuffer, 0, 640*32*2,(uint32_t*)(&Jpeg_IN_BufferTab.DataBufferSize));
                                                        break;
                                        }
                        }


      Jpeg_IN_BufferTab.State = JPEG_BUFFER_FULL;
                       

      if(Input_Is_Paused == 1)
      {
        Input_Is_Paused = 0;
        HAL_JPEG_ConfigInputBuffer(hjpeg,Jpeg_IN_BufferTab.DataBuffer, Jpeg_IN_BufferTab.DataBufferSize);   

        HAL_JPEG_Resume(hjpeg, JPEG_PAUSE_RESUME_INPUT);
      }

  }
}



/*****************************************************************************/
uint32_t JPEG_EncodeOutputHandler(JPEG_HandleTypeDef *hjpeg)
{
  uint32_t bytesWritefile = 0;

  if(Jpeg_OUT_BufferTab.State == JPEG_BUFFER_FULL)
  {  
    f_write (pJpegFile, Jpeg_OUT_BufferTab.DataBuffer ,Jpeg_OUT_BufferTab.DataBufferSize, (UINT*)(&bytesWritefile)) ;

    Jpeg_OUT_BufferTab.State = JPEG_BUFFER_EMPTY;
    Jpeg_OUT_BufferTab.DataBufferSize = 0;//--0622 0

    if(Jpeg_HWEncodingEnd != 0)
    {
      return 1;
    }
    else if(Output_Is_Paused == 1)
    {
      Output_Is_Paused = 0;
      HAL_JPEG_Resume(hjpeg, JPEG_PAUSE_RESUME_OUTPUT);            
    }   
  }

  return 0;  
}








友情提示: 此问题已得到解决,问题已经关闭,关闭后问题禁止继续编辑,回答。