今天学习摄像头模块,使用该模块进行拍摄,照相等功能进行对stm32 控制板的结合,了解他的原理以及应用。
主角: ov7670摄像头模块。(大概了解一下产品背景)
OV7670 是 OV( OmniVision)公司生产的一颗 1/6 寸的 CMOS VGA 图像传 感器。该传感器体积小、工作电压低,提供单片 VGA 摄像头和影像处理器的所 有功能。通过 SCCB 总线控制,可以输出整帧、子采样、取窗口等方式的各种分 辨率 8 位影像数据。该产品 VGA 图像最高达到 30 帧/秒。用户可以完全控制 图像质量、数据格式和传输方式。所有图像处理功能过程包括伽玛曲线、白平衡、 度、色度等都可以通过 SCCB 接口编程。 OmmiVision 图像传感器应用独有的传 感器技术,通过减少或消除光学或电子缺陷如固定图案噪声、托尾、浮散等,提 高图像质量,得到清晰的稳定的彩色图像。(官方说明请进一步查看说明文档,部分 中文版翻译有出入,有能力的可以看英文版的)
SCCB?(后面会用到这里简单讲解一下)
SCCB是欧姆尼图像技术公司(OmniVision)开发的一种总线,并广泛的应用于OV系列图像传感器上,所以一般使用OV的图像传感器都离不开SCCB总线协议。可以通俗地讲SCCB有两种工作模式,一主多从,一主一从模式。
参考正反面接线柱以及元器件(如下图)
实物图如下
OV7670 的特点有:
(1)高灵敏度、低电压适合嵌入式应用
(2)标准的 SCCB 接口,兼容 IIC 接口
(3)支持 RawRGB、RGB(GBR4:2:2,RGB565/RGB555/RGB444),YUV(4:2:2) 和 YCbCr( 4:2:2)输出格式
(4)支持 VGA、 CIF,和从 CIF 到 40*30 的各种尺寸输出
(5)支持自动曝光控制、自动增益控制、自动白平衡、自动消除灯光条纹、 自动黑电平校准等自动控制功能。同时支持色饱和度、色相、伽马、锐度等设置。
(6)支持闪光灯
(7)支持图像缩放
应用,进行拍摄,画面传输在控制板的TFT 屏幕上,下期更新拍照。
OV7670 传感器 功能模块:
1.感光整列( Image Array) OV7670 总共有 656488 个像素,其中 640480 个有效(即有效像素为 30W)。
2.时序发生器( Video Timing Generator) 时序发生器具有的功能包括:整列控制和帧率发生( 7 种不同格式输出)、 内部信号发生器和分布、帧率时序、自动曝光控制、输出外部时序( VSYNC帧同步信号、 HREF/HSYNC同步信号 和 PCLK像素时钟)。
3.模拟信号处理( Analog Processing) 模拟信号处理所有模拟功能,并包括:自动增益( AGC)和自动白平衡( AWB)。
4.A/D 转换( A/D) 原始的信号经过模拟处理器模块之后 ,分 G 和 BR 两路进入一个 10 位的 A/D 转换器,A/D 转换器工作在 12M 频率,与像素频率完全同步(转换的频率 和帧率有关)。 除 A/D 转换器外,该模块还有以下三个功能: ①黑电平校正( BLC) ②U/V 通道延迟 ③A/D 范围控制 A/D 范围乘积和 A/D 的范围控制共同设置 A/D 的范围和最大值,允许用户 2根据应用调整图片的亮度。
5.测试图案发生器( Test Pattern Generator) 测试图案发生器功能包括:八色彩色条图案、渐变至黑白彩色条图案和输出 脚移位“ 1”。
6.数字处理器( DSP) 这个部分控制由原始信号插值到 RGB 信号的过程,并控制一些图像质量: ①边缘锐化(二维高通滤波器) ②颜色空间转换(原始信号到 RGB 或者 YUV/YCbYCr) ③RGB 色彩矩阵以消除串扰 ④色相和饱和度的控制 ⑤黑/白点补偿 ⑥降噪 ⑦镜头补偿 ⑧可编程的伽玛 ⑨十位到八位数据转换
7.缩放功能( Image Scaler) 这个模块按照预先设置的要求输出数据格式,能将 YUV/RGB 信号从 VGA 缩 小到 CIF 以下的任何尺寸。
8.数字视频接口( Digital Video Port) 通过寄存器 COM2[1:0],调节 IOL/IOH 的驱动电流,以适应用户的负载。
9.SCCB 接口( SCCB Interface) SCCB 接 口 控 制 图 像 传 感 器 芯 片 的 运 行 , 详 细 使 用 方 法 参 照 《 OmniVisionTechnologies Seril Camera Control Bus(SCCB) Specification》 这个文档。
10.LED 和闪光灯的输出控制( LED and Storbe Flash Control Output) OV7670 有闪光灯模式,可以控制外接闪光灯或闪光 LED 的工作。 OV7670 的寄存器通过 SCCB 时序访问并设置,SCCB 时序和 IIC 时序十分 类似,在这里我们不做介绍,请大家参考模块的相关文档。
重点定义:
VGA,即分辨率为 640480 的输出模式;
QVGA,即分辨率为 320240 的输出格式,也就是本手册我们需要用到的格 式;
QQVGA,即分辨率为 160*120 的输出格式;
PCLK,即像素时钟,一个 PCLK 时钟,输出一个像素(或半个像素)。
VSYNC,即帧同步信号。
HREF /HSYNC,即行同步信号。
图像输出的控制条件
OV7670 的图像数据输出(通过 D[7:0])就是在 PCLK, VSYNC 和 HREF/ HSYNC 的控制下进行的。
首先看看行输出时序,如图所示:
-----上属已经初步了解了0V7670的原理和背景(下面市重点),下面学习OV7670 模块使用方法-------------------------
下面图像数据的存储于读取的过程分析
如何存储图像数据?
-OV7670 摄像头模块存储图像数据的过程为:等待 OV7670 同步信号→ FIFO 写指针复位→FIFO 写使能→等待第二个 OV7670 同步信号→FIFO 写禁 止。通过以上 5 个步骤,我们就完成了 1 帧图像数据的存储
如何读取图像数据?
在存储完一帧图像以后,我们就可以开始读取图像数据了。读取过程为: FIFO 读指针复位→给 FIFO 读时钟( FIFO_RCLK)→读取第一个像素高字节→ 给 FIFO 读时钟→读取第一个像素低字节→给 FIFO 读时钟→读取第二个像素 高字节→循环读取剩余像素→结束。
原理图如下所示
由上图可以看出0v7670(图片信号) ------传输数据到--------->FIFO------------------------>经过输出模块------------------->mcu (我们拿到的图片信息)
下面直接开始分析代码函数的使用
初始化SCCB接口(前面讲到使用sccb 进行控制图像)/
初始化OV7670
设置图像输出窗口
帧中断标记
更新LCD显示
//初始化SCCB接口
//CHECK OK
void SCCB_Init(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOD|RCC_APB2Periph_GPIOG, ENABLE);
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_13; // 端口配置
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU; //输入
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOG, &GPIO_InitStructure);
GPIO_SetBits(GPIOG,GPIO_Pin_13); // 输出高
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_3; // 端口配置
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; //输输出
GPIO_Init(GPIOD, &GPIO_InitStructure);
GPIO_SetBits(GPIOD,GPIO_Pin_3); // 输出高
SCCB_SDA_OUT();
}
//初始化OV7670
//返回0:成功
//返回其他值:错误代码
u8 OV7670_Init(void)
{
u8 temp;
u16 i=0;
//设置IO
GPIO_InitTypeDef GPIO_InitStructure;
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA|RCC_APB2Periph_GPIOB|RCC_APB2Periph_GPIOC|RCC_APB2Periph_GPIOD|RCC_APB2Periph_GPIOG|RCC_APB2Periph_AFIO, ENABLE); //使能相关端口时钟
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_8; //PA8 输入 上拉 **VSYNC**
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOA, &GPIO_InitStructure);
GPIO_SetBits(GPIOA,GPIO_Pin_8);
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_3|GPIO_Pin_4;// 端口配置SWD 禁止swj 因为默认的PB3和pb4 是Jtag下载占用
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; //推挽输出
GPIO_Init(GPIOB, &GPIO_InitStructure);
GPIO_SetBits(GPIOB,GPIO_Pin_3|GPIO_Pin_4);
GPIO_InitStructure.GPIO_Pin = 0xff; //PC0~7 输入 上拉
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;
GPIO_Init(GPIOC, &GPIO_InitStructure);
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
GPIO_Init(GPIOD, &GPIO_InitStructure);
GPIO_SetBits(GPIOD,GPIO_Pin_6);
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_14|GPIO_Pin_15;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
GPIO_Init(GPIOG, &GPIO_InitStructure);
GPIO_SetBits(GPIOG,GPIO_Pin_14|GPIO_Pin_15);
GPIO_PinRemapConfig(GPIO_Remap_SWJ_JTAGDisable,ENABLE); //SWD 禁止swj 因为默认的PB3和pb4 是Jtag下载占用的
SCCB_Init(); //初始化SCCB 的IO口
if(SCCB_WR_Reg(0x12,0x80))return 1; //复位SCCB
delay_ms(50);
//读取产品型号
temp=SCCB_RD_Reg(0x0b);
if(temp!=0x73)return 2;
temp=SCCB_RD_Reg(0x0a);
if(temp!=0x76)return 2;
//初始化序列
for(i=0;i<sizeof(ov7670_init_reg_tbl)/sizeof(ov7670_init_reg_tbl[0]);i++)
{
//初始化寄存器序列及其对应的值
SCCB_WR_Reg(ov7670_init_reg_tbl[i][0],ov7670_init_reg_tbl[i][1]); //SCCB_WR_Reg对ov7670_init_reg_tbl的写入完成初始化
}
return 0x00; //ok
}
//设置图像输出窗口
//对QVGA设置。 可参考0v7670分辨率设置文档
void OV7670_Window_Set(u16 sx,u16 sy,u16 width,u16 height)
{
u16 endx;
u16 endy;
u8 temp;
endx=sx+width*2; //V*2
endy=sy+height*2;
if(endy>784)endy-=784;
temp=SCCB_RD_Reg(0X03); //读取Vref之前的值
temp&=0XF0;
temp|=((endx&0X03)<<2)|(sx&0X03);
SCCB_WR_Reg(0X03,temp); //设置Vref的start和end的最低2位
SCCB_WR_Reg(0X19,sx>>2); //设置Vref的start高8位
SCCB_WR_Reg(0X1A,endx>>2); //设置Vref的end的高8位
temp=SCCB_RD_Reg(0X32); //读取Href之前的值
temp&=0XC0;
temp|=((endy&0X07)<<3)|(sy&0X07);
SCCB_WR_Reg(0X17,sy>>3); //设置Href的start高8位
SCCB_WR_Reg(0X18,endy>>3); //设置Href的end的高8位
}
//等待ov7670 帧同步信号(帧中断标记是否开始)
u8 ov_sta; //帧中断标记
void EXTI9_5_IRQHandler(void) //红外遥控外部中断
{
if(EXTI_GetITStatus(EXTI_Line8)==SET) //是8线的中断
{
if(ov_sta<2)
{
if(ov_sta==0)
{
OV7670_WRST=0; //复位写指针
OV7670_WRST=1;
OV7670_WREN=1; //允许写入FIFO
}
else
{
OV7670_WREN=0;//禁止写入FIFO
OV7670_WRST=0; //复位写指针
OV7670_WRST=1;
}
ov_sta++; //帧中断加1
}
}
EXTI_ClearITPendingBit(EXTI_Line8); //清除EXTI8线路挂起位
}
//更新LCD显示
void camera_refresh(void)
{
u32 j;
u16 color;
if(ov_sta)//有帧中断更新?
{
LCD_Display_Dir(1);
LCD_Set_Window(0,0,320-1,240-1);//将显示区域设置到屏幕中央
OV7670_RRST=0; //开始复位读指针
OV7670_RCK_L;
OV7670_RCK_H;
OV7670_RCK_L;
OV7670_RRST=1; //复位读指针结束
OV7670_RCK_H;
for(j=0;j<76800;j++) //此种方式需清楚TFT内部显示方向控制寄存器值 速度较快
{
OV7670_RCK_L;
color=GPIOC->IDR&0XFF; //读数据
OV7670_RCK_H;
color<<=8;
OV7670_RCK_L;
color|=GPIOC->IDR&0XFF; //读数据
OV7670_RCK_H;
LCD_WriteData_Color(color);
}
ov_sta=0; //清零帧中断标记
ov_frame++;
LCD_Display_Dir(0);
}
}
我们使用的话,直接将sccb 引入我们的项目,直接使用函数
sccb。h 文件
#ifndef __SCCB_H
#define __SCCB_H
#include "system.h"
//#define SCCB_SDA_IN() {GPIOG->CRH&=0XFF0FFFFF;GPIOG->CRH|=0X00800000;}
//#define SCCB_SDA_OUT() {GPIOG->CRH&=0XFF0FFFFF;GPIOG->CRH|=0X00300000;}
//IO操作函数
#define SCCB_SCL PDout(3) //SCL
#define SCCB_SDA PGout(13) //SDA
#define SCCB_READ_SDA PGin(13) //输入SDA
#define SCCB_ID 0X42 //OV7670的ID
///
void SCCB_Init(void);
void SCCB_Start(void);
void SCCB_Stop(void);
void SCCB_No_Ack(void);
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
```c
#include "system.h"
#include "sccb.h"
#include "SysTick.h"
void SCCB_SDA_OUT(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_13; // 端口配置
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOG, &GPIO_InitStructure);
}
void SCCB_SDA_IN(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_13; // 端口配置
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU; //输入
GPIO_Init(GPIOG, &GPIO_InitStructure);
}
//初始化SCCB接口
//CHECK OK
void SCCB_Init(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOD|RCC_APB2Periph_GPIOG, ENABLE);
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_13; // 端口配置
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU; //输入
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOG, &GPIO_InitStructure);
GPIO_SetBits(GPIOG,GPIO_Pin_13); // 输出高
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_3; // 端口配置
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; //输输出
GPIO_Init(GPIOD, &GPIO_InitStructure);
GPIO_SetBits(GPIOD,GPIO_Pin_3); // 输出高
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;
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;
else SCCB_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)res=1; //SDA=1发送失败,返回1
else res=0; //SDA=0发送成功,返回0
SCCB_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();
return res;
}
//读寄存器
//返回值:读到的寄存器值
u8 SCCB_RD_Reg(u8 reg)
{
u8 val=0;
SCCB_Start(); //启动SCCB传输
SCCB_WR_Byte(SCCB_ID); //写器件ID
delay_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;
}
主函数main
extern u8 ov_sta;
extern u8 ov_frame; //在time.c里面定义
更新LCD显示
void camera_refresh(void)
{
u32 j;
u16 color;
if(ov_sta)//有帧中断更新?
{
LCD_Display_Dir(1);
LCD_Set_Window(0,0,320-1,240-1);//将显示区域设置到屏幕中央
OV7670_RRST=0; //开始复位读指针
OV7670_RCK_L;
OV7670_RCK_H;
OV7670_RCK_L;
OV7670_RRST=1; //复位读指针结束
OV7670_RCK_H;
for(j=0;j<76800;j++) //此种方式需清楚TFT内部显示方向控制寄存器值 速度较快
{
OV7670_RCK_L;
color=GPIOC->IDR&0XFF; //读数据
OV7670_RCK_H;
color<<=8;
OV7670_RCK_L;
color|=GPIOC->IDR&0XFF; //读数据
OV7670_RCK_H;
LCD_WriteData_Color(color);
}
ov_sta=0; //清零帧中断标记
ov_frame++;
LCD_Display_Dir(1); //设置扫描方向
//定位颜色识别区域
if(Trace(&condition, &result))
{
LCD_DrawRectangle( result.x-result.w/2, result.y-result.h/2, result.x-result.w/2+result.w, result.y-result.h/2+result.h);
LCD_DrawRectangle( result.x-2, result.y-2,result.x+2, result.y+2);
}
}
}
const u8*LMODE_TBL[5]={"Auto","Sunny","Cloudy","Office","Home"};
const u8*EFFECTS_TBL[7]={"Normal","Negative","B&W","Redish","Greenish","Bluish","Antique"}; //7种特效
int main()
{
u8 i=0;
u8 key;
u8 lightmode=0,saturation=2,brightness=2,contrast=2;
u8 effect=0;
u8 sbuf[15];
u8 count;
SysTick_Init(72);
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2); //中断优先级分组 分2组
LED_Init();
USART1_Init(115200);
TFTLCD_Init(); //LCD初始化
KEY_Init();
EN25QXX_Init(); //初始化EN25Q128
my_mem_init(SRAMIN); //初始化内部内存池
FRONT_COLOR=RED;//设置字体为红色
LCD_ShowString(10,10,tftlcd_data.width,tftlcd_data.height,16,"PRECHIN STM32F1");
LCD_ShowString(10,30,tftlcd_data.width,tftlcd_data.height,16,"www.prechin.net");
LCD_ShowString(10,50,tftlcd_data.width,tftlcd_data.height,16,"OV7670 Test");
while(OV7670_Init())//初始化OV7670
{
LCD_ShowString(10,80,tftlcd_data.width,tftlcd_data.height,16,"OV7670 Error!");
delay_ms(200);
LCD_Fill(10,80,239,206,WHITE);
delay_ms(200);
}
LCD_ShowString(10,80,tftlcd_data.width,tftlcd_data.height,16,"OV7670 OK! ");
delay_ms(1500);
OV7670_Light_Mode(0);
OV7670_Color_Saturation(2);
OV7670_Brightness(2);
OV7670_Contrast(2);
OV7670_Special_Effects(0);
TIM4_Init(10000,7199); //10Khz计数频率,1秒钟中断
EXTI8_Init();
OV7670_Window_Set(12,176,240,320); //设置窗口
OV7670_CS=0;
LCD_Clear(BLACK);
while(1)
{
key=KEY_Scan(0);
if(key)count=20;
switch(key)
{
case KEY_UP_PRESS: //灯光模式设置
lightmode++;
if(lightmode>4)lightmode=0;
OV7670_Light_Mode(lightmode);
sprintf((char*)sbuf,"%s",LMODE_TBL[lightmode]);
break;
case KEY1_PRESS: //饱和度
saturation++;
if(saturation>4)saturation=0;
OV7670_Color_Saturation(saturation);
sprintf((char*)sbuf,"Saturation:%d",(char)saturation-2);
break;
case KEY2_PRESS: //亮度
brightness++;
if(brightness>4)brightness=0;
OV7670_Brightness(brightness);
sprintf((char*)sbuf,"Brightness:%d",(char)brightness-2);
break;
case KEY0_PRESS: //对比度
contrast++;
if(contrast>4)contrast=0;
OV7670_Contrast(contrast);
sprintf((char*)sbuf,"Contrast:%d",(char)contrast-2);
break;
}
if(count)
{
count--;
LCD_ShowString((tftlcd_data.width-240)/2+30,(tftlcd_data.height-320)/2+60,200,16,16,sbuf);
}
camera_refresh();//更新显示
i++;
if(i%20==0)
{
LED1=!LED1;
}
// delay_ms(5);
}
}
总结:
摄像头模块内容相对以往 比较多,获取图像,图像转化-再到显示-帧数更新显示。
SCCB 库的使用
注释,代码我学习使用的是普中的代码f103zet6,战舰V3 ,需要完整版本的demo 私信
上一节 stm32 MPU6050 6轴姿态传感器的介绍与DMP的应用