w806开发板驱动ov2640读取jpeg图片1600x1200分辨率,以及花屏原因及解决办法

news/2024/12/2 16:33:53/

主频需要160MHz以上,80MHz主频读取会丢数据,读取过程中要关闭所有中断否则会出现丢数据花屏现象,还有一个重要的地方需要注意,PCLK速度过慢同时照片信息量多时,jpeg文件过大也会花一部分,像如这样

这样

出现部分花屏原因是因为ov2640发现以当前PCLK的速度已经无法在一帧照片的时间内将jpeg文件发送完,索性直接就停止发送了,在单片机允许的速度下适当的调整PCLK的速度可以发送更大的jpeg图片,调整的方法就是设置0xD3寄存器

SCCB_WR_Reg(0XD3,0X14);//0X30:48MHz/48 = 1MHz;0X18:48MHz/24 = 2MHz;0X14:48MHz/20 = 2.4MHz;0X0F:48MHz/16 = 3MHz;0X0C:48MHz/12 = 4MHz 

手册

废话不多说上样张102 KB (104,520 字节)

下位机程序

main.c


#include <stdio.h>
#include "wm_hal.h"
#include "ov2640.h"
#include "general.h"void Error_Handler(void);
static void GPIO_Init(void);static void GPIO_Init(void)
{GPIO_InitTypeDef GPIO_InitStruct = {0};__HAL_RCC_GPIO_CLK_ENABLE();GPIO_InitStruct.Pin = GPIO_PIN_0 | GPIO_PIN_1 | GPIO_PIN_2;GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT;GPIO_InitStruct.Pull = GPIO_NOPULL;HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);HAL_GPIO_WritePin(GPIOB, GPIO_PIN_0 | GPIO_PIN_1 | GPIO_PIN_2, GPIO_PIN_RESET);GPIO_InitStruct.Pin =  GPIO_PIN_8| GPIO_PIN_12| GPIO_PIN_14;GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT;GPIO_InitStruct.Pull = GPIO_NOPULL;HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);HAL_GPIO_WritePin(GPIOA, GPIO_PIN_8| GPIO_PIN_12| GPIO_PIN_14, GPIO_PIN_RESET);
//	//设置摄像头数据接口GPIO_InitStruct.Pin =  GPIO_PIN_9| GPIO_PIN_11| GPIO_PIN_13| GPIO_PIN_15;GPIO_InitStruct.Mode = GPIO_MODE_INPUT;GPIO_InitStruct.Pull = GPIO_NOPULL;HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);//设置摄像头数据接口GPIO_InitStruct.Pin = GPIO_PIN_0 | GPIO_PIN_1 | GPIO_PIN_2| GPIO_PIN_3 | GPIO_PIN_4 | GPIO_PIN_5| GPIO_PIN_6 | GPIO_PIN_7 ;GPIO_InitStruct.Mode = GPIO_MODE_INPUT;GPIO_InitStruct.Pull = GPIO_NOPULL;HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);HAL_NVIC_SetPriority(GPIOB_IRQn, 0);HAL_NVIC_EnableIRQ(GPIOB_IRQn);}int main(void)
{SystemClock_Config(CPU_CLK_160M);printf("enter main\r\n");HAL_Init();GPIO_Init();HAL_Delay(5000);printf("ov2640_init\r\n");ov2640_init();while (1){HAL_Delay(5000);}return 0;
}void Error_Handler(void)
{while (1){}
}void assert_failed(uint8_t *file, uint32_t line)
{printf("Wrong parameters value: file %s on line %d\r\n", file, line);
}

ov2640.c

#include "ov2640.h"
#include "ov2640cfg.h"
#include "wm_hal.h"
#include "general.h"#define OV2640_VSYNC 	HAL_GPIO_ReadPin(GPIOA, GPIO_PIN_9)	#define OV2640_PWDN_H  	HAL_GPIO_WritePin(GPIOA, GPIO_PIN_14, GPIO_PIN_SET)		//POWER DOWN控制信号
#define OV2640_PWDN_L  	HAL_GPIO_WritePin(GPIOA, GPIO_PIN_14, GPIO_PIN_RESET)	//POWER DOWN控制信号#define OV2640_RST_H  	HAL_GPIO_WritePin(GPIOA, GPIO_PIN_12, GPIO_PIN_SET)		//复位控制信号
#define OV2640_RST_L  	HAL_GPIO_WritePin(GPIOA, GPIO_PIN_12, GPIO_PIN_RESET)	//复位控制信号#define OV2640_HREF  	HAL_GPIO_ReadPin(GPIOA, GPIO_PIN_11)					//HREF信号
#define OV2640_PCLK  	HAL_GPIO_ReadPin(GPIOA, GPIO_PIN_13)					//PCLK信号//#define OV2640_SCL  	HAL_GPIO_ReadPin(GPIOA, GPIO_PIN_8)						//读SCL信号 
#define OV2640_SCL_H  	HAL_GPIO_WritePin(GPIOA, GPIO_PIN_8, GPIO_PIN_SET)		//写SCL高
#define OV2640_SCL_L  	HAL_GPIO_WritePin(GPIOA, GPIO_PIN_8, GPIO_PIN_RESET)	//写SCL低#define OV2640_SDA  	HAL_GPIO_ReadPin(GPIOA, GPIO_PIN_10)					//读SDA信号 
#define OV2640_SDA_H  	HAL_GPIO_WritePin(GPIOA, GPIO_PIN_10, GPIO_PIN_SET)		//写SDA信号
#define OV2640_SDA_L  	HAL_GPIO_WritePin(GPIOA, GPIO_PIN_10, GPIO_PIN_RESET)	//读SDA信号#define OV2640_JPEG_WIDTH	1600	//320//1600	//JPEG拍照的宽度	
#define OV2640_JPEG_HEIGHT	1200	//240//1200	//JPEG拍照的高度#define SCCB_ID   			0X60  			//OV2640的IDuint8_t buffer[200*1024];static void gpio_sda_output()
{GPIO_InitTypeDef GPIO_InitStruct = {0};GPIO_InitStruct.Pin = GPIO_PIN_10;GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT;GPIO_InitStruct.Pull = GPIO_PULLUP;HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
}static void gpio_sda_input()
{GPIO_InitTypeDef GPIO_InitStruct = {0};GPIO_InitStruct.Pin = GPIO_PIN_10;GPIO_InitStruct.Mode = GPIO_MODE_INPUT;GPIO_InitStruct.Pull = GPIO_PULLUP;HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
}unsigned char ov2640_read_data(GPIO_TypeDef *GPIOx)
{unsigned char data = GPIOx->DATA&0x00FF;//数据输入端口return data;
}//SCCB起始信号
//当时钟为高的时候,数据线的高到低,为SCCB起始信号
//在激活状态下,SDA和SCL均为低电平
void SCCB_Start(void)
{OV2640_SDA_H;     //数据线高电平	   OV2640_SCL_H;	    //在时钟线高的时候数据线由高至低delay_us(50);  OV2640_SDA_L;delay_us(50);	 OV2640_SCL_L;	    //数据线恢复低电平,单操作函数必要	  
}//SCCB停止信号
//当时钟为高的时候,数据线的低到高,为SCCB停止信号
//空闲状况下,SDA,SCL均为高电平
void SCCB_Stop(void)
{OV2640_SDA_L;delay_us(50);	 OV2640_SCL_H;delay_us(50); OV2640_SDA_H; delay_us(50);
}  //产生NA信号
void SCCB_No_Ack(void)
{delay_us(50);OV2640_SDA_H;OV2640_SCL_H;delay_us(50);OV2640_SCL_L;	delay_us(50);OV2640_SDA_L;delay_us(50);
}//SCCB,写入一个字节
//返回值:0,成功;1,失败. 
uint8_t SCCB_WR_Byte(uint8_t dat)
{uint8_t j,res;	 for(j=0;j<8;j++) //循环8次发送数据{if(dat&0x80){OV2640_SDA_H;}else{OV2640_SDA_L;}dat<<=1;delay_us(50);OV2640_SCL_H;delay_us(50);OV2640_SCL_L;	   }			 gpio_sda_input();		//设置SDA为输入 delay_us(50);OV2640_SCL_H;		//接收第九位,以判断是否发送成功delay_us(50);if(OV2640_SDA == GPIO_PIN_SET){res=1;  		//SDA=1发送失败,返回1//printf("SDA=1发送失败,返回1\r\n");}else {res=0;         //SDA=0发送成功,返回0//printf("SDA=0发送成功,返回0\r\n");}OV2640_SCL_L;	 	 gpio_sda_output();		//设置SDA为输出    return res;  
}	 //SCCB 读取一个字节
//在SCL的上升沿,数据锁存
//返回值:读到的数据
uint8_t SCCB_RD_Byte(void)
{uint8_t temp=0,j;    gpio_sda_input();		//设置SDA为输入  for(j=8;j>0;j--) 	//循环8次接收数据{		     	  delay_us(50);OV2640_SCL_H;temp=temp<<1;if(OV2640_SDA == GPIO_PIN_SET){temp++;   }delay_us(50);OV2640_SCL_L;	}	gpio_sda_output();		//设置SDA为输出    return temp;
} 	//写寄存器
//返回值:0,成功;1,失败.
uint8_t SCCB_WR_Reg(uint8_t reg,uint8_t data)
{uint8_t 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;
}//读寄存器
//返回值:读到的寄存器值
uint8_t SCCB_RD_Reg(uint8_t reg)
{uint8_t 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;
}uint8_t ov2640_start()
{uint16_t i;uint16_t reg;gpio_sda_output(); OV2640_RST_H;				//结束复位OV2640_PWDN_H;				//POWER OFFHAL_Delay(1000);OV2640_PWDN_L;				//POWER ONHAL_Delay(100);OV2640_RST_L;				//复位OV2640HAL_Delay(100);OV2640_RST_H;				//结束复位 SCCB_WR_Reg(OV2640_DSP_RA_DLMT, 0x01);	//操作sensor寄存器SCCB_WR_Reg(OV2640_SENSOR_COM7, 0x80);	//软复位OV2640HAL_Delay(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;}   //初始化 OV2640,采用SXGA分辨率(1600*1200)  for(i=0;i<sizeof(ov2640_uxga_init_reg_tbl)/2;i++){SCCB_WR_Reg(ov2640_uxga_init_reg_tbl[i][0],ov2640_uxga_init_reg_tbl[i][1]);} return 0x00; 	//ok
}//OV2640切换为JPEG模式
void OV2640_JPEG_Mode(void) 
{uint16_t 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) 
{uint16_t 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]); } 
} //设置图像输出大小
//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拍照jpg图片
//返回值:0,成功
//    其他,错误代码
uint16_t ov2640_jpg_photo()
{uint8_t res=0;uint32_t bwr;uint32_t i=0;uint32_t jpeglen=0;
//	uint8_t isJpeg = 0;OV2640_JPEG_Mode();							//切换为JPEG模式 OV2640_OutSize_Set(OV2640_JPEG_WIDTH,OV2640_JPEG_HEIGHT); SCCB_WR_Reg(0XFF,0X00);SCCB_WR_Reg(0XD3,30);SCCB_WR_Reg(0XFF,0X01);SCCB_WR_Reg(0X11,0X1); HAL_NVIC_DisableIRQ(SYS_TICK_IRQn);for(i=0;i<10;i++)		//丢弃20帧,等待OV2640自动调节好(曝光白平衡之类的){while(OV2640_VSYNC == GPIO_PIN_SET); while(OV2640_VSYNC == GPIO_PIN_RESET);	 }  while(OV2640_VSYNC == GPIO_PIN_SET)	//开始采集jpeg数据{while(OV2640_HREF){  while(OV2640_PCLK == GPIO_PIN_RESET);   buffer[jpeglen]=ov2640_read_data(GPIOA);while(OV2640_PCLK == GPIO_PIN_SET);  jpeglen++;} }	printf("jpeg data size:%d\r\n",jpeglen);	//串口打印JPEG文件大小	HAL_NVIC_EnableIRQ(SYS_TICK_IRQn);HAL_Delay(1000);for(i = 0;i < jpeglen;i++){printf("%c",buffer[i]);}return res;
}  void ov2640_init()
{while(ov2640_start())			//初始化OV2640{HAL_Delay(1000);}printf("ov2640_init_ok\r\n");while(1){ov2640_jpg_photo();HAL_Delay(2000);}
}

ov2640.h

#ifndef __OV2640_H__
#define __OV2640_H__// 
#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 0x62void ov2640_init();#endif

ov2640cfg.h

#ifndef __OV2640_CFG_H__
#define __OV2640_CFG_H__
//OV2640 UXGA初始化寄存器序列表
//此模式下帧率为15帧
//UXGA(1600*1200) 
const unsigned char ov2640_uxga_init_reg_tbl[][2]= 
{   0xff, 0x00,0x2c, 0xff,0x2e, 0xdf,0xff, 0x01,0x3c, 0x32,//0x11, 0x01,0x09, 0x02,0x04, 0xD8,//水平镜像,垂直翻转0x13, 0xe5,0x14, 0x48,0x2c, 0x0c,0x33, 0x78,0x3a, 0x33,0x3b, 0xfB,//0x3e, 0x00,0x43, 0x11,0x16, 0x10,//0x39, 0x92,//0x35, 0xda,0x22, 0x1a,0x37, 0xc3,0x23, 0x00,0x34, 0xc0,0x36, 0x1a,0x06, 0x88,0x07, 0xc0,0x0d, 0x87,0x0e, 0x41,0x4c, 0x00,0x48, 0x00,0x5B, 0x00,0x42, 0x03,//0x4a, 0x81,0x21, 0x99,//0x24, 0x40,0x25, 0x38,0x26, 0x82,0x5c, 0x00,0x63, 0x00,0x46, 0x00,0x0c, 0x3c,//0x61, 0x70,0x62, 0x80,0x7c, 0x05,//0x20, 0x80,0x28, 0x30,0x6c, 0x00,0x6d, 0x80,0x6e, 0x00,0x70, 0x02,0x71, 0x94,0x73, 0xc1, 0x3d, 0x34, 0x5a, 0x57,//0x12, 0x00,//UXGA 1600*12000x17, 0x11,0x18, 0x75,0x19, 0x01,0x1a, 0x97,0x32, 0x36,0x03, 0x0f, 0x37, 0x40,// 0x4f, 0xca,0x50, 0xa8,0x5a, 0x23,0x6d, 0x00,0x6d, 0x38,//0xff, 0x00,0xe5, 0x7f,0xf9, 0xc0,0x41, 0x24,0xe0, 0x14,0x76, 0xff,0x33, 0xa0,0x42, 0x20,0x43, 0x18,0x4c, 0x00,0x87, 0xd5,0x88, 0x3f,0xd7, 0x03,0xd9, 0x10,0xd3, 0x82,//0xc8, 0x08,0xc9, 0x80,//0x7c, 0x00,0x7d, 0x00,0x7c, 0x03,0x7d, 0x48,0x7d, 0x48,0x7c, 0x08,0x7d, 0x20,0x7d, 0x10,0x7d, 0x0e,//0x90, 0x00,0x91, 0x0e,0x91, 0x1a,0x91, 0x31,0x91, 0x5a,0x91, 0x69,0x91, 0x75,0x91, 0x7e,0x91, 0x88,0x91, 0x8f,0x91, 0x96,0x91, 0xa3,0x91, 0xaf,0x91, 0xc4,0x91, 0xd7,0x91, 0xe8,0x91, 0x20,//0x92, 0x00,0x93, 0x06,0x93, 0xe3,0x93, 0x05,0x93, 0x05,0x93, 0x00,0x93, 0x04,0x93, 0x00,0x93, 0x00,0x93, 0x00,0x93, 0x00,0x93, 0x00,0x93, 0x00,0x93, 0x00,//0x96, 0x00,0x97, 0x08,0x97, 0x19,0x97, 0x02,0x97, 0x0c,0x97, 0x24,0x97, 0x30,0x97, 0x28,0x97, 0x26,0x97, 0x02,0x97, 0x98,0x97, 0x80,0x97, 0x00,0x97, 0x00,//0xc3, 0xef,0xa4, 0x00,0xa8, 0x00,0xc5, 0x11,0xc6, 0x51,0xbf, 0x80,0xc7, 0x10,0xb6, 0x66,0xb8, 0xA5,0xb7, 0x64,0xb9, 0x7C,0xb3, 0xaf,0xb4, 0x97,0xb5, 0xFF,0xb0, 0xC5,0xb1, 0x94,0xb2, 0x0f,0xc4, 0x5c,//0xc0, 0xc8,0xc1, 0x96,0x8c, 0x00,0x86, 0x3d,0x50, 0x00,0x51, 0x90,0x52, 0x2c,0x53, 0x00,0x54, 0x00,0x55, 0x88,0x5a, 0x90,0x5b, 0x2C,0x5c, 0x05,0xd3, 0x82,//auto设置要小心//0xc3, 0xed,0x7f, 0x00,0xda, 0x09,0xe5, 0x1f,0xe1, 0x67,0xe0, 0x00,0xdd, 0x7f,0x05, 0x00,
};  
//OV2640 SVGA初始化寄存器序列表
//此模式下,帧率可以达到30帧
//SVGA 800*600
const unsigned char ov2640_svga_init_reg_tbl[][2]= 
{    0xff, 0x00,0x2c, 0xff,0x2e, 0xdf,0xff, 0x01,0x3c, 0x32,//0x11, 0x01,0x09, 0x02,0x04, 0xD8,//水平镜像,垂直翻转0x13, 0xe5,0x14, 0x48,0x2c, 0x0c,0x33, 0x78,0x3a, 0x33,0x3b, 0xfB,//0x3e, 0x00,0x43, 0x11,0x16, 0x10,//0x39, 0x92,//0x35, 0xda,0x22, 0x1a,0x37, 0xc3,0x23, 0x00,0x34, 0xc0,0x36, 0x1a,0x06, 0x88,0x07, 0xc0,0x0d, 0x87,0x0e, 0x41,0x4c, 0x00,0x48, 0x00,0x5B, 0x00,0x42, 0x03,//0x4a, 0x81,0x21, 0x99,//0x24, 0x40,0x25, 0x38,0x26, 0x82,0x5c, 0x00,0x63, 0x00,0x46, 0x22,0x0c, 0x3c,//0x61, 0x70,0x62, 0x80,0x7c, 0x05,//0x20, 0x80,0x28, 0x30,0x6c, 0x00,0x6d, 0x80,0x6e, 0x00,0x70, 0x02,0x71, 0x94,0x73, 0xc1,0x3d, 0x34, 0x5a, 0x57,//根据分辨率不同而设置0x12, 0x40,//SVGA 800*6000x17, 0x11,0x18, 0x43,0x19, 0x00,0x1a, 0x4b,0x32, 0x09,0x37, 0xc0,//0x4f, 0xca,0x50, 0xa8,0x5a, 0x23,0x6d, 0x00,0x3d, 0x38,//0xff, 0x00,0xe5, 0x7f,0xf9, 0xc0,0x41, 0x24,0xe0, 0x14,0x76, 0xff,0x33, 0xa0,0x42, 0x20,0x43, 0x18,0x4c, 0x00,0x87, 0xd5,0x88, 0x3f,0xd7, 0x03,0xd9, 0x10,0xd3, 0x82,//0xc8, 0x08,0xc9, 0x80,//0x7c, 0x00,0x7d, 0x00,0x7c, 0x03,0x7d, 0x48,0x7d, 0x48,0x7c, 0x08,0x7d, 0x20,0x7d, 0x10,0x7d, 0x0e,//0x90, 0x00,0x91, 0x0e,0x91, 0x1a,0x91, 0x31,0x91, 0x5a,0x91, 0x69,0x91, 0x75,0x91, 0x7e,0x91, 0x88,0x91, 0x8f,0x91, 0x96,0x91, 0xa3,0x91, 0xaf,0x91, 0xc4,0x91, 0xd7,0x91, 0xe8,0x91, 0x20,//0x92, 0x00,0x93, 0x06,0x93, 0xe3,0x93, 0x05,0x93, 0x05,0x93, 0x00,0x93, 0x04,0x93, 0x00,0x93, 0x00,0x93, 0x00,0x93, 0x00,0x93, 0x00,0x93, 0x00,0x93, 0x00,//0x96, 0x00,0x97, 0x08,0x97, 0x19,0x97, 0x02,0x97, 0x0c,0x97, 0x24,0x97, 0x30,0x97, 0x28,0x97, 0x26,0x97, 0x02,0x97, 0x98,0x97, 0x80,0x97, 0x00,0x97, 0x00,//0xc3, 0xed,0xa4, 0x00,0xa8, 0x00,0xc5, 0x11,0xc6, 0x51,0xbf, 0x80,0xc7, 0x10,0xb6, 0x66,0xb8, 0xA5,0xb7, 0x64,0xb9, 0x7C,0xb3, 0xaf,0xb4, 0x97,0xb5, 0xFF,0xb0, 0xC5,0xb1, 0x94,0xb2, 0x0f,0xc4, 0x5c,//根据分辨率不同而设置0xc0, 0x64,0xc1, 0x4B,0x8c, 0x00,0x86, 0x3D,0x50, 0x00,0x51, 0xC8,0x52, 0x96,0x53, 0x00,0x54, 0x00,0x55, 0x00,0x5a, 0xC8,0x5b, 0x96,0x5c, 0x00,0xd3, 0x82,//auto设置要小心//0xc3, 0xed,0x7f, 0x00,0xda, 0x09,0xe5, 0x1f,0xe1, 0x67,0xe0, 0x00,0xdd, 0x7f,0x05, 0x00,
};   
const unsigned char ov2640_yuv422_reg_tbl[][2]= 
{0xFF, 0x00, 0xDA, 0x10,0xD7, 0x03,0xDF, 0x00,0x33, 0x80,0x3C, 0x40,0xe1, 0x77,0x00, 0x00,
};
const unsigned char ov2640_jpeg_reg_tbl[][2]=
{0xff, 0x01, 0xe0, 0x14,0xe1, 0x77,0xe5, 0x1f,0xd7, 0x03,0xda, 0x10,0xe0, 0x00, 
};
const unsigned char ov2640_rgb565_reg_tbl[][2]=
{0xFF, 0x00,0xDA, 0x09,0xD7, 0x03,0xDF, 0x02,0x33, 0xa0,0x3C, 0x00,0xe1, 0x67,0xff, 0x01, 0xe0, 0x00,0xe1, 0x00,0xe5, 0x00,0xd7, 0x00, 0xda, 0x00,0xe0, 0x00,  
}; 
#endif

上位机程序.net开发,协议很简单,先发一行特定字符,包含图片大小,然后直接发送图片数据

程序 

private byte[] buffer = new byte[200 * 1024];
private int offset = 0;
private int length = 0;
private bool isData = false;
public void DataCallBack(Object sender, SerialDataReceivedEventArgs e)
{try{if (isData==false){var data = _serialPort.ReadLine();if (!string.IsNullOrEmpty(data) && data.Length > 4){if(data.IndexOf("jpeg data size:")>=0){var lengthStr = data.Split(':');if(lengthStr != null && lengthStr.Length>1){length = int.Parse(lengthStr[1]);isData = true;}Console.WriteLine(data);}}}else{int thisLength = _serialPort.Read(buffer, offset, length - offset);offset = offset + thisLength;if(offset >= length){Console.WriteLine($"接收完一张图片,offset:{offset},length:{length}");string path = Directory.GetCurrentDirectory();DirectoryCheak(path + "\\out\\");bool ispictrue = false;List<byte> data = new List<byte>();for(int i = 1;i< length;i++){//Console.WriteLine($"i:{i},length:{length}");if (ispictrue == true){data.Add(buffer[i]);}if((buffer[i - 1] == 0xFF)&& (buffer[i] == 0xd8)){ispictrue = true;data.Add(buffer[i - 1]);data.Add(buffer[i]);}if((buffer[i - 1] == 0xFF) && (buffer[i] == 0xd9)){data.Add(buffer[i - 1]);data.Add(buffer[i]);ispictrue = false;break;}}WriteFileUsingBinaryWriter(path + "\\out\\",DateTime.Now.ToString("yyyyMMdd-HHmmss.fff") + ".jpg", data.ToArray(), data.Count());offset = 0;length = 0;isData = false;}}}catch (Exception ex){Console.WriteLine("串口解析出错" + ex.ToString());}
}public void WriteFileUsingBinaryWriter(string path,string fileName,byte[] data,int length)
{var outputStream = File.Create(path + fileName);using (var writer = new BinaryWriter(outputStream)){writer.Write(data, 0, length);}
}/// <summary>
/// 效验文件夹,没有就创建
/// </summary>
private void DirectoryCheak(string path)
{if (false == System.IO.Directory.Exists(path)){System.IO.Directory.CreateDirectory(path);}
}private void OpenSerialPort_Click(object sender, RoutedEventArgs e)
{_serialPort = new SerialPort();_serialPort.PortName = SerialPort.Text;_serialPort.BaudRate = 115200;_serialPort.Parity = Parity.None;_serialPort.DataBits = 8;_serialPort.StopBits = StopBits.One;_serialPort.ReadTimeout = 10000;//单位毫秒_serialPort.WriteTimeout = 10000;//单位毫秒//设置串口字节接收缓冲值,通常为1//获得接收后,触发事件处理_serialPort.ReceivedBytesThreshold = 1;_serialPort.DataReceived += new SerialDataReceivedEventHandler(DataCallBack);try{_serialPort.Open();//Console.WriteLine(serialPort.IsOpen.ToString());OpenSerialPort.IsEnabled = false;CloseSerialPort.IsEnabled = true;}catch (Exception ex){MessageBox.Show("串口打开失败" + ex.ToString());System.Environment.Exit(0);//退出应用程序}
}private void CloseSerialPort_Click(object sender, RoutedEventArgs e)
{try{if (_serialPort.IsOpen == true){_serialPort.Close();OpenSerialPort.IsEnabled = true;CloseSerialPort.IsEnabled = false;}}catch (Exception ex){MessageBox.Show("串口关闭失败" + ex.ToString());System.Environment.Exit(0);//退出应用程序}
}


http://www.ppmy.cn/news/272686.html

相关文章

MTK平台设置不同的预览Size

这边文章记录的是1280x8001.6屏幕分辨率预览窗口大小&#xff0c;sensor预览实际出图为4656x3496。 &#xff08;1&#xff09;App设置不同的预览Size的Log分析 &#xff08;A&#xff09;预览Size960x7201.333&#xff08;Surface窗口设置为4:3&#xff09;——Hal层会进行r…

meg和bank_显卡和Pentium过热传奇终止...并且对ATI Radeon 256Meg 9800 Pro超频

meg和bank The Video Card 显卡 Well, Ive been an NVidia fan for years, and I really thought Id go for the new NVidia 6800 Ultra. Theyve got fantastically stable drivers, dual monitor support, and dual DVI support. However, its US$600 and Ive got a wife - …

多媒体/Display认知记录总结

OMX TUNNEL的一种工作模型: 1.对于每个解码器,都有一个码流使它无法工作,视频编码都是YUV420像素格式,硬件输出也只支持这几种格式。 2. 码流相当于光盘,video codec相当于播放器,从数学的角度讲,它们是同构的的装置,这是一种新的解读。 3.编码与隐含的意义,有一种…

modetest工具测试(linux-5.10)

(102条消息) modetest编译、原理分析_空腹吃饭的博客-CSDN博客 (102条消息) tools:drm-kms调试手段[modetest]_drm_debug_kms_maze.ma的博客-CSDN博客 本内容通过modetest的打印&#xff0c;了解drm中各个object之间的关联&#xff0c;即如何正确的设置crtc&#xff0c;conne…

详解-自定义树莓派的显示分辨率

背景&#xff1a;树莓派一般可以自动检测目标设备的分辨率。但对于部分设备&#xff0c;尤其是HDMI-VGA转换器&#xff0c;分辨率可能会明显不对&#xff08;过大或过小&#xff09;。这时就需要给树莓派指定一个分辨率。 方法1&#xff1a;设置方法是在终端输入&#xff1a;s…

Mtk平台Camera新增差值(二)

之前介绍了一篇Mtk平台如何在Metadata当中来配置差值Mtk平台Camera新增差值&#xff08;1&#xff09;&#xff0c;实际功能是可以实现的&#xff0c;但是却无法通过CTS测试的&#xff0c;因为CTS测试会抓取sensor drv的最大输出能力和metadata的最大值来进行比较。 下面将介绍…

CVBS、VGA、HDMI、MIPI等8种视频接口详解

硬件接口&#xff08;hardware interface&#xff09;指的是两个硬件设备之间的连接方式。硬件接口既包括物理上的接口&#xff0c;还包括逻辑上的数据传送协议。 CVBSCVBS英文全称为Composite Video Broadcast Signal 或 Composite Video Blanking and Sync。中文翻译为复合视…

TC358775XBG是一颗将MIPI DSI信号转换成single/ dual -link LVDS的芯片,最高分辨率支持到1920x1200

产品特征&#xff1a; MIPI接口&#xff1a; &#xff08;1&#xff09;、支持1/2/3/4 lane(s) data&#xff0c;Maximum bit rate of 1 Gbps/lane &#xff08;2&#xff09;、支持video mode&#xff08;Non-burst Mode with Sync Pulses、Non-Burst Mode with Sync Events&a…