stm32驱动ov7670 数据转BMP格式再转JPEG存储

一.搞了几天摄像头终于搞出来了一点成果,本打算用BMP格式保存读出的数据但是数据太大达到225k,后来又将BMP数据转成JPEG格式就小了很多,jpeg是有损压缩图片会变得不那么清晰。

搞出来的成果:

stm32驱动ov7670 数据转BMP格式再转JPEG存储_第1张图片

 

二.摄像头小知识:XCLK是输入摄像头的时钟,看别的原理图接的是一个12M的晶振,初始化的时候4倍频达到48M,这里没有接,用PA8输出8M内部6倍频达到48M,PCLK是摄像头输出的时钟达到12M,图像输出的是QVGA,RGB565格式,用的是VGA时序,一个像素需要2个pclk.

行输出时序图:

stm32驱动ov7670 数据转BMP格式再转JPEG存储_第2张图片

HREF是一个行信号,这个信号和mcu的一个引脚连接在SN74LVC1G00D(与非门)上,和mcu一块控制fifo,当准备写fifo时,mcu发送高电平,这时fifo并没有被使能,只有当HREF产生高电平信号时,在PCLK的配合下将数据写到fifo中。

帧输出时序图:

stm32驱动ov7670 数据转BMP格式再转JPEG存储_第3张图片

VSYNC是帧同步信号,当摄像头采集到一帧数据,会发出帧同步信号,用外部中断捕获这个帧中断信号。

void EXTI4_IRQHandler(void)
{         
    if(EXTI_GetITStatus(EXTI_Line4)==SET)    //是4线的中断
    {   if(OV7670_CS == 0) 
        {       
                if(ov_sta == 0)
                {            
                    OV7670_WRST=0;    //复位写指针                   
                    OV7670_WRST=1;    
                    OV7670_WREN=1;    //允许写入FIFO      
                    ov_sta=1;
                }
                else
                {
                    OV7670_WRST=0;    //复位写指针                   
                    OV7670_WRST=0;    
                    OV7670_WREN=1;    //允许写入FIFO 
                }
            }
    }
    EXTI_ClearITPendingBit(EXTI_Line4);  //清除EXTI4线路挂起位                          
}

三.读取数据并转换,也是仿照的别人的用的开源库。

void camera_refresh(void)
{   
    int width, height;
    int j,i;
     u16 color=0;
    int col;
    int t;
   jpeg_compress_info *cinfo;
    pt_buf = 0;
    if(ov_sta)//有帧中断更新?
    {
          width = 320;//图像的宽度 
          height = 240;//图像的高度 
          cinfo = jpeg_create_compress();
          if (!cinfo) 
          {
            //printf("error in create cinfo, malloc faild!\n");
          }
          cinfo->image_width = width;
          cinfo->image_height= height;
          cinfo->output =(char *)JPG_enc_buf;//fopen("test.jpg", "wb");
          jpeg_set_default(cinfo);  
          
          jpeg_start_compress(cinfo);
  
        FLASH_SIZE1 = 8192;
        OV7670_RRST=0;                //开始复位读指针         
        OV7670_RCK_L;
        OV7670_RCK_H;
        OV7670_RCK_L;
        OV7670_RRST=1;                //复位读指针结束 
        OV7670_RCK_H;                
        for(j=0;j<240;j++)
        {    //printf("第%u行",j);
            for(i=319;i>=0;i--)
            {

      //高字节  数据位接的比较乱 根据实际情况修改
                OV7670_RCK_L;
                color = ((GPIOD->IDR&0xC000)>>14);   //D14 D15
                color |= ((GPIOD->IDR&0x0003)<<2);  //D0 D1
                color |= ((GPIOE->IDR&0x0780)>>3);  //E7 8 9 10
                OV7670_RCK_H;                 
                color<<=8;  
                OV7670_RCK_L;
                //低字节
                color |= ((GPIOD->IDR&0xC000)>>14);   //D14 D15
                color |= ((GPIOD->IDR&0x0003)<<2);  //D0 D1
                color |= ((GPIOE->IDR&0x0780)>>3);  //E7 8 9 10                
                OV7670_RCK_H;                                 
                R = (color>>8)&0xF8;
                G = (color>>3)&0xFC;
                B = (color<<3)&0xF8;
                
                buffer[i*3+0] = R;//jpeg格式顺序RGB 如果是bmp格式写成BGR
                buffer[i*3+1] = G;
                buffer[i*3+2] = B;
            }            
            jpeg_write_scanline(cinfo, buffer);//一行一行的压缩
        } 
        jpeg_finish_compress(cinfo);  
        jpeg_destory_compress(cinfo);
        //OV7670_CS=1;
         ov_sta=0;        //清零帧中断标记
        //需要多少擦多少
        for(i = 0;i<=(pt_buf/4096);i++)
        {
            W25QXX_Erase_Sector( 8192/4096+i );
        }      
        for(t = 0;t         {
         send_data(JPG_enc_buf[t]);//发送数据给上位机          
        }      
        W25QXX_Write_NoCheck((u8*)JPG_enc_buf,FLASH_SIZE1,pt_buf);//写到flash

    } 
}
  

突然发现没加源码地址,补上:https://download.csdn.net/download/forwardjia/10633160

你可能感兴趣的:(嵌入式,stm32,ov7670,摄像头)