文章目录

  • OV2640
    • SCCB时序
      • 基本概念简介
      • 行输出时序
      • 帧输出时序
      • JPEG时序
    • 相关硬件配置
      • OV2640传感器窗口设置
      • 图像尺寸设置
      • 图像窗口设置
      • 图像输出大小设置(缩放设置)
      • OV2640模块参数
    • OV2640模块使用过程
      • 初始化
      • MCU读取模块图像数据
  • DCMI接口
      • 时序
    • 数据存储
    • 相关设置
    • 初始化流程
  • 实际配置方法与代码
    • 硬件配置
    • 软件配置

OV2640

OV2640是OmniVision公司生产的1/4英寸CMOS UXGA(1632_1232分辨率)图像传感器

特点:

  • 体积小、工作电压低、灵敏度高
  • 具有单片UXGA摄像头和影像处理器的所有功能
  • 通过SCCB总线控制
  • 可输出整帧、子采样、缩放、取窗口等方式各种分辨率的8/10位影像数据
  • 最高帧数15帧/秒(SVGA可达30帧,CIF可达60帧)
  • 用户定义图像质量、数据格式、传输方式等
  • 所有图像处理功能都可以通过SCCB接口(行摄像机控制总线协议,相当于一个简易的I2C协议)编程
  • 兼容I2C接口
  • 支持RawRGB、RGB、GRB422、YUV和YCbCr输出格式
  • 内置DSP,支持UXGA、SXGA、SVGA以及按比例缩小到从SXGA到40*30的任何尺寸,支持图像缩放
  • 支持自动曝光控制、自动增益控制、自动白平衡、自动消除灯光条纹、自动黑电平校准等自动控制功能和色饱和度、色相、伽马、锐度等设置,支持闪光灯
  • 支持图像压缩,可输出JPEG图像数据

SCCB时序

SCCB(Serial Camera Control Bus串行摄像头控制总线)总线是由OV(OmniVision)公司定义和发展的三线式串行总线。现在SCCB总线大多采用两线式接口总线,接口总线包括SIOC串行时钟输入线和SIOD串行双向数据线,分别相当于IIC协议的SCL信号线和SDA信号线。SCCB就是个简化版的IIC,可以直接使用IIC的软件驱动代码改编成SCCB的驱动

基本概念简介

UXGA 1600*1200
SXGA 1280*1024
XVGA 1280*960
WXGA 1280*800
XGA 1024*768
SVGA 800*600
VGA 640*480
QQVGA 160*120
CIF 352*288
PCLK 像素时钟:一个PCLK时钟,输出一个(Raw格式)或半个(RGB565格式)像素
VSYNC 帧同步信号
HREF/HSYNC 行同步信号

ov2640的图像数据输出通过Y[9:0]寄存器输出,这里只使用一**字节(8位)**数据,再PCLK、VSYNC、HREF/HSYNC控制下进行

对于Raw格式数据,1∗tp=1∗TPCLK1*t_p=1*T_{PCLK}1∗tp​=1∗TPCLK​

对于YUV/RGB格式数据,1∗tp=2∗TPCLK1*t_p=2*T_{PCLK}1∗tp​=2∗TPCLK​

行输出时序

HREF高电平期间的PCLK上升沿进行输出,每个PCLK上升沿从Y[9:0]输出一个**字节(8位)**数据

PCLK最大可达36MHz

例:以UXGA(1600*1200)时序,采用RGB565格式输出,每2字节组成一个像素的颜色,且低字节在前高字节在后。这样每行输出总共有1600*2个PCLK周期输出1600*2个字节

帧输出时序

输出开始时,VSYNC输出4∗tLINE4*t_{LINE}4∗tLINE​有效电平(可自行设置为高/低)脉冲

27193∗tp27193*t_p27193∗tp​后,HREF拉高,开始输出行数据,每行数据输出之间以322∗tp322*t_p322∗tp​为间隔,直到完成所有行输出

最后会有57697∗tp57697*t_p57697∗tp​间隔才能进行下一帧输出

JPEG时序

JPEG输出时,PCLK大大减少,HREF不连续,数据流以0xFF、0xD8开头,以0xFF、0xD9结束,将此间数据保存为.jpg文件即可在电脑打开查看

相关硬件配置

OV2640传感器窗口设置

传感器窗口设置允许用户设置整个传感器区域(1632*1220)的感兴趣部分,即在传感器里面开窗,开窗范围从2*2到1632*1220都可以设置,但要求这个窗口必须大于等于随后设置的图像尺寸

详细内容可查看数据手册

图像尺寸设置

DSP输出到LCD的图像最大尺寸,该尺寸要小于等于传感器窗口设置所设定的窗口尺寸

图像窗口设置

在设置的图像尺寸里面再次设置窗口大小,该窗口必须小于等于前面设置的图像尺寸,该窗口设置后的图像范围将用于输出到外部

图像输出大小设置(缩放设置)

控制最终输出到外部的图像尺寸

该设置仅会对图像进行缩放处理,如果设置的图像输出大小不等于图像窗口设置图像大小,那么图像就会被缩放处理,只有两者大小一样(图像输出大小=图像窗口设置大小)时,输出比例才是1:1

OV2640模块参数

  1. 支持RGB565/JPEG数据输出
  2. 支持最大UXGA分辨率输出
  3. 支持图像任意缩放
  4. 自带24M有源晶振、3.3V稳压电路、带滤光片的感光红外镜头
  5. 支持手动对焦(旋下盖上螺丝调节镜头即可)

引脚参数:

脚位 名称 说明
1 GND 接地
2 VCC3.3 接3.3V电源
3 OV_SCL SCCB时钟线(I)
4 OV_VSYNC 帧同步信号(O)
5 OV_SDA SCCB数据线(I/O)
6 OV_HREF 行同步信号(O)
8 OV_RESET 复位信号,低电平有效(I)
15 OV_PCLK 像素时钟(O)
17 OV_PWDN 掉电模式使能,高电平有效(I)
18 NC 空脚
7、9、10、11、12、13、14、16 OV_D0~D7 数据线(O)

OV2640模块使用过程

初始化

  1. 初始化IO口
  2. 上电、复位
  3. 读取传感器ID
  4. 执行初始化序列

全部内容由OV2640公司提供源码

MCU读取模块图像数据

  1. 等待帧同步(等待VSYNC信号)
  2. 等待HRED为高电平
  3. 等待第一个PCLK上升沿
  4. 读取第一个像素的低字节
  5. 等待第二个PCLK上升沿
  6. 读取第一个像素的高字节
  7. 等待下一个PCLK上升沿
  8. 重复4-7步骤直到读完剩余像素
  9. 结束读取

DCMI接口

DCMI(Digital Camera Interface)是STM32F4xx自带的数字摄像头接口,属于同步并行接口

特性:

  • 能够接受外部8、10、12、14位并行接口最高54MB/s的高速数据流

  • 支持内嵌码/外部行同步/帧同步

  • 支持连续模式或快照模式

  • 支持裁剪功能

  • 可支持不同数据格式:单色或原始拜尔(Bayer)格式、YCbCr 4:2:2逐行视频、RGB565逐行视频、压缩数据(JPEG)格式

  • 接口通过FIFO和数据格式化器直接与AHB总线相连

该接口包含14条数据线(D13-D0)和1条像素时钟线(PIXCLK),且像素时钟的有效电平可由用户程序决定,能在像素时钟的上升沿或下降沿捕获数据

DCMI接口包含以下信号:

DCMI接口 引脚 别名 对应OV2640接口 引脚
数据流输入 D[0:13] 数据流输出 D[0:7]
水平同步 输入HREF/HSYNC 行同步 行同步信号 HREF/HSYNC
垂直同步 输入VSYNC 帧同步/场同步 帧同步信号 VSYNC
像素时钟输入 PIXCLK 像素时钟 像素时钟 PCLK

时序

数据与PIXCLK同步,并根据像素时钟的极性在像素时钟上升沿/下降沿发生变化

HREF/HSYNC指示行的开始或结束,VSYNC指示帧的开始或结束

DCMI时序与上述OV2640时序基本一致,但DCMI的PIXCLK有效沿可自定义,且HSYNC、VSYNC有效状态对应指示数据在并行接口上无效时,HSYNC/VSYNC引脚上的引脚电平(人话:和OV2640的有效状态相反)

数据存储

DCMI接收到的数据存储在DCMI_DR 32位寄存器内,接入OV2640模块时采用8位数据宽度,所以每4个像素时钟才捕获完32位数据,第一个字节存放在LSB位置,第四个字节存放在MSB位置遵守低字节在前,高字节在后

DCMI支持DMA传输,DCMI可被配置为每在其数据寄存器中收到一个完整的32位数据块时,发送一个DMA请求,由DMA将寄存器内的值搬运到目的地址(如LCD/SRAM)

注意:DCMI的DMA请求映射在DMA2 Channel1 Stream1上;如果使用DCMI->DMA->LCD的传输路径,因为LCD是16位宽(RGB565),但DCMI_DR是32位宽,所以一次DCMI引起的DMA请求将引发往LCD写2次数据

相关设置

DCMI支持连续模式和快照模式,连续模式=录像;快照模式=照相

DCMI支持内嵌码同步和硬件同步,一般采用硬件同步

硬件同步下使用HSYNC和VSYNC两个信号,系统会忽略两个信号有效电平期间接收的所有数据,即硬件同步模式下的HSYNC、VSYNC信号相当于消隐信号

初始化流程

  1. 配置相关引脚复用为DCMI
  2. 使能DCMI时钟
  3. 设置DCMI工作模式和PCLK、HSYNC、VSYNC等参数
  4. 设置DMA搬运DCMI数据
  5. 使能DCMI传输

实际配置方法与代码

硬件配置

OV2640模块-转接-DCMI接口 对应好即可

软件配置

  1. sccb协议驱动(与I2C协议类似)

sccb.h

#ifndef __SCCB_H#define __SCCB_H#include "sys.h"//IO方向设置#define SCCB_SDA_IN() {GPIOD->MODER&=~(3<<(7*2));GPIOD->MODER|=0<<7*2;} //PD7输入#define SCCB_SDA_OUT() {GPIOD->MODER&=~(3<<(7*2));GPIOD->MODER|=1<<7*2;} //PD7输出//IO操作函数#define SCCB_SCL PDout(6) //PD6配置为SCL(仅输出)#define SCCB_SDA PDout(7) //SDA输出#define SCCB_READ_SDA PDin(7) //SDA输出#define SCCB_ID 0X60 //OV2640的IDvoid SCCB_Init(void);//SCCB接口初始化void SCCB_Start(void);//起始信号void SCCB_Stop(void);//停止信号void SCCB_No_Ack(void);//NA信号u8 SCCB_WR_Byte(u8 dat);//写数据u8 SCCB_RD_Byte(void);//读数据u8 SCCB_WR_Reg(u8 reg,u8 data);//写寄存器u8 SCCB_RD_Reg(u8 reg);//读寄存器
#endif

sccb.c

#include "sccb.h"
#include "delay.h"//初始化SCCB接口
void SCCB_Init(void)
{GPIO_InitTypeDef  GPIO_InitStructure;RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOD, ENABLE);//使能GPIOD时钟GPIO_InitStructure.GPIO_Pin=GPIO_Pin_6|GPIO_Pin_7;//PD6、PD7GPIO_InitStructure.GPIO_Mode=GPIO_Mode_OUT;//输出模式GPIO_InitStructure.GPIO_OType=GPIO_OType_PP;//推挽输出GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz;//100MHzGPIO_InitStructure.GPIO_PuPd=GPIO_PuPd_UP;//内部上拉//应用设置GPIO_Init(GPIOD,&GPIO_InitStructure);GPIO_SetBits(GPIOD,GPIO_Pin_6|GPIO_Pin_7);//初始为高电平SCCB_SDA_OUT();
}//SCCB起始信号
//时钟为高时,数据线下降沿,为SCCB起始信号
//在激活状态下,SDA和SCL均为低电平
void SCCB_Start(void)
{SCCB_SDA=1;//数据线高电平      SCCB_SCL=1;//时钟线高时数据线下降沿delay_us(50);SCCB_SDA=0;delay_us(50);SCCB_SCL=0;//数据线恢复低电平,单操作函数必要
}//SCCB停止信号
//时钟为高时,数据线上升沿,为SCCB停止信号
//空闲状况下,SDA,SCL均为高电平
void SCCB_Stop(void)
{SCCB_SDA=0;delay_us(50);   SCCB_SCL=1;//数据线高电平delay_us(50);SCCB_SDA=1;//时钟线高时数据线上升沿delay_us(50);
}//NA信号
void SCCB_No_Ack(void)
{delay_us(50);SCCB_SDA=1;//SDA、SCL都为高电平SCCB_SCL=1;delay_us(50);SCCB_SCL=0;delay_us(50);SCCB_SDA=0;delay_us(50);
}//SCCB写入一个字节
//返回值:0,成功;1,失败
u8 SCCB_WR_Byte(u8 dat)
{u8 j,res;   for(j=0;j<8;j++)//循环8次发送数据{if(dat&0x80)SCCB_SDA=1;  elseSCCB_SDA=0;dat<<=1;//发送数据delay_us(50);SCCB_SCL=1;delay_us(50);SCCB_SCL=0;        }SCCB_SDA_IN();//设置SDA为输入 delay_us(50);SCCB_SCL=1;//接收第九位,判断是否发送成功delay_us(50);if(SCCB_READ_SDA)//读取到NA数据res=1;//SDA=1发送失败,返回1elseres=0;//SDA=0发送成功,返回0SCCB_SCL=0;        SCCB_SDA_OUT();//设置SDA为输出 return res;
}//SCCB读取一个字节
//SCL上升沿,数据锁存
//返回值:读到的数据
u8 SCCB_RD_Byte(void)
{u8 temp=0,j;SCCB_SDA_IN();//设置SDA为输入  for(j=8;j>0;j--)//循环8次接收数据{delay_us(50);SCCB_SCL=1;temp=temp<<1;if(SCCB_READ_SDA)temp++;   delay_us(50);SCCB_SCL=0;}SCCB_SDA_OUT();//设置SDA为输出    return temp;
}//写寄存器
//返回值:0,成功;1,失败.
u8 SCCB_WR_Reg(u8 reg,u8 data)
{u8 res=0;SCCB_Start();//启动SCCB传输if(SCCB_WR_Byte(SCCB_ID))res=1;//写器件ID     delay_us(100);if(SCCB_WR_Byte(reg))res=1;//写寄存器地址      delay_us(100);if(SCCB_WR_Byte(data))res=1;//写数据   SCCB_Stop();returnres;
}//读寄存器
//返回值:读到的寄存器值
u8 SCCB_RD_Reg(u8 reg)
{u8 val=0;SCCB_Start();//启动SCCB传输SCCB_WR_Byte(SCCB_ID);//写器件IDdelay_us(100);    SCCB_WR_Byte(reg);//写寄存器地址   delay_us(100);      SCCB_Stop();   delay_us(100);    //设置寄存器地址后进行读操作SCCB_Start();SCCB_WR_Byte(SCCB_ID|0X01);//发送读命令     delay_us(100);val=SCCB_RD_Byte();//读取数据SCCB_No_Ack();SCCB_Stop();return val;
}
  1. ov2640驱动

ov2640.h

#ifndef _OV2640_H
#define _OV2640_H
#include "sys.h"
#include "sccb.h"#define OV2640_PWDN PGout(9) //POWER_DOWN控制信号
#define OV2640_RST PGout(15) //复位控制信号 /*片内信息核对*/
#define OV2640_MID 0X7FA2
#define OV2640_PID 0X2642//当选择DSP地址(0XFF=0X00)时,OV2640的DSP寄存器地址映射表
#define OV2640_DSP_R_BYPASS     0x05
#define OV2640_DSP_Qs           0x44
#define OV2640_DSP_CTRL         0x50
#define OV2640_DSP_HSIZE1       0x51
#define OV2640_DSP_VSIZE1       0x52
#define OV2640_DSP_XOFFL        0x53
#define OV2640_DSP_YOFFL        0x54
#define OV2640_DSP_VHYX         0x55
#define OV2640_DSP_DPRP         0x56
#define OV2640_DSP_TEST         0x57
#define OV2640_DSP_ZMOW         0x5A
#define OV2640_DSP_ZMOH         0x5B
#define OV2640_DSP_ZMHH         0x5C
#define OV2640_DSP_BPADDR       0x7C
#define OV2640_DSP_BPDATA       0x7D
#define OV2640_DSP_CTRL2        0x86
#define OV2640_DSP_CTRL3        0x87
#define OV2640_DSP_SIZEL        0x8C
#define OV2640_DSP_HSIZE2       0xC0
#define OV2640_DSP_VSIZE2       0xC1
#define OV2640_DSP_CTRL0        0xC2
#define OV2640_DSP_CTRL1        0xC3
#define OV2640_DSP_R_DVP_SP     0xD3
#define OV2640_DSP_IMAGE_MODE   0xDA
#define OV2640_DSP_RESET        0xE0
#define OV2640_DSP_MS_SP        0xF0
#define OV2640_DSP_SS_ID        0x7F
#define OV2640_DSP_SS_CTRL      0xF8
#define OV2640_DSP_MC_BIST      0xF9
#define OV2640_DSP_MC_AL        0xFA
#define OV2640_DSP_MC_AH        0xFB
#define OV2640_DSP_MC_D         0xFC
#define OV2640_DSP_P_STATUS     0xFE
#define OV2640_DSP_RA_DLMT      0xFF //当选择传感器地址(0XFF=0X01)时,OV2640的DSP寄存器地址映射表
#define OV2640_SENSOR_GAIN       0x00
#define OV2640_SENSOR_COM1       0x03
#define OV2640_SENSOR_REG04      0x04
#define OV2640_SENSOR_REG08      0x08
#define OV2640_SENSOR_COM2       0x09
#define OV2640_SENSOR_PIDH       0x0A
#define OV2640_SENSOR_PIDL       0x0B
#define OV2640_SENSOR_COM3       0x0C
#define OV2640_SENSOR_COM4       0x0D
#define OV2640_SENSOR_AEC        0x10
#define OV2640_SENSOR_CLKRC      0x11
#define OV2640_SENSOR_COM7       0x12
#define OV2640_SENSOR_COM8       0x13
#define OV2640_SENSOR_COM9       0x14
#define OV2640_SENSOR_COM10      0x15
#define OV2640_SENSOR_HREFST     0x17
#define OV2640_SENSOR_HREFEND    0x18
#define OV2640_SENSOR_VSTART     0x19
#define OV2640_SENSOR_VEND       0x1A
#define OV2640_SENSOR_MIDH       0x1C
#define OV2640_SENSOR_MIDL       0x1D
#define OV2640_SENSOR_AEW        0x24
#define OV2640_SENSOR_AEB        0x25
#define OV2640_SENSOR_W          0x26
#define OV2640_SENSOR_REG2A      0x2A
#define OV2640_SENSOR_FRARL      0x2B
#define OV2640_SENSOR_ADDVSL     0x2D
#define OV2640_SENSOR_ADDVHS     0x2E
#define OV2640_SENSOR_YAVG       0x2F
#define OV2640_SENSOR_REG32      0x32
#define OV2640_SENSOR_ARCOM2     0x34
#define OV2640_SENSOR_REG45      0x45
#define OV2640_SENSOR_FLL        0x46
#define OV2640_SENSOR_FLH        0x47
#define OV2640_SENSOR_COM19      0x48
#define OV2640_SENSOR_ZOOMS      0x49
#define OV2640_SENSOR_COM22      0x4B
#define OV2640_SENSOR_COM25      0x4E
#define OV2640_SENSOR_BD50       0x4F
#define OV2640_SENSOR_BD60       0x50
#define OV2640_SENSOR_REG5D      0x5D
#define OV2640_SENSOR_REG5E      0x5E
#define OV2640_SENSOR_REG5F      0x5F
#define OV2640_SENSOR_REG60      0x60
#define OV2640_SENSOR_HISTO_LOW  0x61
#define OV2640_SENSOR_HISTO_HIGH 0x62/*OV2640初始化函数*/
u8 OV2640_Init(void);
/*OV2640选项调节函数*/
void OV2640_JPEG_Mode(void);
void OV2640_RGB565_Mode(void);
void OV2640_Auto_Exposure(u8 level);
void OV2640_Light_Mode(u8 mode);
void OV2640_Color_Saturation(u8 sat);
void OV2640_Brightness(u8 bright);
void OV2640_Contrast(u8 contrast);
void OV2640_Special_Effects(u8 eft);
void OV2640_Color_Bar(u8 sw);
/*OV2640硬件软件"开窗"函数*/
void OV2640_Window_Set(u16 sx,u16 sy,u16 width,u16 height);
u8 OV2640_OutSize_Set(u16 width,u16 height);
u8 OV2640_ImageWin_Set(u16 offx,u16 offy,u16 width,u16 height);
u8 OV2640_ImageSize_Set(u16 width,u16 height);
#endif

ov2640.c

#include "ov2640.h"
#include "ov2640cfg.h"
#include "timer.h“
#include "sccb.h"
#include "delay.h"
#include "usart.h"//初始化OV2640
//默认输出1600*1200尺寸的图片
//返回值:0,成功
//    其他,错误代码
u8 OV2640_Init(void)
{ u16 i=0;u16 reg;/*设置IO连接OV2640*/GPIO_InitTypeDef GPIO_InitStructure;RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOG, ENABLE);//GPIOG9,15初始化设置GPIO_InitStructure.GPIO_Pin=GPIO_Pin_9|GPIO_Pin_15;//PG9,15GPIO_InitStructure.GPIO_Mode=GPIO_Mode_OUT; //普通输出模式GPIO_InitStructure.GPIO_OType=GPIO_OType_PP;//推挽输出GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz;//100MHzGPIO_InitStructure.GPIO_PuPd=GPIO_PuPd_UP;//内部上拉//应用设置GPIO_Init(GPIOG,&GPIO_InitStructure);OV2640_PWDN=0;//开始硬复位delay_ms(10);OV2640_RST=0;//复位OV2640delay_ms(10);OV2640_RST=1;//结束复位SCCB_Init();//初始化SCCB 的IO口   SCCB_WR_Reg(OV2640_DSP_RA_DLMT,0x01);//操作sensor寄存器SCCB_WR_Reg(OV2640_SENSOR_COM7,0x80);//开始软复位delay_ms(50);reg=SCCB_RD_Reg(OV2640_SENSOR_MIDH);//读取厂家ID 高八位reg<<=8;//存入寄存器reg|=SCCB_RD_Reg(OV2640_SENSOR_MIDL);//读取厂家ID 低八位 并 存入寄存器if(reg!=OV2640_MID){printf("MID:%d\r\n",reg);return 1;}reg=SCCB_RD_Reg(OV2640_SENSOR_PIDH);//读取厂家ID 高八位reg<<=8;reg|=SCCB_RD_Reg(OV2640_SENSOR_PIDL);//读取厂家ID 低八位if(reg!=OV2640_PID){printf("HID:%d\r\n",reg);return 2;}/*采用SXGA分辨率(1600*1200)初始化*/  for(i=0;i<sizeof(ov2640_sxga_init_reg_tbl)/2;i++){SCCB_WR_Reg(ov2640_sxga_init_reg_tbl[i][0],ov2640_sxga_init_reg_tbl[i][1]);}return 0x00;
} /*参数选项函数*/
//OV2640切换为JPEG模式
void OV2640_JPEG_Mode(void)
{u16 i=0;//设置:YUV422格式for(i=0;i<(sizeof(ov2640_yuv422_reg_tbl)/2);i++){SCCB_WR_Reg(ov2640_yuv422_reg_tbl[i][0],ov2640_yuv422_reg_tbl[i][1]); } //设置:输出JPEG数据for(i=0;i<(sizeof(ov2640_jpeg_reg_tbl)/2);i++){SCCB_WR_Reg(ov2640_jpeg_reg_tbl[i][0],ov2640_jpeg_reg_tbl[i][1]);  }
}
//OV2640切换为RGB565模式
void OV2640_RGB565_Mode(void)
{u16 i=0;//设置:RGB565输出for(i=0;i<(sizeof(ov2640_rgb565_reg_tbl)/2);i++){SCCB_WR_Reg(ov2640_rgb565_reg_tbl[i][0],ov2640_rgb565_reg_tbl[i][1]); }
}
//自动曝光设置参数表,支持5个等级
const static u8 OV2640_AUTOEXPOSURE_LEVEL[5][8]=
{{0xFF,0x01,0x24,0x20,0x25,0x18,0x26,0x60,},{0xFF,0x01,0x24,0x34,0x25,0x1c,0x26,0x00,},{0xFF,0x01,  0x24,0x3e,  0x25,0x38,0x26,0x81,},{0xFF,0x01,0x24,0x48,0x25,0x40,0x26,0x81,},{0xFF,0x01,    0x24,0x58,  0x25,0x50,  0x26,0x92,  },
};
//OV2640自动曝光等级设置
//level:0~4
void OV2640_Auto_Exposure(u8 level)
{  u8 i;u8* p=(u8*)OV2640_AUTOEXPOSURE_LEVEL[level];for(i=0;i<4;i++){ SCCB_WR_Reg(p[i*2],p[i*2+1]); }
}
//白平衡设置
//0:自动
//1:太阳sunny
//2,阴天cloudy
//3,办公室office
//4,家里home
void OV2640_Light_Mode(u8 mode)
{u8 regccval=0X5E;//Sunny u8 regcdval=0X41;u8 regceval=0X54;switch(mode){ case 0://auto SCCB_WR_Reg(0XFF,0X00);   SCCB_WR_Reg(0XC7,0X10);//AWB ON return;    case 2://cloudyregccval=0X65;regcdval=0X41;regceval=0X4F;break;  case 3://officeregccval=0X52;regcdval=0X41;regceval=0X66;break;  case 4://homeregccval=0X42;regcdval=0X3F;regceval=0X71;break;    }SCCB_WR_Reg(0XFF,0X00);     SCCB_WR_Reg(0XC7,0X40);    //AWB OFF SCCB_WR_Reg(0XCC,regccval); SCCB_WR_Reg(0XCD,regcdval); SCCB_WR_Reg(0XCE,regceval);
}
//色度设置
//0:-2
//1:-1
//2,0
//3,+1
//4,+2
void OV2640_Color_Saturation(u8 sat)
{ u8 reg7dval=((sat+2)<<4)|0X08;SCCB_WR_Reg(0XFF,0X00);     SCCB_WR_Reg(0X7C,0X00);     SCCB_WR_Reg(0X7D,0X02);             SCCB_WR_Reg(0X7C,0X03);         SCCB_WR_Reg(0X7D,reg7dval);         SCCB_WR_Reg(0X7D,reg7dval);
}
//亮度设置
//0:(0X00)-2
//1:(0X10)-1
//2,(0X20) 0
//3,(0X30)+1
//4,(0X40)+2
void OV2640_Brightness(u8 bright)
{SCCB_WR_Reg(0xff, 0x00);SCCB_WR_Reg(0x7c, 0x00);SCCB_WR_Reg(0x7d, 0x04);SCCB_WR_Reg(0x7c, 0x09);SCCB_WR_Reg(0x7d, bright<<4); SCCB_WR_Reg(0x7d, 0x00);
}
//对比度设置
//0:-2
//1:-1
//2,0
//3,+1
//4,+2
void OV2640_Contrast(u8 contrast)
{u8 reg7d0val=0X20;//默认为普通模式u8 reg7d1val=0X20;switch(contrast){case 0://-2reg7d0val=0X18;         reg7d1val=0X34;        break; case 1://-1reg7d0val=0X1C;      reg7d1val=0X2A;        break; case 3://1reg7d0val=0X24;       reg7d1val=0X16;        break; case 4://2reg7d0val=0X28;       reg7d1val=0X0C;        break; }SCCB_WR_Reg(0xff,0x00);SCCB_WR_Reg(0x7c,0x00);SCCB_WR_Reg(0x7d,0x04);SCCB_WR_Reg(0x7c,0x07);SCCB_WR_Reg(0x7d,0x20);SCCB_WR_Reg(0x7d,reg7d0val);SCCB_WR_Reg(0x7d,reg7d1val);SCCB_WR_Reg(0x7d,0x06);
}
//特效设置
//0:普通模式
//1,负片
//2,黑白
//3,偏红色
//4,偏绿色
//5,偏蓝色
//6,复古
void OV2640_Special_Effects(u8 eft)
{u8 reg7d0val=0X00;//默认为普通模式u8 reg7d1val=0X80;u8 reg7d2val=0X80; switch(eft){case 1://负片reg7d0val=0X40; break;  case 2://黑白reg7d0val=0X18; break;   case 3://偏红色reg7d0val=0X18; reg7d1val=0X40;reg7d2val=0XC0; break;   case 4://偏绿色reg7d0val=0X18; reg7d1val=0X40;reg7d2val=0X40; break;    case 5://偏蓝色reg7d0val=0X18; reg7d1val=0XA0;reg7d2val=0X40; break;    case 6://复古reg7d0val=0X18; reg7d1val=0X40;reg7d2val=0XA6; break;  }SCCB_WR_Reg(0xff,0x00);SCCB_WR_Reg(0x7c,0x00);SCCB_WR_Reg(0x7d,reg7d0val);SCCB_WR_Reg(0x7c,0x05);SCCB_WR_Reg(0x7d,reg7d1val);SCCB_WR_Reg(0x7d,reg7d2val);
}
//彩条测试
//sw:0,关闭彩条
//   1,开启彩条(注意OV2640的彩条是叠加在图像上面的)
void OV2640_Color_Bar(u8 sw)
{u8 reg;SCCB_WR_Reg(0XFF,0X01);reg=SCCB_RD_Reg(0X12);reg&=~(1<<1);if(sw)reg|=1<<1; SCCB_WR_Reg(0X12,reg);
}/*硬件软件窗口配置*///设置图像输出窗口
//sx,sy,起始地址
//width,height:宽度(对应:horizontal)和高度(对应:vertical)
void OV2640_Window_Set(u16 sx,u16 sy,u16 width,u16 height)
{u16 endx;u16 endy;u8 temp; endx=sx+width/2;//V*2endy=sy+height/2;SCCB_WR_Reg(0XFF,0X01);           temp=SCCB_RD_Reg(0X03);//读取Vref之前的值temp&=0XF0;temp|=((endy&0X03)<<2)|(sy&0X03);SCCB_WR_Reg(0X03,temp);//设置Vref的start和end的最低2位SCCB_WR_Reg(0X19,sy>>2);//设置Vref的start高8位SCCB_WR_Reg(0X1A,endy>>2);//设置Vref的end的高8位temp=SCCB_RD_Reg(0X32);//读取Href之前的值temp&=0XC0;temp|=((endx&0X07)<<3)|(sx&0X07);SCCB_WR_Reg(0X32,temp);//设置Href的start和end的最低3位SCCB_WR_Reg(0X17,sx>>3);//设置Href的start高8位SCCB_WR_Reg(0X18,endx>>3);//设置Href的end的高8位
}
//设置图像输出大小
//OV2640输出图像的大小(分辨率),完全由改函数确定
//width,height:宽度(对应:horizontal)和高度(对应:vertical),width和height必须是4的倍数
//返回值:0,设置成功
//    其他,设置失败
u8 OV2640_OutSize_Set(u16 width,u16 height)
{u16 outh;u16 outw;u8 temp;if(width%4)return 1;if(height%4)return 2;outw=width/4;outh=height/4;SCCB_WR_Reg(0XFF,0X00);    SCCB_WR_Reg(0XE0,0X04);         SCCB_WR_Reg(0X5A,outw&0XFF);//设置OUTW的低八位SCCB_WR_Reg(0X5B,outh&0XFF);//设置OUTH的低八位temp=(outw>>8)&0X03;temp|=(outh>>6)&0X04;SCCB_WR_Reg(0X5C,temp);//设置OUTH/OUTW的高位 SCCB_WR_Reg(0XE0,0X00);return 0;
}
//设置图像开窗大小
//由:OV2640_ImageSize_Set确定传感器输出分辨率从大小.
//该函数则在这个范围上面进行开窗,用于OV2640_OutSize_Set的输出
//注意:本函数的宽度和高度,必须大于等于OV2640_OutSize_Set函数的宽度和高度
//     OV2640_OutSize_Set设置的宽度和高度,根据本函数设置的宽度和高度,由DSP
//     自动计算缩放比例,输出给外部设备.
//width,height:宽度(对应:horizontal)和高度(对应:vertical),width和height必须是4的倍数
//返回值:0,设置成功
//    其他,设置失败
u8 OV2640_ImageWin_Set(u16 offx,u16 offy,u16 width,u16 height)
{u16 hsize;u16 vsize;u8 temp;if(width%4)return 1;if(height%4)return 2;hsize=width/4;vsize=height/4;SCCB_WR_Reg(0XFF,0X00);    SCCB_WR_Reg(0XE0,0X04);                 SCCB_WR_Reg(0X51,hsize&0XFF);//设置H_SIZE的低八位SCCB_WR_Reg(0X52,vsize&0XFF);//设置V_SIZE的低八位SCCB_WR_Reg(0X53,offx&0XFF);//设置offx的低八位SCCB_WR_Reg(0X54,offy&0XFF);//设置offy的低八位temp=(vsize>>1)&0X80;temp|=(offy>>4)&0X70;temp|=(hsize>>5)&0X08;temp|=(offx>>8)&0X07; SCCB_WR_Reg(0X55,temp);//设置H_SIZE/V_SIZE/OFFX,OFFY的高位SCCB_WR_Reg(0X57,(hsize>>2)&0X80);//设置H_SIZE/V_SIZE/OFFX,OFFY的高位SCCB_WR_Reg(0XE0,0X00);  return 0;
}
//该函数设置图像尺寸大小,也就是所选格式的输出分辨率
//UXGA:1600*1200,SVGA:800*600,CIF:352*288
//width,height:图像宽度和图像高度
//返回值:0,设置成功
//    其他,设置失败
u8 OV2640_ImageSize_Set(u16 width,u16 height)
{ u8 temp;SCCB_WR_Reg(0XFF,0X00);           SCCB_WR_Reg(0XE0,0X04);         SCCB_WR_Reg(0XC0,(width)>>3&0XFF);//设置HSIZE的10:3位SCCB_WR_Reg(0XC1,(height)>>3&0XFF);//设置VSIZE的10:3位temp=(width&0X07)<<3;temp|=height&0X07;temp|=(width>>4)&0X80;SCCB_WR_Reg(0X8C,temp);  SCCB_WR_Reg(0XE0,0X00);return 0;
}

ov2640cfg.h

//OV2640 SXGA初始化寄存器序列表
//模式选择
//内容过长,略去,详见正点原子教程
  1. dcmi接口配置

dcmi.h

#ifndef _DCMI_H#define _DCMI_H#include "sys.h"void My_DCMI_Init(void);void DCMI_DMA_Init(u32 DMA_Memory0BaseAddr,u16 DMA_BufferSize,u32 DMA_MemoryDataSize,u32 DMA_MemoryInc);void DCMI_Start(void);void DCMI_Stop(void);void DCMI_Set_Window(u16 sx,u16 sy,u16 width,u16 height);void DCMI_CR_Set(u8 pclk,u8 hsync,u8 vsync);#endif

dcmi.c

#include "dcmi.h"
#include "lcd.h"
#include "led.h"
#include "ov2640.h”u8 ov_frame=0;//帧率
extern void jpeg_data_process(void);//JPEG数据处理函数DCMI_InitTypeDef DCMI_InitStructure;//全局变量注意//DCMI中断服务函数
void DCMI_IRQHandler(void)
{if(DCMI_GetITStatus(DCMI_IT_FRAME)==SET)//捕获到一帧图像{jpeg_data_process();//jpeg数据处理 DCMI_ClearITPendingBit(DCMI_IT_FRAME);//清除帧中断LED1=!LED1;//LED指示捕获到图像ov_frame++;LCD_SetCursor(0,0);//重置LCDLCD_WriteRAM_Prepare();//开始写入GRAM}
} //DCMI DMA配置
//DMA_Memory0BaseAddr:存储器地址——将要存储摄像头数据的内存地址(也可以是外设地址)
//DMA_BufferSize:存储器长度——0~65535
//DMA_MemoryDataSize:存储器位宽
//DMA_MemoryInc:存储器增长方式
void DCMI_DMA_Init(u32 DMA_Memory0BaseAddr,u16 DMA_BufferSize,u32 DMA_MemoryDataSize,u32 DMA_MemoryInc)
{ DMA_InitTypeDef  DMA_InitStructure;RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_DMA2,ENABLE);//使能DMA2时钟DMA_DeInit(DMA2_Stream1);//清空流while (DMA_GetCmdStatus(DMA2_Stream1)!=DISABLE);//等待DMA2Stream1可配置 /*配置DMA2 Stream1 Channel1*/DMA_InitStructure.DMA_Channel=DMA_Channel_1;//DMA2Stream1Channel1DMA_InitStructure.DMA_PeripheralBaseAddr=(u32)&DCMI->DR;//外设地址:DCMI->DRDMA_InitStructure.DMA_Memory0BaseAddr=DMA_Memory0BaseAddr;//DMA存储器0地址DMA_InitStructure.DMA_DIR=DMA_DIR_PeripheralToMemory;//外设到存储器模式DMA_InitStructure.DMA_BufferSize=DMA_BufferSize;//数据传输量 DMA_InitStructure.DMA_PeripheralInc=DMA_PeripheralInc_Disable;//外设非增量模式DMA_InitStructure.DMA_MemoryInc=DMA_MemoryInc;//存储器增量模式DMA_InitStructure.DMA_PeripheralDataSize=DMA_PeripheralDataSize_Word;//外设数据长度:32位DMA_InitStructure.DMA_MemoryDataSize=DMA_MemoryDataSize;//存储器数据长度DMA_InitStructure.DMA_Mode=DMA_Mode_Circular;//使用循环模式 DMA_InitStructure.DMA_Priority=DMA_Priority_High;//高优先级DMA_InitStructure.DMA_FIFOMode=DMA_FIFOMode_Enable;//使能FIFO        DMA_InitStructure.DMA_FIFOThreshold=DMA_FIFOThreshold_Full;//使用全FIFO DMA_InitStructure.DMA_MemoryBurst=DMA_MemoryBurst_Single;//外设突发单次传输DMA_InitStructure.DMA_PeripheralBurst=DMA_PeripheralBurst_Single;//存储器突发单次传输//应用设置DMA_Init(DMA2_Stream1,&DMA_InitStructure);
}//DCMI初始化
void My_DCMI_Init(void)
{GPIO_InitTypeDef  GPIO_InitStructure;NVIC_InitTypeDef NVIC_InitStructure;RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA|\RCC_AHB1Periph_GPIOB|\RCC_AHB1Periph_GPIOC|\RCC_AHB1Periph_GPIOE,ENABLE);//使能GPIOA B C E时钟RCC_AHB2PeriphClockCmd(RCC_AHB2Periph_DCMI,ENABLE);//使能DCMI时钟/*PA4、PA6、PB6、PB7、PC6、PC7、PC8、PC9、PC11、PE5、PE6设置为复用输出*/GPIO_InitStructure.GPIO_Mode=GPIO_Mode_AF; //复用功能GPIO_InitStructure.GPIO_OType=GPIO_OType_PP;//推挽输出GPIO_InitStructure.GPIO_Speed=GPIO_Speed_100MHz;//100MHzGPIO_InitStructure.GPIO_PuPd=GPIO_PuPd_UP;//内部上拉GPIO_InitStructure.GPIO_Pin=GPIO_Pin_4|GPIO_Pin_6;//PA4、6复用输出//应用设置GPIO_Init(GPIOA, &GPIO_InitStructure);GPIO_InitStructure.GPIO_Pin=GPIO_Pin_7|GPIO_Pin_6;//PB6、7复用输出//应用设置GPIO_Init(GPIOB, &GPIO_InitStructure);GPIO_InitStructure.GPIO_Pin=GPIO_Pin_6|GPIO_Pin_7|GPIO_Pin_8|GPIO_Pin_9|GPIO_Pin_11;//PC6、7、8、9、11 复用输出//应用设置GPIO_Init(GPIOC, &GPIO_InitStructure);GPIO_InitStructure.GPIO_Pin = GPIO_Pin_5|GPIO_Pin_6;//PE5、6复用输出//应用设置GPIO_Init(GPIOE, &GPIO_InitStructure);GPIO_PinAFConfig(GPIOA,GPIO_PinSource4,GPIO_AF_DCMI);//PA4,AF13  DCMI_HSYNCGPIO_PinAFConfig(GPIOA,GPIO_PinSource6,GPIO_AF_DCMI);//PA6,AF13  DCMI_PCLK  GPIO_PinAFConfig(GPIOB,GPIO_PinSource7,GPIO_AF_DCMI);//PB7,AF13  DCMI_VSYNC GPIO_PinAFConfig(GPIOC,GPIO_PinSource6,GPIO_AF_DCMI);//PC6,AF13  DCMI_D0  GPIO_PinAFConfig(GPIOC,GPIO_PinSource7,GPIO_AF_DCMI);//PC7,AF13  DCMI_D1 GPIO_PinAFConfig(GPIOC,GPIO_PinSource8,GPIO_AF_DCMI);//PC8,AF13  DCMI_D2GPIO_PinAFConfig(GPIOC,GPIO_PinSource9,GPIO_AF_DCMI);//PC9,AF13  DCMI_D3GPIO_PinAFConfig(GPIOC,GPIO_PinSource11,GPIO_AF_DCMI);//PC11,AF13 DCMI_D4 GPIO_PinAFConfig(GPIOB,GPIO_PinSource6,GPIO_AF_DCMI);//PB6,AF13  DCMI_D5 GPIO_PinAFConfig(GPIOE,GPIO_PinSource5,GPIO_AF_DCMI);//PE5,AF13  DCMI_D6GPIO_PinAFConfig(GPIOE,GPIO_PinSource6,GPIO_AF_DCMI);//PE6,AF13  DCMI_D7DCMI_DeInit();//清除原来的设置DCMI_InitStructure.DCMI_CaptureMode=DCMI_CaptureMode_Continuous;//连续模式DCMI_InitStructure.DCMI_CaptureRate=DCMI_CaptureRate_All_Frame;//全帧捕获DCMI_InitStructure.DCMI_ExtendedDataMode= DCMI_ExtendedDataMode_8b;//8位数据格式  DCMI_InitStructure.DCMI_HSPolarity= DCMI_HSPolarity_Low;//HSYNC低电平有效DCMI_InitStructure.DCMI_VSPolarity=DCMI_VSPolarity_Low;//VSYNC低电平有效DCMI_InitStructure.DCMI_PCKPolarity= DCMI_PCKPolarity_Rising;//PCLK上升沿有效DCMI_InitStructure.DCMI_SynchroMode= DCMI_SynchroMode_Hardware;//硬件同步HSYNC,VSYNC//应用设置DCMI_Init(&DCMI_InitStructure);DCMI_ITConfig(DCMI_IT_FRAME,ENABLE);//使能帧中断 DCMI_Cmd(ENABLE);//使能DCMI//此时不能捕获,还要启动传输NVIC_InitStructure.NVIC_IRQChannel=DCMI_IRQn;NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=0;//抢占优先级0NVIC_InitStructure.NVIC_IRQChannelSubPriority=0;//子优先级0NVIC_InitStructure.NVIC_IRQChannelCmd=ENABLE;//IRQ通道使能//应用设置NVIC_Init(&NVIC_InitStructure);
}//DCMI,启动传输
void DCMI_Start(void)
{  LCD_SetCursor(0,0);//重置LCDLCD_WriteRAM_Prepare();//开始写入GRAMDMA_Cmd(DMA2_Stream1, ENABLE);//开启DMA2Stream1 DCMI_CaptureCmd(ENABLE);//使能DCMI捕获
}
//DCMI,关闭传输
void DCMI_Stop(void)
{ DCMI_CaptureCmd(DISABLE);//关闭DCMI捕获   while(DCMI->CR&0X01);//等待传输结束DMA_Cmd(DMA2_Stream1,DISABLE);//关闭DMA2Stream1
}
  1. main()配置

main.c

#include "sys.h"
#include "delay.h"
#include "usart.h"
#include "led.h"
#include "key.h"
#include "lcd.h"
#include "usmart.h"
#include "usart2.h"
#include "timer.h"
#include "ov2640.h"
#include "dcmi.h" u8 ov2640_mode=0;//工作模式:0,RGB565模式;1,JPEG模式#define jpeg_buf_size 31*1024//定义JPEG数据缓存jpeg_buf的大小(*4字节)
__align(4) u32 jpeg_buf[jpeg_buf_size];//JPEG数据缓存buf
volatile u32 jpeg_data_len=0;//buf中的JPEG有效数据长度
volatile u8 jpeg_data_ok=0;//JPEG数据采集完成标志 //0,数据没有采集完;//1,数据采集完了,但是还没处理;//2,数据已经处理完成了,可以开始下一帧接收
//JPEG尺寸支持列表
const u16 jpeg_img_size_tbl[][2]=
{176,144,   //QCIF160,120,  //QQVGA352,288, //CIF320,240,   //QVGA640,480,  //VGA800,600,   //SVGA1024,768, //XGA1280,1024, //SXGA1600,1200,    //UXGA
};
const u8*EFFECTS_TBL[7]={"Normal","Negative","B&W","Redish","Greenish","Bluish","Antique"};//7种特效
const u8*JPEG_SIZE_TBL[9]={"QCIF","QQVGA","CIF","QVGA","VGA","SVGA","XGA","SXGA","UXGA"};//JPEG 9种尺寸 //处理JPEG数据
//当采集完一帧JPEG数据后,调用此函数,切换JPEG BUF.开始下一帧采集.
void jpeg_data_process(void)
{if(ov2640_mode)//只有在JPEG格式下,才需要做处理{if(jpeg_data_ok==0)//如果还未采集完数据{   DMA_Cmd(DMA2_Stream1, DISABLE);//停止当前传输 while(DMA_GetCmdStatus(DMA2_Stream1)!=DISABLE);//等待DMA2_Stream1可配置  jpeg_data_len=jpeg_buf_size-DMA_GetCurrDataCounter(DMA2_Stream1);//得到此次数据传输的长度jpeg_data_ok=1;//标记JPEG数据采集完成,等待其他函数处理}if(jpeg_data_ok==2)//如果jpeg数据已经被处理了{DMA2_Stream1->NDTR=jpeg_buf_size; DMA_SetCurrDataCounter(DMA2_Stream1,jpeg_buf_size);//传输长度为jpeg_buf_size*4字节DMA_Cmd(DMA2_Stream1,ENABLE);//重新传输jpeg_data_ok=0;//标记数据未采集}}
}//JPEG测试
//JPEG数据,通过串口1发送给电脑.
void jpeg_test(void)
{u32 i; u8* p;u8 key;u8 effect=0,saturation=2,contrast=2;u8 size=3;//默认QVGA 320*240尺寸u8 msgbuf[15];//消息缓存区 LCD_Clear(WHITE);POINT_COLOR=RED; LCD_ShowString(30,70,200,16,16,"OV2640 JPEG Mode");LCD_ShowString(30,100,200,16,16,"KEY0:Contrast");//对比度//LCD_ShowString(30,120,200,16,16,"KEY1:Saturation");//色彩饱和度//LCD_ShowString(30,140,200,16,16,"KEY2:Effects");//特效 LCD_ShowString(30,160,200,16,16,"KEY_UP:Size");//分辨率设置 sprintf((char*)msgbuf,"JPEG Size:%s",JPEG_SIZE_TBL[size]);LCD_ShowString(30,180,200,16,16,msgbuf);//显示当前JPEG分辨率OV2640_JPEG_Mode();//JPEG模式My_DCMI_Init();//初始化DCMIDCMI_DMA_Init((u32)&jpeg_buf,jpeg_buf_size,DMA_MemoryDataSize_Word,DMA_MemoryInc_Enable);//初始化DMAOV2640_OutSize_Set(jpeg_img_size_tbl[size][0],jpeg_img_size_tbl[size][1]);//设置输出尺寸DCMI_Start();//启动传输while(1){if(jpeg_data_ok==1)//若已经采集完一帧图像{  p=(u8*)jpeg_buf;LCD_ShowString(30,210,210,16,16,"Sending JPEG data...");//提示正在传输数据for(i=0;i<jpeg_data_len*4;i++)//dma传输1次等于4字节,要乘4{while((USART1->SR&0X40)==RESET);//循环发送直到发送完毕         USART1->DR=p[i];key=KEY_Scan(0);if(key)break;//若按键按下则需要处理,跳至下部分}if(key)//有按键按下,需要处理{  LCD_ShowString(30,210,210,16,16,"Quit Sending data");//提示退出数据传输switch(key){                 case KEY0_PRES://对比度设置contrast++;if(contrast>4)contrast=0;OV2640_Contrast(contrast);sprintf((char*)msgbuf,"Contrast:%d",(signed char)contrast-2);break;case KEY1_PRES://饱和度Saturation//saturation++;//if(saturation>4)saturation=0;//OV2640_Color_Saturation(saturation);//sprintf((char*)msgbuf,"Saturation:%d",(signed char)saturation-2);break;case KEY2_PRES://特效设置              //effect++;//if(effect>6)effect=0;//OV2640_Special_Effects(effect);//设置特效//sprintf((char*)msgbuf,"%s",EFFECTS_TBL[effect]);break;case WKUP_PRES://JPEG输出尺寸设置   size++;  if(size>8)size=0;   OV2640_OutSize_Set(jpeg_img_size_tbl[size][0],jpeg_img_size_tbl[size][1]);//设置输出尺寸  sprintf((char*)msgbuf,"JPEG Size:%s",JPEG_SIZE_TBL[size]);break;}LCD_Fill(30,180,239,190+16,WHITE);LCD_ShowString(30,180,210,16,16,msgbuf);//显示提示内容delay_ms(800);                   }else LCD_ShowString(30,210,210,16,16,"Send data complete!!");//提示传输结束设置 jpeg_data_ok=2;   //标记jpeg数据处理完毕,可以让DMA采集下一帧}     }
} //RGB565测试
//RGB数据直接显示在LCD上面
void rgb565_test(void)
{ u8 key;u8 effect=0,saturation=2,contrast=2;u8 scale=1;//默认是全尺寸缩放u8 msgbuf[15];//消息缓存区LCD_Clear(WHITE);POINT_COLOR=RED; LCD_ShowString(30,70,200,16,16,"OV2640 RGB565 Mode");LCD_ShowString(30,100,200,16,16,"KEY0:Contrast");//对比度//LCD_ShowString(30,130,200,16,16,"KEY1:Saturation");//色彩饱和度//LCD_ShowString(30,150,200,16,16,"KEY2:Effects");//特效 LCD_ShowString(30,170,200,16,16,"KEY_UP:FullSize/Scale");//1:1尺寸(显示真实尺寸)/全尺寸缩放OV2640_RGB565_Mode();//RGB565模式My_DCMI_Init();//DCMI配置DCMI_DMA_Init((u32)&LCD->LCD_RAM,1,DMA_MemoryDataSize_HalfWord,DMA_MemoryInc_Disable);//DCMI DMA配置  OV2640_OutSize_Set(lcddev.width,lcddev.height); DCMI_Start();//启动传输while(1){key=KEY_Scan(0); if(key){ DCMI_Stop();//停止显示switch(key){                  case KEY0_PRES://对比度设置contrast++;if(contrast>4)contrast=0;OV2640_Contrast(contrast);sprintf((char*)msgbuf,"Contrast:%d",(signed char)contrast-2);break;case KEY1_PRES:  //饱和度Saturation//saturation++;//if(saturation>4)saturation=0;//OV2640_Color_Saturation(saturation);//sprintf((char*)msgbuf,"Saturation:%d",(signed char)saturation-2);break;case KEY2_PRES://特效设置                //effect++;//if(effect>6)effect=0;//OV2640_Special_Effects(effect);//设置特效//sprintf((char*)msgbuf,"%s",EFFECTS_TBL[effect]);break;case WKUP_PRES://1:1尺寸(显示真实尺寸)/缩放     scale=!scale;  if(scale==0){OV2640_ImageWin_Set((1600-lcddev.width)/2,(1200-lcddev.height)/2,lcddev.width,lcddev.height);//1:1真实尺寸OV2640_OutSize_Set(lcddev.width,lcddev.height); sprintf((char*)msgbuf,"Full Size 1:1");}else{OV2640_ImageWin_Set(0,0,1600,1200);             //全尺寸缩放OV2640_OutSize_Set(lcddev.width,lcddev.height); sprintf((char*)msgbuf,"Scale");}break;}LCD_ShowString(30,50,210,16,16,msgbuf);//显示提示内容delay_ms(800);DCMI_Start();//重新开始传输} delay_ms(10);       }
}int main(void)
{ u8 key;u8 t;NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);//设置系统中断优先级分组2delay_init(168);//初始化延时函数uart_init(115200);//初始化串口波特率为115200usart2_init(42,115200);//初始化串口2波特率为115200LED_Init();//初始化LED LCD_Init();//LCD初始化  KEY_Init();//按键初始化 TIM3_Int_Init(10000-1,8400-1);//10Khz计数,1秒钟中断一次usmart_dev.init(84);//初始化USMARTPOINT_COLOR=RED;//设置字体为红色 while(OV2640_Init())//初始化OV2640{LCD_ShowString(30,130,240,16,16,"OV2640 ERR");delay_ms(200);LCD_Fill(30,130,239,170,WHITE);delay_ms(200);}LCD_ShowString(30,130,200,16,16,"OV2640 OK");while(1){   key=KEY_Scan(0);if(key==KEY0_PRES)//RGB565模式{ov2640_mode=0;   break;}else if(key==WKUP_PRES)//JPEG模式{ov2640_mode=1;break;}t++;                                       if(t==100)LCD_ShowString(30,150,230,16,16,"KEY0:RGB565  KEY_UP:JPEG");//闪烁显示提示信息if(t==200){ LCD_Fill(30,150,230,150+16,WHITE);t=0; }delay_ms(5);}if(ov2640_mode)jpeg_test();else rgb565_test();
}

STM32F4外设配置速查【OV2640摄像头部分】相关推荐

  1. STM32H7外设配置速查【QSPI部分】

    QSPI协议 QSPI是Queued SPI(队列串行外围接口)的缩写,是由摩托罗拉公司推出的SPI协议的一个扩展,比SPI应用更加广泛,现在的FLASH.SRAM等存储器大多支持QSPI协议--QS ...

  2. STM32F407获取OV2640摄像头图像及上位机解码(一维码二维码)

    STM32F407获取OV2640摄像头图像及上位机解码(一维码&二维码) 1. 目的 针对静止拍摄图像场景,实现STM32F407对200万像素OV2640摄像头进行图像捕获,并通过串口将数 ...

  3. Postfix 配置参数速查

    本附录按照字母顺序,列出可在main.cf配置文件里设定的参数,并简略说明各参数的意义或用途.本附录只能算是postfix参数的"速查参考". 所有参数都有一个默认值(虽然某些默认 ...

  4. (40)STM32——OV2640摄像头实验

    目录 学习目标 运行结果 内容 OV2640 特点 时序 帧输出时序 配置 DCMI 特点 信号 DMA 寄存器 配置 硬件连接 代码 总结 学习目标 今天我们要学习的是OV2640摄像头实验,采用的 ...

  5. STM32 F4 OV2640摄像头学习笔记(一)

    //尝试写作,记录学习过程. 一.OV2640摄像头简介 本节将主要讲解OV2640摄像头基础部分和一些引脚配置. OV2640传感器简介 OV2640是Omni Vision公司生产的一颗1/4寸的 ...

  6. 【STM32】OV2640摄像头学习笔记 转

    [STM32]OV2640摄像头学习笔记 2019年03月03日 13:01:35 淹死的大白鲨 阅读数 4736更多 分类专栏: [STM32] 版权声明:本文为博主原创文章,遵循 CC 4.0 B ...

  7. 简述sed、grep和parted的速查表

    下载 sed.grep和parted的速查表来整合新的流程到你的工作中. Linux 因其命令闻名,部分原因是 Linux 执行的几乎所有操作都可以从终端调用:另一部分原因是 Linux 是一个高度模 ...

  8. java全能速查宝典.chm_Java API 快速速查宝典

    ava API 快速速查宝典 作者:明日科技,陈丹丹,李银龙,王国辉 著 出版社:人民邮电出版社 出版时间:2012年5月 Java编程的最基本要素是方法.属性和事件,掌握这些要素,就掌握了解决实际问 ...

  9. Git 常用命令速查表(图文+表格)

    一. Git 常用命令速查 git branch 查看本地所有分支 git status 查看当前状态  git commit 提交  git branch -a 查看所有的分支 git branch ...

最新文章

  1. linux磁盘配额管理
  2. mysql:mysql error:Access denied for user 'root'@'localhost' (using password: YES)
  3. 从零开始学习jQuery (二) 万能的选择器
  4. C++ Primer 5th笔记(6)chapter6 函数: 参数
  5. CCS5连接调试C64X系列DSP核
  6. poj 1230(贪心)
  7. 高效率读写文件方法比较
  8. 如何为resin的jvm-default.log瘦身
  9. python离线安装whl文件.
  10. plist 与 JOSN的解析
  11. ue4渲染速度太慢_看虚幻引擎技术大神分享烧脑干货《克服VR眩晕之帧数:提升UE4内容实时渲染效率》...
  12. 使用迅雷9.1.48从ftp服务器下载文件
  13. [Matlab]FIR滤波器设计:(基本窗函数FIR滤波器设计)
  14. 计算机网络期末试题及答案
  15. 中国空气质量在线监测分析平台-js混淆的坑
  16. 应聘中巧用积极的心理暗示
  17. Historic Exhibition 贪心
  18. Educational Codeforces Round 132 div.2 A-F题解
  19. 成也IP败也IP,中日美盲盒经济背后不变的商业逻辑
  20. 软考高级系统分析师知识点整理

热门文章

  1. iOS中 本地通知/本地通知详解 韩俊强的博客
  2. 双11狂欢节模板 让大屏“闪电”起来
  3. 群晖网络不通_一次拯救群晖NAS数据的历程
  4. excel导出复杂表格
  5. iOS黑科技之(AVFoundation)动态人脸识别(二)
  6. 谷歌字体着色HTML,谷歌浏览器不支持11px字体_html/css_WEB-ITnose
  7. 全球计算机ACM总决赛浙大第…
  8. 【c语言】按位与、按位或、按位异或。
  9. brew开发--FM 收音机
  10. CSI室内指纹定位——CSI数据说明