抑郁症健康,内容丰富有趣,生活中的好帮手!
抑郁症健康 > w806开发板驱动ov2640读取jpeg图片1600x1200分辨率 以及花屏原因及解决办法

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

时间:2021-01-09 10:01:10

相关推荐

主频需要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_WIDTH1600//320//1600//JPEG拍照的宽度#define OV2640_JPEG_HEIGHT1200//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(); returnres;}//读寄存器//返回值:读到的寄存器值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_MID0X7FA2#define OV2640_PID0X2642//当选择DSP地址(0XFF=0X00)时,OV2640的DSP寄存器地址映射表#define OV2640_DSP_R_BYPASS0x05#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_SP0xD3#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_CTRL0xF8#define OV2640_DSP_MC_BIST0xF9#define OV2640_DSP_MC_AL 0xFA#define OV2640_DSP_MC_AH 0xFB#define OV2640_DSP_MC_D 0xFC#define OV2640_DSP_P_STATUS0xFE#define OV2640_DSP_RA_DLMT0xFF //当选择传感器地址(0XFF=0X01)时,OV2640的DSP寄存器地址映射表#define OV2640_SENSOR_GAIN 0x00#define OV2640_SENSOR_COM1 0x03#define OV2640_SENSOR_REG040x04#define OV2640_SENSOR_REG080x08#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_CLKRC0x11#define OV2640_SENSOR_COM7 0x12#define OV2640_SENSOR_COM8 0x13#define OV2640_SENSOR_COM9 0x14#define OV2640_SENSOR_COM100x15#define OV2640_SENSOR_HREFST0x17#define OV2640_SENSOR_HREFEND 0x18#define OV2640_SENSOR_VSTART0x19#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_W0x26#define OV2640_SENSOR_REG2A0x2A#define OV2640_SENSOR_FRARL0x2B#define OV2640_SENSOR_ADDVSL0x2D#define OV2640_SENSOR_ADDVHS0x2E#define OV2640_SENSOR_YAVG 0x2F#define OV2640_SENSOR_REG320x32#define OV2640_SENSOR_ARCOM20x34#define OV2640_SENSOR_REG450x45#define OV2640_SENSOR_FLL 0x46#define OV2640_SENSOR_FLH 0x47#define OV2640_SENSOR_COM190x48#define OV2640_SENSOR_ZOOMS0x49#define OV2640_SENSOR_COM220x4B#define OV2640_SENSOR_COM250x4E#define OV2640_SENSOR_BD50 0x4F#define OV2640_SENSOR_BD60 0x50#define OV2640_SENSOR_REG5D0x5D#define OV2640_SENSOR_REG5E0x5E#define OV2640_SENSOR_REG5F0x5F#define OV2640_SENSOR_REG600x60#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*600const 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);//退出应用程序}}

如果觉得《w806开发板驱动ov2640读取jpeg图片1600x1200分辨率 以及花屏原因及解决办法》对你有帮助,请点赞、收藏,并留下你的观点哦!

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。