|
楼主 |
发表于 2021-3-28 21:28:01
|
显示全部楼层
二.C51代码部分
这部分的核心主要是OV2640摄像头的驱动代码以及jpg图片的显示代码,对于OV2640的驱动代码,主要由如下图中的5个文件组成:
因为OV2640摄像头是采用SCCB接口对外通信的,这种接口类似于IIC接口,下面我再给出OV2640与EK043迪文屏的硬件连线说明,如下代码所示:
sbit OV2640_PWDN = P2^2; //POWER DOWN控制信号
sbit OV2640_RST = P2^3; //复位控制信号
sbit OV2640_VSYNC = P2^4; //VSYNC信号
sbit OV2640_HREF = P2^5; //HREF信号
sbit OV2640_PCLK = P2^6; //PCLK信号
#define OV2640_DATA P1 //数据输入端口,8位
sbit SCCB_SCL = P2^0; //SCCB接口的SCL
sbit SCCB_SDA = P2^1; //SCCB接口的SDA线
再次说明一下,大家用杜邦线或者飞线连接时,尽量保持短,然后再来看一下main.c文件:
xdata u8 jpg_buf[20000];//定义一个大缓冲区,用来存放摄像头传出来的jpg图片数据
xdata u32 jpg_len;
void main(void)
{
u16 res;
sys_init();//系统初始化
res = OV2640_Init();//初始化OV2640摄像头
sys_write_vp(0x1000,(u8*)&res,1);//把初始化结果显示到屏幕上
//开始采集摄像头的jpg图片
OV2640_JPEG_Mode();//将摄像头设置为JPG模式
OV2640_OutSize_Set(320,240);//图片输出大小,注意这个大小不能随意设置,
SCCB_WR_Reg(0XFF,0X00);
SCCB_WR_Reg(0XD3,30);
SCCB_WR_Reg(0XFF,0X01);
SCCB_WR_Reg(0X11,0X1);
while(1)
{
//开始采集一张jpg图片
jpg_len = 0;
while(OV2640_VSYNC)
{
while(OV2640_HREF)
{
while(OV2640_PCLK==0);
jpg_buf[jpg_len] = OV2640_DATA;
while(OV2640_PCLK);
jpg_len++;
}
}
//将jpg图片显示到屏幕上
sys_draw_jpg(0x2000,jpg_buf,jpg_len);
}
}
在main.c中主要是先采集jpg图片数据,然后通过sys_draw_jpg函数把图片显示到迪文屏上,sys_draw_jpg函数的实现,我是根据官方文档来编写的,具体代码如下所示:
//动态绘制jpg图片
//vp:图标叠加控件的vp地址,必须为偶数
//jpg_data:jpg图片的原始数据
//data_len:jpg图片的原始数据的长度,单位字节
void sys_draw_jpg(u16 vp,u8 *jpg_data,u32 data_len)
{
u32 i;
for(i=0;i<data_len;i++)//查找0xFF,0xD8,也就是jpg图像的起始数据
{
if((jpg_data[i]==0xFF)&&(jpg_data[i+1]==0xD8))
break;
}
if(i==data_len)
return;
data_len = (data_len-i)/2+1;//得到字节,宁可多写一个字
sys_write_vp(vp+2,jpg_data+i,data_len);
data_len |= 0x5AA50000;
sys_write_vp(vp,(u8*)&data_len,2);
}
好了,整个项目的实现细节差不多就这么多!
|
|