OpenEdv-开源电子网

 找回密码
 立即注册
正点原子全套STM32/Linux/FPGA开发资料,上千讲STM32视频教程免费下载...
查看: 3457|回复: 9

ov5640采集JPEG如何进入帧中断

[复制链接]

23

主题

117

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
251
金钱
251
注册时间
2019-8-7
在线时间
51 小时
发表于 2022-3-8 11:00:15 | 显示全部楼层 |阅读模式
1金钱
了原子的ov5640采集JPEG代码有点疑惑,jpeg_data_ok 采集完一帧后变成1,然后关掉DMA,然后main循环发送完JPEG到串口后改为jpeg_data_ok =2,之后他怎么再次进入jpeg_data_process的,不是已经关闭DMA了吗,怎么进入帧中断回调函数呢,jpeg_data_ok 就判断不了了,开启不了下一次DMA采集

volatile u8 jpeg_data_ok = 0;//JPEG数据采集完成标志
//0,数据没有采集完;
//1,数据采集完了,但是还没处理;
//2,数据已经处理完成了,可以开始下一帧接收



/捕获到一帧图像处理函数
//hdcmi DCMI句柄
void HAL_DCMI_FrameEventCallback(DCMI_HandleTypeDef *hdcmi)
{
        jpeg_data_process();//jpeg数据处理
        LED1_Toggle;
        ov_frame++;
    //重新使能帧中断,因为HAL_DCMI_IRQHandler()函数会关闭帧中断
    __HAL_DCMI_ENABLE_IT(&DCMI_Handler,DCMI_IT_FRAME);
}



//处理JPEG数据
//当采集完一帧JPEG数据后,调用此函数,切换JPEG BUF.开始下一帧采集.
void jpeg_data_process(void)
{
        u16 i;
        u16 rlen;                        //剩余数据长度
        u32 *pbuf;
        curline = yoffset;        //行数复位

        if(ovx_mode & 0X01)        //只有在JPEG格式下,才需要做处理.
                {
                        if(jpeg_data_ok == 0)        //jpeg数据还未采集完?
                                {
                                     __HAL_DMA_DISABLE(&DMADMCI_Handler);//关闭DMA
                                        rlen = jpeg_line_size - __HAL_DMA_GET_COUNTER(&DMADMCI_Handler); //得到剩余数据长度
                                        pbuf = jpeg_data_buf + jpeg_data_len; //偏移到有效数据末尾,继续添加

                                        //if(DMADMCI_Handler.Instance->CR&(1<<19))for(i=0;i<rlen;i++)pbuf=dcmi_line_buf[1];//读取buf1里面的剩余数据
                                        if(DMA1_Stream1->CR & (1 << 19))for(i = 0; i < rlen; i++)pbuf = dcmi_line_buf[1]; //读取buf1里面的剩余数据
                                        else for(i = 0; i < rlen; i++)pbuf = dcmi_line_buf[0]; //读取buf0里面的剩余数据

                                        jpeg_data_len += rlen;                        //加上剩余长度
                                        jpeg_data_ok = 1;                                 //标记JPEG数据采集完成,等待其他函数处理
                                }

                        if(jpeg_data_ok == 2)        //上一次的jpeg数据已经被处理了
                                {
                                        __HAL_DMA_SET_COUNTER(&DMADMCI_Handler, jpeg_line_size);        //传输长度为jpeg_buf_size*4字节
                                        __HAL_DMA_ENABLE(&DMADMCI_Handler); //打开DMA
                                        jpeg_data_ok = 0;                                          //标记数据未采集
                                        jpeg_data_len = 0;                                  //数据重新开始
                                }
                }
        else
                {
                        LCD_SetCursor(0, 0);
                        LCD_WriteRAM_Prepare();                //开始写入GRAM
                }
}

最佳答案

查看完整内容[请看2#楼]

重点是要找一下哪里有 jpeg_data_ok =2 还有就是,DMA与DCMI中断是两码事,关DMA并不影响DCMI中断, DCMI中断应当是由VSYNC引脚边沿触发,就像外部中断。
学习
正点原子逻辑分析仪DL16劲爆上市
回复

使用道具 举报

10

主题

3280

帖子

1

精华

论坛元老

Rank: 8Rank: 8

积分
8182
金钱
8182
注册时间
2020-5-11
在线时间
3694 小时
发表于 2022-3-8 11:00:16 | 显示全部楼层
溪悦哦 发表于 2022-3-8 14:56
原子的摄像头实验
/捕获到一帧图像处理函数
//hdcmi DCMI句柄

重点是要找一下哪里有 jpeg_data_ok =2
还有就是,DMA与DCMI中断是两码事,关DMA并不影响DCMI中断,
DCMI中断应当是由VSYNC引脚边沿触发,就像外部中断。
专治疑难杂症
回复

使用道具 举报

10

主题

3280

帖子

1

精华

论坛元老

Rank: 8Rank: 8

积分
8182
金钱
8182
注册时间
2020-5-11
在线时间
3694 小时
发表于 2022-3-8 11:22:58 | 显示全部楼层
或许有别的地方再次调用了jpeg_data_process()函数。
可以把工程传上来看看吗?
专治疑难杂症
回复

使用道具 举报

23

主题

117

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
251
金钱
251
注册时间
2019-8-7
在线时间
51 小时
 楼主| 发表于 2022-3-8 14:56:26 | 显示全部楼层
LcwSwust 发表于 2022-3-8 11:22
或许有别的地方再次调用了jpeg_data_process()函数。
可以把工程传上来看看吗?

原子的摄像头实验
/捕获到一帧图像处理函数
//hdcmi DCMI句柄
void HAL_DCMI_FrameEventCallback(DCMI_HandleTypeDef *hdcmi)
{
        jpeg_data_process();//jpeg数据处理
        LED1_Toggle;
        ov_frame++;
    //重新使能帧中断,因为HAL_DCMI_IRQHandler()函数会关闭帧中断
    __HAL_DCMI_ENABLE_IT(&DCMI_Handler,DCMI_IT_FRAME);
}
只有在这里调用,是不是关闭了DMA传输,DCMI还是会传输,帧中断依然产生?
学习
回复

使用道具 举报

23

主题

117

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
251
金钱
251
注册时间
2019-8-7
在线时间
51 小时
 楼主| 发表于 2022-3-8 16:14:15 | 显示全部楼层
LcwSwust 发表于 2022-3-8 15:26
重点是要找一下哪里有 jpeg_data_ok =2
还有就是,DMA与DCMI中断是两码事,关DMA并不影响DCMI中断,
...


while(1)
                {
                        if(jpeg_data_ok == 1)        //已经采集完一帧图像了
                                {
                                        p = (u8*)jpeg_data_buf;
                                        printf("jpeg_data_len:%d\r\n", jpeg_data_len * 4); //打印帧率
                                        LCD_ShowString(30, 210, 210, 16, 16, "Sending JPEG data..."); //提示正在传输数据
                                        jpglen = 0;        //设置jpg文件大小为0
                                        headok = 0;        //清除jpg头标记

                                        for(i = 0; i < jpeg_data_len * 4; i++) //查找0XFF,0XD8和0XFF,0XD9,获取jpg文件大小
                                                {
                                                        if((p == 0XFF) && (p[i + 1] == 0XD8)) //找到FF D8
                                                                {
                                                                        jpgstart = i;
                                                                        headok = 1;        //标记找到jpg头(FF D8)
                                                                }

                                                        if((p == 0XFF) && (p[i + 1] == 0XD9) && headok) //找到头以后,再找FF D9
                                                                {
                                                                        jpglen = i - jpgstart + 2;
                                                                        break;
                                                                }
                                                }
                                        if(jpglen)        //正常的jpeg数据
                                                {
                                                        p += jpgstart;                        //偏移到0XFF,0XD8处

                                                        for(i = 0; i < jpglen; i++)        //发送整个jpg文件
                                                                {
                                                                        USART2->TDR = p;

                                                                        while((USART2->ISR & 0X40) == 0);        //循环发送,直到发送完毕

                                                                        key = KEY_Scan(0);

                                                                        if(key)break;
                                                                }
                                                }

                                        else LCD_ShowString(30, 210, 210, 16, 16, "Send data complete!!"); //提示传输结束设置

                                        jpeg_data_ok = 2;        //标记jpeg数据处理完了,可以让DMA去采集下一帧了.
                                }
                }


在主循环这,发送完jpeg到串口就改成2

学习
回复

使用道具 举报

10

主题

3280

帖子

1

精华

论坛元老

Rank: 8Rank: 8

积分
8182
金钱
8182
注册时间
2020-5-11
在线时间
3694 小时
发表于 2022-3-8 16:19:34 | 显示全部楼层
溪悦哦 发表于 2022-3-8 16:14
while(1)
                {
                        if(jpeg_data_ok == 1)        //已经采集完一帧图像了

嗯,先前我也没注意,楼主的问题其实就是关DMA并不影响DCMI中断。
关DMA只是不让DCMI数据存入数组,中断不受影响,如同定时中断。
专治疑难杂症
回复

使用道具 举报

23

主题

117

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
251
金钱
251
注册时间
2019-8-7
在线时间
51 小时
 楼主| 发表于 2022-3-8 16:34:51 | 显示全部楼层
LcwSwust 发表于 2022-3-8 16:19
嗯,先前我也没注意,楼主的问题其实就是关DMA并不影响DCMI中断。
关DMA只是不让DCMI数据存入数组,中断 ...

对 我就是这个意思,就是帧中断回调函数关闭DMA传输是不影响摄像头传数据的,只不过数据都丢失了
学习
回复

使用道具 举报

23

主题

117

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
251
金钱
251
注册时间
2019-8-7
在线时间
51 小时
 楼主| 发表于 2022-3-8 16:37:29 | 显示全部楼层
那这个摄像头就是配置完后CPU不用管他了,他会自动传数据,开启DMA就搬运数据到对应内存了
学习
回复

使用道具 举报

1

主题

4

帖子

0

精华

新手上路

积分
44
金钱
44
注册时间
2024-2-5
在线时间
10 小时
发表于 2024-8-1 00:48:59 | 显示全部楼层
最近学习时也在困惑这一点,if (g_jpeg_data_ok == 2)  语句的执行,是不是又产生了一次帧中断但是这些数据没有DMA搬运,那是不是浪费了这一帧的时间,想着if (g_jpeg_data_ok == 2) 语句能不能在while(1){      g_jpeg_data_ok = 2;     /* 标记jpeg数据处理完了,可以让DMA去采集下一帧了. */ }  后面紧跟执行,这样就节省时间。
  
后来想了应该不能但是不确定,在处理上一帧数据时,DCMI仍然在接受数据,可能在接收一帧的中间数据,如果此时打开DMA应该会显示乱码,所以只能在一帧的开始时候打开dma。   
               
回复

使用道具 举报

1

主题

4

帖子

0

精华

新手上路

积分
44
金钱
44
注册时间
2024-2-5
在线时间
10 小时
发表于 2024-8-1 00:51:01 | 显示全部楼层
最近学习时也在困惑这一点,if (g_jpeg_data_ok == 2)  语句的执行,是不是又产生了一次帧中断但是这些数据没有DMA搬运,那是不是浪费了这一帧的时间,想着if (g_jpeg_data_ok == 2) 语句能不能在while(1){      g_jpeg_data_ok = 2;     /* 标记jpeg数据处理完了,可以让DMA去采集下一帧了. */ }  后面紧跟执行,这样就节省时间。
  
后来想了应该不能但是不确定,在处理上一帧数据时,DCMI仍然在接受数据,可能在接收一帧的中间数据,如果此时打开DMA应该会显示乱码,所以只能在一帧的开始时候打开dma。   
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则



关闭

原子哥极力推荐上一条 /2 下一条

正点原子公众号

QQ|手机版|OpenEdv-开源电子网 ( 粤ICP备12000418号-1 )

GMT+8, 2024-11-22 07:05

Powered by OpenEdv-开源电子网

© 2001-2030 OpenEdv-开源电子网

快速回复 返回顶部 返回列表