#include "sys.h" #include "ov2640.h" #include "ov2640cfg.h" //#include "timer.h" #include "delay.h" #include "usart.h" #include "sccb.h" #include "stdio.h" ////////////////////////////////////////////////////////////////////////////////// //本程序只供学习使用,未经作者许可,不得用于其它任何用途 //ALIENTEK STM32F103开发板 //OV2640 驱动代码 //正点原子@ALIENTEK //技术论坛:www.openedv.com //创建日期:2015/4/16 //版本:V1.0 //版权所有,盗版必究。 //Copyright(C) 广州市星翼电子科技有限公司 2014-2024 //All rights reserved ////////////////////////////////////////////////////////////////////////////////// //初始化OV2640 //配置完以后,默认输出是1600*1200尺寸的图片!! //返回值:0,成功 // 其他,错误代码 void OV2640_PWDN(uint8_t signal) { HAL_GPIO_WritePin(GPIOB, GPIO_PIN_15, (GPIO_PinState)signal); } void OV2640_RST(uint8_t signal) { HAL_GPIO_WritePin(GPIOB, GPIO_PIN_13, (GPIO_PinState)signal); } uint8_t OV2640_Init(void) { uint16_t i=0; uint16_t reg; //设置IO GPIO_InitTypeDef GPIO_InitStructure; __HAL_RCC_GPIOG_CLK_ENABLE(); //使能GPIOB时钟 HAL_GPIO_WritePin(GPIOB, GPIO_PIN_13|GPIO_PIN_15, GPIO_PIN_RESET); //GPIOF9,F10初始化设置 GPIO_InitStructure.Pin = GPIO_PIN_13|GPIO_PIN_15; GPIO_InitStructure.Mode = GPIO_MODE_OUTPUT_PP; GPIO_InitStructure.Speed = GPIO_SPEED_FAST; GPIO_InitStructure.Pull = GPIO_PULLUP;//上拉 HAL_GPIO_Init(GPIOB, &GPIO_InitStructure);//初始� OV2640_PWDN(0); //POWER ON delay_ms(10); OV2640_RST(0); //复位OV2640 delay_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); //软复位OV2640 delay_ms(50); reg=SCCB_RD_Reg(OV2640_SENSOR_MIDH); //读取厂家ID 高八位 reg<<=8; reg|=SCCB_RD_Reg(OV2640_SENSOR_MIDL); //读取厂家ID 低八位 printf("OV2640_MID = %#X\n" , reg); 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; } for(i=0;i>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,设置成功 // 其他,设置失败 uint8_t OV2640_OutSize_Set(uint16_t width,uint16_t height) { uint16_t outh; uint16_t outw; uint8_t 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,设置成功 // 其他,设置失败 uint8_t OV2640_ImageWin_Set(uint16_t offx,uint16_t offy,uint16_t width,uint16_t height) { uint16_t hsize; uint16_t vsize; uint8_t 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,设置成功 // 其他,设置失败 uint8_t OV2640_ImageSize_Set(uint16_t width,uint16_t height) { uint8_t 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; }