初级会员

- 积分
- 50
- 金钱
- 50
- 注册时间
- 2019-6-14
- 在线时间
- 13 小时
|
15金钱
我现在想使用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;
}
|
最佳答案
查看完整内容[请看2#楼]
找到了一个替代的解决方案,就是拍照的时候定格,然后第一场拍第一个32行,第二场拍第二个32行(33-64行),....依次类推,测试可以解决问题,这样拍一个640*480的图片,需要480/32=15场,测试可以解决问题
|