OpenEdv-开源电子网

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

OV2640二值化的分辨率提升 呼唤原子哥

[复制链接]

13

主题

52

帖子

0

精华

初级会员

Rank: 2

积分
148
金钱
148
注册时间
2017-2-8
在线时间
39 小时
发表于 2017-7-24 18:54:30 | 显示全部楼层 |阅读模式
1金钱
因为摄像头实验例程里,DMA_BufferSize为16位的,最大支持65536,超过该大小的数据会编译不过。分辨率被限制在220*280左右。

然后自己的想法是分多次传输存储到外部SRAM。
外部SRAM地址从0x6800 0000开始,定义一个sram_buf[400*300/2] at0x6800 0000de 的数组用来存储数据

下面代码的基本思路是:有数据时触发中断,每次传输200*150/2的数据,传输完以后地址增加,再穿下一帧。但画面始终不对
是思路错了?还是设置有问题?

[mw_shl_code=applescript,true]void DMA2_Stream1_IRQHandler(void)
{
        //u32 addr=0x68000000;
        if(DMA_GetFlagStatus(DMA2_Stream1,DMA_FLAG_TCIF1)==SET)//DMA2_Steam1,传输完成标志
        {
                 DCMI_DMA_Init(addr,200*150/2,DMA_MemoryDataSize_Word,DMA_MemoryInc_Enable);
                 addr += 200*150/2;
DMA_ClearFlag(DMA2_Stream1,DMA_FLAG_TCIF1);//清除传输完成中断       
        }
        if(addr >= 0x6803A97C)
                addr = 0x68000000;

} [/mw_shl_code]

正点原子逻辑分析仪DL16劲爆上市
回复

使用道具 举报

13

主题

52

帖子

0

精华

初级会员

Rank: 2

积分
148
金钱
148
注册时间
2017-2-8
在线时间
39 小时
 楼主| 发表于 2017-7-25 13:32:29 来自手机 | 显示全部楼层
顶上去,原子哥在哪里
回复

使用道具 举报

13

主题

52

帖子

0

精华

初级会员

Rank: 2

积分
148
金钱
148
注册时间
2017-2-8
在线时间
39 小时
 楼主| 发表于 2017-7-25 19:53:08 | 显示全部楼层
原子哥能不能给点提示啊,就是想要传输大于65535数据时,该怎么处理
回复

使用道具 举报

530

主题

11万

帖子

34

精华

管理员

Rank: 12Rank: 12Rank: 12

积分
165508
金钱
165508
注册时间
2010-12-1
在线时间
2115 小时
发表于 2017-7-26 00:29:10 | 显示全部楼层
降低摄像头的输出速率。  采用双缓冲,比如一个缓冲是10K(双缓冲必须是内部SRAM),传输完一个后,拷贝这个倒外部SRAM,使用另外一个缓冲接收。
回复

使用道具 举报

13

主题

52

帖子

0

精华

初级会员

Rank: 2

积分
148
金钱
148
注册时间
2017-2-8
在线时间
39 小时
 楼主| 发表于 2017-7-26 21:12:27 | 显示全部楼层
正点原子 发表于 2017-7-26 00:29
降低摄像头的输出速率。  采用双缓冲,比如一个缓冲是10K(双缓冲必须是内部SRAM),传输完一个后,拷贝这 ...

哥,根据你的提示,利用照相机实验进行了修改,代码如下。
但是白屏。貌似中断没进去
思路错了吗

[mw_shl_code=c,true]#include "sys.h"
#include "delay.h"
#include "usart.h"
#include "led.h"
#include "lcd.h"
#include "key.h"  
#include "sram.h"   
#include "malloc.h"
#include "usmart.h"  
#include "sdio_sdcard.h"   
#include "malloc.h"
#include "w25qxx.h"   
#include "ff.h"  
#include "exfuns.h"   
#include "fontupd.h"
#include "text.h"       
#include "piclib.h"       
#include "string.h"       
#include "math.h"       
#include "dcmi.h"       
#include "ov2640.h"       
#include "beep.h"       
#include "timer.h"
//ALIENTEK 探索者STM32F407开发板 实验42
//照相机 实验 -库函数版本
//技术支持:www.openedv.com
//淘宝店铺:http://eboard.taobao.com
//广州市星翼电子科技有限公司   
//作者:正点原子 @alientek

u8 ov2640_mode=0;                                                //工作模式:0,RGB565模式;1,JPEG模式

#define jpeg_dma_bufsize        5*1024                //定义JPEG DMA接收时数据缓存jpeg_buf0/1的大小(*4字节)
volatile u32 data_len=0;                         //buf中的JPEG有效数据长度(*4字节)
volatile u8 data_ok=0;                                //JPEG数据采集完成标志
                                                                                                                        //0,数据没有采集完;
                                                                                                                        //1,数据采集完了,但是还没处理;
                                                                                                                        //2,数据已经处理完成了,可以开始下一帧接收
                                                                               
u32 *jpeg_buf0;                                                                //JPEG数据缓存buf,通过malloc申请内存
u32 *jpeg_buf1;                                                                //JPEG数据缓存buf,通过malloc申请内存
u32 *sram_buf;                                                                //JPEG数据缓存buf,通过malloc申请内存

#define width                400
#define height        300
#define  yuv_sram_buf_size width*height*2/4
//__align(4) u32 sram_buf[yuv_sram_buf_size] __attribute__((at(0X6800000)));

//函数功能:YUV422格式转灰度图像(RGB565格式显示)
//yuv422:yuv格式数据
u16 yuv422_to_Gray(u16 yuv422)
{
        u16 Gray;        //用于储存灰度值变量(RGB565格式显示)
        Gray =(((yuv422>>(8+3))<<11)|((yuv422>>(8+2))<<5)|((yuv422>>(8+3))<<0));//Y量转为灰度值(RGB565格式显示)
        return Gray;        //返回灰度图像值(RGB565格式显示)
}

//处理JPEG数据
//当采集完一帧JPEG数据后,调用此函数,切换JPEG BUF.开始下一帧采集.
extern void data_process(void)
{
        u16 i;
        u16 rlen;//剩余数据长度
        u32 *pbuf;
        if(ov2640_mode)//只有在JPEG格式下,才需要做处理.
        {
                if(data_ok==0)        //jpeg数据还未采集完?
                {
                        DMA_Cmd(DMA2_Stream1,DISABLE);                //停止当前传输
                        while(DMA_GetCmdStatus(DMA2_Stream1) != DISABLE);        //等待DMA2_Stream1可配置
                        rlen=jpeg_dma_bufsize-DMA_GetCurrDataCounter(DMA2_Stream1);//得到剩余数据长度       
                        pbuf=pbuf+data_len;//偏移到有效数据末尾,继续添加
                        if(DMA2_Stream1->CR&(1<<19))
                                for(i=0;i<rlen;i++)
                                        pbuf=jpeg_buf1;//读取buf1里面的剩余数据
                        else
                                for(i=0;i<rlen;i++)
                                        pbuf=jpeg_buf0;//读取buf0里面的剩余数据
                        data_len+=rlen;                        //加上剩余长度
                        data_ok=1;                                 //标记JPEG数据采集完按成,等待其他函数处理
                }
                if(data_ok==2)        //上一次的jpeg数据已经被处理了
                { DMA_SetCurrDataCounter(DMA2_Stream1,jpeg_dma_bufsize);//传输长度为jpeg_buf_size*4字节
                        DMA_Cmd(DMA2_Stream1,ENABLE); //重新传输
                        data_ok=0;                                        //标记数据未采集
                        data_len=0;                                //数据重新开始
                }
        }
}

//jpeg数据接收回调函数
void jpeg_dcmi_rx_callback(void)
{
        u16 i;
        //u32 *pbuf;
        sram_buf=sram_buf+data_len;//偏移到有效数据末尾
        if(DMA2_Stream1->CR&(1<<19))//buf0已满,正常处理buf1
        {
                for(i=0;i<jpeg_dma_bufsize;i++)
                        sram_buf=jpeg_buf0;//读取buf0里面的数据
                data_len+=jpeg_dma_bufsize;//偏移
        }else //buf1已满,正常处理buf0
        {
                for(i=0;i<jpeg_dma_bufsize;i++)
                        sram_buf=jpeg_buf1;//读取buf1里面的数据
                data_len+=jpeg_dma_bufsize;//偏移
        }        
}
//切换为OV2640模式(GPIOC8/9/11切换为 DCMI接口)
void sw_ov2640_mode(void)
{
        OV2640_PWDN=0;//OV2640 Power Up
        GPIO_PinAFConfig(GPIOC,GPIO_PinSource8,GPIO_AF_DCMI);  //PC8,AF13  DCMI_D2
        GPIO_PinAFConfig(GPIOC,GPIO_PinSource9,GPIO_AF_DCMI);  //PC9,AF13  DCMI_D3
        GPIO_PinAFConfig(GPIOC,GPIO_PinSource11,GPIO_AF_DCMI); //PC11,AF13 DCMI_D4  

}   
int main(void)
{
        sw_ov2640_mode();
        NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);//设置系统中断优先级分组2
        delay_init(168);  //初始化延时函数
        uart_init(115200);                //初始化串口波特率为115200
        LED_Init();                                        //初始化LED
        TIM3_Int_Init(10000-1,8400-1);//10Khz计数,1秒钟中断一次
        LCD_Init();                                        //LCD初始化  
        FSMC_SRAM_Init();                        //初始化外部SRAM.
        KEY_Init();                                        //按键初始化   
        my_mem_init(SRAMIN);                //初始化内部内存池
        my_mem_init(SRAMEX);                //初始化内部内存池  
        my_mem_init(SRAMCCM);                //初始化CCM内存池
        POINT_COLOR=RED;
        while(font_init())                 //检查字库
        {            
                LCD_ShowString(30,50,200,16,16,"Font Error!");
                delay_ms(200);                                  
                LCD_Fill(30,50,240,66,WHITE);//清除显示             
                delay_ms(200);                                  
        }       
        Show_Str(30,50,200,16,"Explorer STM32F4开发板",16,0);                                              
        Show_Str(30,70,200,16,"照相机实验",16,0);                                             
        Show_Str(30,90,200,16,"KEY0:拍照(bmp格式)",16,0);                                     
        Show_Str(30,110,200,16,"KEY1:拍照(jpg格式)",16,0);                                                     
        Show_Str(30,130,200,16,"WK_UP:FullSize/Scale",16,0);                                             
        Show_Str(30,150,200,16,"2014年5月16日",16,0);
               
        jpeg_buf0=mymalloc(SRAMIN,jpeg_dma_bufsize*4);        //为jpeg dma接收申请内存       
        jpeg_buf1=mymalloc(SRAMIN,jpeg_dma_bufsize*4);        //为jpeg dma接收申请内存       
        sram_buf=mymalloc(SRAMEX,yuv_sram_buf_size);                //为jpeg文件申请内存(最大300KB)

        while(OV2640_Init())//初始化OV2640
        {
                Show_Str(30,190,240,16,"OV2640 错误!",16,0);
                delay_ms(200);
          LCD_Fill(30,190,239,206,WHITE);
                delay_ms(200);
        }       
        Show_Str(30,190,200,16,"OV2640 正常",16,0);
        OV2640_YUV422_Mode();        //JPEG模式
        My_DCMI_Init();                        //DCMI配置
         
        OV2640_OutSize_Set(width,height);
        DCMI_Start();                         //启动传输
        while(1)
        {       
                LCD_Clear(WHITE);
                POINT_COLOR = RED;
                My_DCMI_Init();       
                DCMI_DMA_Init((u32)&jpeg_buf0,(u32)&jpeg_buf1,jpeg_dma_bufsize,DMA_MemoryDataSize_Word,DMA_MemoryInc_Disable);//DCMI DMA配置                
                //OV2640_ImageWin_Set(0,0,width,height);//1:1真实尺寸
                OV2640_OutSize_Set(height,width);
                while(1)
                {
                        u16 i,temp_h,temp_l;
                        delay_ms(10);
                        OV2640_YUV422_Mode();
                        DCMI_Start();
                        DCMI_Stop();
                        LCD_Set_Window(0,0,height,width);
                        LCD_WriteRAM_Prepare();
                       
                        for(i=0;i<yuv_sram_buf_size;i++)
                        {       
                                //printf("addr[%d] = 0x%08x\n",i,(u32)&sram_buf);
                                temp_l=(u16)(sram_buf);
                                //printf("%d\n",sram_buf);
                                if(temp_l>0x7FFF)
                                        temp_l = 0xffff;
                                else
                                        temp_l=0x00;
                                LCD_WriteRAM(yuv422_to_Gray(temp_l));
                               
                                temp_h=(u16)(sram_buf>>16);
                                if(temp_h>0x7FFF)
                                        temp_h = 0xffff;
                                else
                                        temp_h=0x00;
                                LCD_WriteRAM(yuv422_to_Gray(temp_h));
                        }
               
                }
        }
}
[/mw_shl_code]
回复

使用道具 举报

530

主题

11万

帖子

34

精华

管理员

Rank: 12Rank: 12Rank: 12

积分
165508
金钱
165508
注册时间
2010-12-1
在线时间
2115 小时
发表于 2017-7-27 00:03:10 | 显示全部楼层
2hen9x1 发表于 2017-7-26 21:12
哥,根据你的提示,利用照相机实验进行了修改,代码如下。
但是白屏。貌似中断没进去
思路错了吗

慢慢改,方法就是这样
我是开源电子网www.openedv.com站长,有关站务问题请与我联系。
正点原子STM32开发板购买店铺http://openedv.taobao.com
正点原子官方微信公众平台,点击这里关注“正点原子”
回复

使用道具 举报

13

主题

52

帖子

0

精华

初级会员

Rank: 2

积分
148
金钱
148
注册时间
2017-2-8
在线时间
39 小时
 楼主| 发表于 2017-8-1 22:36:46 | 显示全部楼层
正点原子 发表于 2017-7-27 00:03
慢慢改,方法就是这样

原子哥,利用内部SRAM接近成功了
画面的顶部(高度有几个像素高的横条)会一直闪烁
就差一点点了,帮忙看看是不是哪里逻辑错了
下面是DMA的中断函数
[mw_shl_code=c,true]void DMA2_Stream1_IRQHandler(void)
{
        u16 i=0;
        u16 temp_h,temp_l;
        delay_us(300);
        if(DMA_GetFlagStatus(DMA2_Stream1,DMA_FLAG_TCIF1)==SET){//DMA2_Steam1,传输完成标志
                 if(DMA2_Stream1->CR&(1<<19)){//buf0已满,正常处理buf1
                         for(i=0;i<bufsize;i++){
                                 temp_l=(u16)(yuv422_to_Gray(jpeg_buf0));
                                if(temp_l>0x7FFF)        temp_l = 0xffff;
                                else                                                        temp_l=0x00;                               
                                LCD_WriteRAM(temp_l);       
                               
                                temp_h=(u16)(yuv422_to_Gray(jpeg_buf0)>>16);
                                if(temp_h>0x7FFF)        temp_h = 0xffff;
                                else                                                        temp_h=0x00;
                                LCD_WriteRAM(temp_h);       
                        }
                }                 
                 else{//buf1已满,正常处理buf0
                       
                         for(i=0;i<bufsize;i++){
                                 temp_l=(u16)(yuv422_to_Gray(jpeg_buf1));
                                if(temp_l>0x7FFF) temp_l = 0xffff;
                                else                                                        temp_l=0x00;
                                LCD_WriteRAM(temp_l);                               
                                temp_h=(u16)(yuv422_to_Gray(jpeg_buf1)>>16);                               
                                if(temp_h>0x7FFF)        temp_h = 0xffff;
                                else                                                        temp_h=0x00;
                                LCD_WriteRAM(temp_h);
                        }                       
                        }                                       
        }
        DMA_ClearFlag(DMA2_Stream1,DMA_FLAG_TCIF1);//清除传输完成中断
}[/mw_shl_code]

main函数基本就是初始化了
[mw_shl_code=c,true]void sw_ov2640_mode(void)
{
        OV2640_PWDN=0;//OV2640 Power Up
        GPIO_PinAFConfig(GPIOC,GPIO_PinSource8,GPIO_AF_DCMI);  //PC8,AF13  DCMI_D2
        GPIO_PinAFConfig(GPIOC,GPIO_PinSource9,GPIO_AF_DCMI);  //PC9,AF13  DCMI_D3
        GPIO_PinAFConfig(GPIOC,GPIO_PinSource11,GPIO_AF_DCMI); //PC11,AF13 DCMI_D4  

}   
int main(void)
{
        sw_ov2640_mode();
        NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);//设置系统中断优先级分组2
        delay_init(168);  //初始化延时函数
        uart_init(115200);                //初始化串口波特率为115200
        LED_Init();                                        //初始化LED
        TIM3_Int_Init(10000-1,8400-1);//10Khz计数,1秒钟中断一次
        LCD_Init();                                        //LCD初始化  
        FSMC_SRAM_Init();                        //初始化外部SRAM.
        KEY_Init();                                        //按键初始化   
        POINT_COLOR=RED;
        while(font_init())                 //检查字库
        {            
                LCD_ShowString(30,50,200,16,16,"Font Error!");
                delay_ms(200);                                  
                LCD_Fill(30,50,240,66,WHITE);//清除显示             
                delay_ms(200);                                  
        }       
        Show_Str(30,50,200,16,"Explorer STM32F4开发板",16,0);                                              
        Show_Str(30,70,200,16,"照相机实验",16,0);                                             
        Show_Str(30,90,200,16,"KEY0:拍照(bmp格式)",16,0);                                     
        Show_Str(30,110,200,16,"KEY1:拍照(jpg格式)",16,0);                                                     
        Show_Str(30,130,200,16,"WK_UP:FullSize/Scale",16,0);                                             
        Show_Str(30,150,200,16,"2014年5月16日",16,0);
               
        //jpeg_buf0=mymalloc(SRAMIN,bufsize);        //为jpeg dma接收申请内存       
        //jpeg_buf1=mymalloc(SRAMIN,bufsize);        //为jpeg dma接收申请内存       
        //sram_buf=mymalloc(SRAMEX,yuv_sram_buf_size);                //为jpeg文件申请内存(最大300KB)

        while(OV2640_Init())//初始化OV2640
        {
                Show_Str(30,190,240,16,"OV2640 错误!",16,0);
                delay_ms(200);
          LCD_Fill(30,190,239,206,WHITE);
                delay_ms(200);
        }       
        Show_Str(30,190,200,16,"OV2640 正常",16,0);
        LCD_Clear(WHITE);
        OV2640_YUV422_Mode();        //JPEG模式
        My_DCMI_Init();                        //DCMI配置
        //OV2640_ImageWin_Set((1600-480)/2,(1600-800)/2,480,800);//1:1真实尺寸       
        OV2640_OutSize_Set(width1,height1);
        LCD_Set_Window(0,0,width1,height1);
        DCMI_DMA_Init((u32)&jpeg_buf0,(u32)&jpeg_buf1,bufsize,DMA_MemoryDataSize_Word,DMA_MemoryInc_Enable);//DCMI DMA配置       
        DCMI_Stop();                         //启动传输
        while(1)
        {       
                DCMI_Stop();
                DCMI_Start();               
                LCD_WriteRAM_Prepare();
        }
}[/mw_shl_code]
回复

使用道具 举报

13

主题

52

帖子

0

精华

初级会员

Rank: 2

积分
148
金钱
148
注册时间
2017-2-8
在线时间
39 小时
 楼主| 发表于 2017-8-2 16:31:34 来自手机 | 显示全部楼层
自顶。…
回复

使用道具 举报

2

主题

16

帖子

0

精华

初级会员

Rank: 2

积分
95
金钱
95
注册时间
2017-2-23
在线时间
23 小时
发表于 2017-8-3 21:11:08 | 显示全部楼层
楼主弄好了?
回复

使用道具 举报

13

主题

52

帖子

0

精华

初级会员

Rank: 2

积分
148
金钱
148
注册时间
2017-2-8
在线时间
39 小时
 楼主| 发表于 2017-8-3 21:22:27 来自手机 | 显示全部楼层
梁眷liang 发表于 2017-8-3 21:11
楼主弄好了?

没有啊…你弄到哪一步了
回复

使用道具 举报

2

主题

16

帖子

0

精华

初级会员

Rank: 2

积分
95
金钱
95
注册时间
2017-2-23
在线时间
23 小时
发表于 2017-8-4 09:26:16 | 显示全部楼层
我用openmv了   虽然贵了一点  你会模糊控制算法没
回复

使用道具 举报

13

主题

52

帖子

0

精华

初级会员

Rank: 2

积分
148
金钱
148
注册时间
2017-2-8
在线时间
39 小时
 楼主| 发表于 2017-8-6 19:30:26 | 显示全部楼层
梁眷liang 发表于 2017-8-4 09:26
我用openmv了   虽然贵了一点  你会模糊控制算法没

不会。。。目前只想搞简单的,没深入研究
回复

使用道具 举报

15

主题

137

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
1429
金钱
1429
注册时间
2019-4-22
在线时间
272 小时
发表于 2019-5-12 17:27:12 | 显示全部楼层
楼主,你搞好了吗
回复

使用道具 举报

0

主题

13

帖子

0

精华

新手上路

积分
29
金钱
29
注册时间
2019-7-7
在线时间
10 小时
发表于 2019-7-7 12:30:05 | 显示全部楼层
顶上去 我也想知道
回复

使用道具 举报

0

主题

6

帖子

0

精华

新手入门

积分
14
金钱
14
注册时间
2019-7-6
在线时间
1 小时
发表于 2019-7-7 15:17:59 | 显示全部楼层
哇太强了
回复

使用道具 举报

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

本版积分规则



关闭

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

正点原子公众号

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

GMT+8, 2025-5-15 07:22

Powered by OpenEdv-开源电子网

© 2001-2030 OpenEdv-开源电子网

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