【单片机开发】OV2640在没有DCMI接口的情况下的STM32驱动

article/2025/9/20 14:10:08

文章目录

  • (一)背景介绍
  • (二)接线
  • (三)软件实现

(一)背景介绍

在之前刚学STM32的时候完成了一个ov7670的驱动
ov7670驱动
已经快要两年过去了,最近抽了一点时间又将之前搞得ov2640的驱动完善了一下
看一下效果吧。

请添加图片描述

请添加图片描述

请添加图片描述

(二)接线

GNDSCLSDAD0D2D4D6PCLKPWDN
GNDPC1PC0PA0PA2PA4PA6PB10PC3
3.3VSYNCHREFRSTD1D3D5D7NC
3.3PC13PB11PC2PA1PA3PA5PA7随便

(三)软件实现

main.c

#include "led.h"
#include "delay.h"
#include "sys.h"
#include "usart.h"
#include "KEY.h"
#include "adc.h"
#include "malloc.h"
#include "Camera.h"
#include "LCD.h"
//PWDN 掉电模式高电平有效
//HREF 行同步信号
//VSYNC 帧同步信号
//PCLK像素同步信号 OV2640自带晶振,直接设置为输入//GND	SCL	SDA	D0  D2  D4  D6   PCLK PWDN
//GND PC1 PC0 PA0 PA2 PA4 PA6  PB10	PC3//3.3 VSYNC HREF RST D1  D3  D5  D7   NC 
//3.3 PC13  PB11 PC2 PA1 PA3 PA5 PA7
#define JPEG_TEST#ifdef JPEG_TEST
//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
}; 
u8* jpeg_buf;
#define jpeg_buf_size 40*1024  			//定义JPEG数据缓存jpeg_buf的大小(*4字节)
volatile u32 jpeg_data_len=0; 			//buf中的JPEG有效数据长度 
/* 串口1发送数组 */
void JPEG_DMA_SendArray()
{uint16_t sendLen =jpeg_buf_size;	// 防止越界while (DMA_GetCurrDataCounter(DMA1_Channel4));  // 检查DMA发送通道内是否还有数据// DMA发送数据-要先关 设置发送长度 开启DMADMA_Cmd(DMA1_Channel4, DISABLE);DMA_SetCurrDataCounter(DMA1_Channel4, sendLen);   // 重新写入要传输的数据数量DMA_Cmd(DMA1_Channel4, ENABLE);     // 启动DMA发送  
}
//JPEG测试
//JPEG数据,通过串口1发送给电脑.
void jpeg_test(void)
{u32 i; u8 *p;u8 key;u8 effect=0,expose=0;u8 size=3;		//默认是QVGA 320*240尺寸u8 msgbuf[15];	//消息缓存区 mem_init();	jpeg_buf=mymalloc(jpeg_buf_size);//32K左右while(!jpeg_buf)	{printf("MALLOC DATA\n");delay_ms(200);}LCD_Clear(WHITE);OV2640_JPEG_Mode();		//JPEG模式  OV2640_OutSize_Set(jpeg_img_size_tbl[size][0],jpeg_img_size_tbl[size][1]);//设置输出尺寸 while(1){key=KEY_Scan(0);if(key==KEY0_PRES){effect++;effect%=7;OV2640_Special_Effects(effect);}if(key==WKUP_PRES){expose++;expose%=5;					OV2640_Auto_Exposure(expose);}while(OV2640_VSYNC==0);//等待帧信号while(OV2640_VSYNC==1){while(OV2640_HREF){ while(OV2640_PCLK==0);jpeg_buf[jpeg_data_len++]=OV2640_DATA; if(jpeg_data_len>jpeg_buf_size){JPEG_DMA_SendArray();jpeg_data_len=0;	}while(OV2640_PCLK==1);}}} 
}#endif#ifdef RGB_TESTu8* ov2640_framebuf;	
void rgb565_test(void)
{u8 key;u8 effect=0,expose=0;int i=0,j=0;u16 pixcnt=0;				//像素统计u32 pix=0;u16 linepix=0;u16 linecnt=0;				//行数统计	mem_init();	ov2640_framebuf=mymalloc(128*128*2);//32K左右while(!ov2640_framebuf)	{printf("MALLOC DATA\n");delay_ms(200);}OV2640_RGB565_Mode();OV2640_OutSize_Set(128,128); while(1){key=KEY_Scan(0);if(key==KEY0_PRES){effect++;effect%=7;OV2640_Special_Effects(effect);}if(key==WKUP_PRES){expose++;expose%=5;					OV2640_Auto_Exposure(expose);}pix=0;while(OV2640_VSYNC)			//等待帧信号{	}pixcnt=0;								//像素计数器清零linecnt=0;					//行统计清零while(linecnt<128)	{while(OV2640_HREF){                                                                                                                         while(OV2640_PCLK==0);ov2640_framebuf[256*linecnt+linepix]=OV2640_DATA; pix++;linepix++;while(OV2640_PCLK==1); while(OV2640_PCLK==0); ov2640_framebuf[256*linecnt+linepix]=OV2640_DATA; pix++;linepix++;while(OV2640_PCLK==1);}  if(pix!=pixcnt){pixcnt=pix;linepix=0;linecnt++;}}	for(i=0;i<128;i++)for(j=0;j<128;j++){LCD_DrawPoint_Color(j,i,(u16)(ov2640_framebuf[2*128*i+1+2*j]<<8|ov2640_framebuf[2*128*i+2*j]));		}}
}
#endifint main(void){delay_init();	    	 //延时函数初始化	  uart1_init(115200); LCD_Init();KEY_Init();while(OV2640_Init())			//初始化OV2640{printf("Camera ERROR\n");delay_ms(200);}ov2640_speed_ctrl();
#ifdef RGB_TESTrgb565_test();
#elsejpeg_test();
#endif
}

SCCB.c


#include "sys.h"
#include "SCCB.h"
#include "delay.h"//初始化SCCB接口
//CHECK OK
void SCCB_Init(void)
{						GPIO_InitTypeDef  GPIO_InitStructure;RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC, ENABLE);	 //使能PCGPIO_InitStructure.GPIO_Pin = GPIO_Pin_0;				 	 	// 端口配置GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU; 		 	//输入GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;GPIO_Init(GPIOC, &GPIO_InitStructure);GPIO_SetBits(GPIOC,GPIO_Pin_0);						 					// 输出高GPIO_InitStructure.GPIO_Pin = GPIO_Pin_1;				 			// 端口配置GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; 		  //输输出GPIO_Init(GPIOC, &GPIO_InitStructure);GPIO_SetBits(GPIOC,GPIO_Pin_1);						 						// 输出高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发送失败,返回1else res=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();	  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;
}

Camera.c

#include "sys.h"
#include "Camera.h"
#include "Camera_Config.h" 
#include "delay.h"
#include "usart.h"			 
#include "sccb.h"	
//OV2640速度控制
//根据LCD分辨率的不同,设置不同的参数
void ov2640_speed_ctrl(void)
{u8 clkdiv,pclkdiv;			//时钟分频系数和PCLK分频系数clkdiv=15;pclkdiv=4;SCCB_WR_Reg(0XFF,0X00);		SCCB_WR_Reg(0XD3,pclkdiv);	//设置PCLK分频SCCB_WR_Reg(0XFF,0X01);SCCB_WR_Reg(0X11,clkdiv);	  //设置CLK分频	
}
void JTAG_Set(u8 mode)
{u32 temp;temp=mode;temp<<=25;RCC->APB2ENR|=1<<0;     //开启辅助时钟	   AFIO->MAPR&=0XF8FFFFFF; //清除MAPR的[26:24]AFIO->MAPR|=temp;       //设置jtag模式
} 
#define SWD_ENABLE         0X01
//初始化OV2640 
//配置完以后,默认输出是1600*1200尺寸的图片!! 
//返回值:0,成功
//    其他,错误代码
u8 OV2640_Init(void)
{ u16 i=0;u16 reg;GPIO_InitTypeDef  GPIO_InitStructure;//设置IO RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA|RCC_APB2Periph_GPIOB|RCC_APB2Periph_GPIOC|RCC_APB2Periph_AFIO, ENABLE);	 //使能相关端口时钟//PCLKGPIO_InitStructure.GPIO_Pin  = GPIO_Pin_10; 	//PC15 输入 上拉GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;GPIO_Init(GPIOB, &GPIO_InitStructure);GPIO_SetBits(GPIOB,GPIO_Pin_10);//OV2640_PWDNGPIO_InitStructure.GPIO_Pin  = GPIO_Pin_3; 	//PC3 输出GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;GPIO_Init(GPIOC, &GPIO_InitStructure);GPIO_SetBits(GPIOC,GPIO_Pin_3);//DATAGPIO_InitStructure.GPIO_Pin  = 0xff; 				//PA0~7 输入 上拉GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;GPIO_Init(GPIOA, &GPIO_InitStructure);//OV2640_VSYNCGPIO_InitStructure.GPIO_Pin  = GPIO_Pin_13;  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;//PC13输入GPIO_Init(GPIOC, &GPIO_InitStructure);GPIO_SetBits(GPIOC,GPIO_Pin_13);//OV2640_RSTGPIO_InitStructure.GPIO_Pin  = GPIO_Pin_2; //PC2输出 GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;GPIO_Init(GPIOC, &GPIO_InitStructure);GPIO_SetBits(GPIOC,GPIO_Pin_2);//OV2640_HREFGPIO_InitStructure.GPIO_Pin  = GPIO_Pin_11; //PB1输入 GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;GPIO_Init(GPIOB, &GPIO_InitStructure);GPIO_SetBits(GPIOB,GPIO_Pin_11);   GPIO_PinRemapConfig(GPIO_Remap_SWJ_JTAGDisable,ENABLE);	OV2640_PWDN=0;				//POWER ONdelay_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);	//软复位OV2640delay_ms(50); reg=SCCB_RD_Reg(OV2640_SENSOR_MIDH);	//读取厂家ID 高八位reg<<=8;reg|=SCCB_RD_Reg(OV2640_SENSOR_MIDL);	//读取厂家ID 低八位printf("MID:%x\r\n",reg);if(reg!=OV2640_MID){printf("MID:%x\r\n",reg);return 1;}reg=SCCB_RD_Reg(OV2640_SENSOR_PIDH);	//读取厂家ID 高八位reg<<=8;reg|=SCCB_RD_Reg(OV2640_SENSOR_PIDL);	//读取厂家ID 低八位printf("HID:%x\r\n",reg);if(reg!=OV2640_PID){printf("HID:%x\r\n",reg);//return 2;}   //初始化 OV2640,采用SXGA分辨率(1600*1200)  for(i=0;i<sizeof(ov2640_svga_init_reg_tbl)/2;i++){SCCB_WR_Reg(ov2640_svga_init_reg_tbl[i][0],ov2640_svga_init_reg_tbl[i][1]);} return 0x00; 	//ok
} 
//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,0X00);//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;
}

设计到的东西有点多,其他文件我就发在这了
OV2640驱动


http://chatgpt.dhexx.cn/article/A4rCHOiy.shtml

相关文章

第45章 DCMI—OV2640摄像头—零死角玩转STM32-F429系列

第45章 DCMI—OV2640摄像头 全套200集视频教程和1000页PDF教程请到秉火论坛下载:www.firebbs.cn 野火视频教程优酷观看网址:http://i.youku.com/firege 本章参考资料:《STM32F4xx参考手册》、《STM32F4xx规格书》、库帮助文档《stm32f4xx_dsp_stdperiph_lib_um.…

stm32cubeMx---DCMI 配置与使用

最近需要使用stm32的DCMI外设&#xff0c;所以经过一段时间研究后&#xff0c;对现有的学习状态进行记录&#xff1a; 1&#xff1a;stm32cube的pinout处进行无脑配置就行了&#xff0c;不进行描述。时钟配置按照自己的需求进行配置。DCMI的DMA配置如下图&#xff1a; 2&#…

通过stm32cubemx配置DCMI驱动ov5640摄像头

打开stm32cubemx选择芯片 选择外部时钟源 选择debug方式 配置dcmi 打开dma 打开dcmi中断 选择合适的io 设置reset、pwdn、scl、sda引脚&#xff0c;注意scl和sda设置为开漏输出&#xff0c;之前参考别人的设置为推挽输出&#xff0c;导致一直没有成功&#xff0c;不知道什么原…

DCMI接口与OV2640原理与配置

OV2640是OmniVision公司生产的一颗1/4寸的CMOS UXGA&#xff08;1632*1232&#xff09;图像传感器。该传感器体积小、工作电压低&#xff0c;提供单片UXGA摄像头和影像处理器的所有功能。通过SCCB 总线控制&#xff0c;可以输出整帧、子采样、缩放和取窗口等方式的各种分辨率8/…

STM32H743中的DCMI无法进入行中断和场中断问题

今天在玩MT9V034摄像头时&#xff0c;用到了DCMI接口处理摄像头的数据&#xff0c;出现了一个BUG&#xff0c;怎么都进入不了行中断或者场中断。究其原因&#xff0c;原来是忘记设置其中断优先级了。 void Msp_DCMI_Init(void) {GPIO_InitTypeDef GPIO_InitStruct;__HAL_RCC_DC…

STM32 DCMI OV9655 直接在LCD显示

CUBEMX配置DCMI如下&#xff1a; 生成代码。DCMI初始化代码如下&#xff1a; void HAL_DCMI_MspInit(DCMI_HandleTypeDef* hdcmi) {GPIO_InitTypeDef GPIO_InitStruct {0};if(hdcmi->InstanceDCMI){/* USER CODE BEGIN DCMI_MspInit 0 *//* USER CODE END DCMI_MspInit …

基于STM32F429的DCMI实现OV7725-NF无缓存摄像头的图像采集HAL库

基于STM32F429的OV7725-NF无缓存摄像头的DCMI图像采集 和LTDC显示 0. 首先说明一下时钟配置1. DCMI配置1.1 首先点击DCMI进入配置页面后&#xff0c;要选择Mode1.2 然后要进行GPIO settings1.3 然后是Parameter settings参数设置1.4 DMA settings1.5 需要使用的HAL库函数 3. OV…

stm32-DCMI—OV2640摄像头

第45章 DCMI—OV2640摄像头 全套200集视频教程和1000页PDF教程请到秉火论坛下载&#xff1a;www.firebbs.cn 野火视频教程优酷观看网址&#xff1a;http://i.youku.com/firege 本章参考资料&#xff1a;《STM32F4xx参考手册》、《STM32F4xx规格书》、库帮助文档《stm32f…

stm32f407的高速并口12位ad——dcmi方式

stm32f407的高速并口12位ad——dcmi方式 关于dcmi 我们可以利用这个摄像头接口&#xff0c;进行一个54M以下的并口ad的数据处理。 这个是dcmi的时序图&#xff0c;时钟使用mco1输出系统时钟四分频也就是42m&#xff0c;我的是ad9926&#xff0c;上升沿触发&#xff0c;那么ad…

STM32H7B0 HAL库中关于DMA的注意事项以及DCMI调试遇到的问题及解决方法

先总结总结问题 问题1&#xff1a;MX_DCMI_Init();放到 MX_DMA_Init();后 问题2&#xff1a;DMA缓存缓存要放到SRAM中__align(32) uint32_t buffer[65535] __attribute((at(0X24040000))); 问题3&#xff1a;IO复用问题&#xff0c;DCMI数据口可以复用到其他IO口&#xff0…

STM32——DCMI接口与OV2640原理与配置

一、OV2640简介 1、什么是OV2640&#xff1f; OV2640是OmniVision公司生产的一颗1/4寸的CMOS UXGA&#xff08;1632*1232&#xff09;图像传感器。该传感器体积小、工作电压低&#xff0c;提供单片UXGA摄像头和影像处理器的所有功能。通过SCCB总线控制&#xff0c;可以输出整…

DCMI接口之OV2640摄像头

一、OV2640简介 OV2640是OmniVision公司生产的一颗1/4寸的CMOS UXGA&#xff08;1632 * 1232&#xff09;图像传感器。该传感器体积小、工作电压低&#xff0c;提供单片UXGA摄像头和影像处理器的所有功能。通过SCCB 总线控制&#xff0c;可以输出整帧、子采样、缩放和取窗口等…

OV2640 DCMI

OV2640 简介&#xff1a; 1/4寸CMOSUXGA (1632 * 1232)图像传感器。体积小、工作电压低,提供单片UXGA摄像头和影像处理器的所有功能。通过SCCB总线控制&#xff0c;可以输出整帧、子采样、缩放和取窗口等方式的各种分辨率8/10位影像数据。&#xff08;此处一般选8位&#xff0…

STM32F429之DCMI 数字相机接口

嵌入式系列文章 参考&#xff1a;《STM32F429_DM00031020_ENV19.pdf》 本文目的&#xff1a;翻译STM32F429的PRM&#xff0c;深入理解DCMI接口的工作原理&#xff0c;最后将DCMI工作原理转换成驱动代码。 DCMI&#xff1a;Digital camera interface&#xff0c;数字摄像头接口 …

DCMI接口

目录 DCMI数字摄像头接口 DCMI引脚 摄像头引脚 操作过程与通信方式 硬件连接图 写操作 读操作 图像输出 数据格式 rawRGB YUV RGB JPEG 代码实现过程简述 学习过程的问题 YUV是亮度和色度的格式&#xff0c;为什么UV中取Cb蓝和Cr红作为色度&#xff1f; 提问MIPI、DVP、DCMI是什…

stm32f4的数字摄像头接口(DCMI)使用

DCMI简介 STM32F4的DCMI接口包括如下信号 1&#xff0c;数据据输入&#xff08;D[0:13]&#xff09;&#xff0c;接摄像头的数据输出。 2&#xff0c;水平同步&#xff08;行同步&#xff09;输入&#xff08;HSYNC&#xff09;&#xff0c;接摄像头的HSYNC/HREF信号&#xff…

Java开发技术

1、基础技术 数据结构与算法 逻辑结构&#xff1a;数据对象中的数据元素之间的逻辑关系 1.集合结构&#xff1a;集合结构中的数据元素除了同属一个集合外&#xff0c;没有其他关系。 2.线性结构&#xff1a;线性结构中的数据元素之间是一对一的关系。 3.树形结构&#xff1a;树…

JAVA 中的代码生成包 CGLIB (Code Generation Library)

JAVA 中的代码生成包 CGLIB &#xff08;Code Generation Library&#xff09; CGLIB 是一个功能强大&#xff0c;高性能的代码生成包。它为没有实现接口的类提供代理&#xff0c;为 JDK 的动态代理提供了很好的补充。通常可以使用Java的动态代理创建代理&#xff0c;但当要代…

Java开发实战讲解!java开发CPU最低要求

前言 本人是底层 211 本科,刚毕业,⽆科研经历,但是有些项⽬经历。 在国内监控行业某头部企业做过一段时间的实习。 想着投下字节,可以积累⼀下⾯试经验和为金九银十面招做准备。投了简历之后,过了一段时 间,HR 就打电话跟我约时间, 说明一下&#xff0c;我投的是北京 office。…

Java面试题技术类一

前端技术导航大全 1、面向对象编程的三大特性是什么? 2、String 和StringBuffer的区别 3、说出ArrayList,Vector, LinkedList的存储性能和特性 4、Collection 和 Collections的区别 5、HashMap和Hashtable的区别 6、final, finally, finalize的区别 7、Overload和Overri…