From 4179db33d2b39856421540ef15eb251b485d4303 Mon Sep 17 00:00:00 2001 From: Yang Qingsheng Date: Wed, 6 Jan 2021 14:41:09 +0800 Subject: [PATCH] Update ov2640.c --- .../BSP/Hardware/Src/ov2640.c | 199 +++++++++--------- 1 file changed, 105 insertions(+), 94 deletions(-) diff --git a/board/NUCLEO_STM32L496ZG/BSP/Hardware/Src/ov2640.c b/board/NUCLEO_STM32L496ZG/BSP/Hardware/Src/ov2640.c index c3cfef1d..213fc21d 100644 --- a/board/NUCLEO_STM32L496ZG/BSP/Hardware/Src/ov2640.c +++ b/board/NUCLEO_STM32L496ZG/BSP/Hardware/Src/ov2640.c @@ -6,11 +6,22 @@ #include "usart.h" #include "sccb.h" #include "stdio.h" - -//初始化OV2640 -//配置完以后,默认输出是1600*1200尺寸的图片!! -//返回值:0,成功 -// 其他,错误代码 +////////////////////////////////////////////////////////////////////////////////// +//鏈▼搴忓彧渚涘涔犱娇鐢紝鏈粡浣滆呰鍙紝涓嶅緱鐢ㄤ簬鍏跺畠浠讳綍鐢ㄩ +//ALIENTEK STM32F103寮鍙戞澘 +//OV2640 椹卞姩浠g爜 +//姝g偣鍘熷瓙@ALIENTEK +//鎶鏈鍧:www.openedv.com +//鍒涘缓鏃ユ湡:2015/4/16 +//鐗堟湰锛歏1.0 +//鐗堟潈鎵鏈夛紝鐩楃増蹇呯┒銆 +//Copyright(C) 骞垮窞甯傛槦缈肩數瀛愮鎶鏈夐檺鍏徃 2014-2024 +//All rights reserved +////////////////////////////////////////////////////////////////////////////////// +//鍒濆鍖朞V2640 +//閰嶇疆瀹屼互鍚,榛樿杈撳嚭鏄1600*1200灏哄鐨勫浘鐗!! +//杩斿洖鍊:0,鎴愬姛 +// 鍏朵粬,閿欒浠g爜 void OV2640_PWDN(uint8_t signal) { HAL_GPIO_WritePin(GPIOB, GPIO_PIN_15, (GPIO_PinState)signal); @@ -25,38 +36,38 @@ uint8_t OV2640_Init(void) { uint16_t i=0; uint16_t reg; - //设置IO + //璁剧疆IO GPIO_InitTypeDef GPIO_InitStructure; - __HAL_RCC_GPIOG_CLK_ENABLE(); //使能GPIOB时钟 + __HAL_RCC_GPIOG_CLK_ENABLE(); //浣胯兘GPIOB鏃堕挓 HAL_GPIO_WritePin(GPIOB, GPIO_PIN_13|GPIO_PIN_15, GPIO_PIN_RESET); - //GPIOF9,F10初始化设置 + //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);//初始 + GPIO_InitStructure.Pull = GPIO_PULLUP;//涓婃媺 + HAL_GPIO_Init(GPIOB, &GPIO_InitStructure);//鍒濆锟 OV2640_PWDN(0); //POWER ON delay_ms(10); - OV2640_RST(0); //复位OV2640 + 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 + OV2640_RST(1); //缁撴潫澶嶄綅 + SCCB_Init(); //鍒濆鍖朣CCB 鐨処O鍙 + SCCB_WR_Reg(OV2640_DSP_RA_DLMT, 0x01); //鎿嶄綔sensor瀵勫瓨鍣 + SCCB_WR_Reg(OV2640_SENSOR_COM7, 0x80); //杞浣峅V2640 delay_ms(50); - reg=SCCB_RD_Reg(OV2640_SENSOR_MIDH); //读取厂家ID 高八位 + reg=SCCB_RD_Reg(OV2640_SENSOR_MIDH); //璇诲彇鍘傚ID 楂樺叓浣 reg<<=8; - reg|=SCCB_RD_Reg(OV2640_SENSOR_MIDL); //读取厂家ID 低八位 + 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=SCCB_RD_Reg(OV2640_SENSOR_PIDH); //璇诲彇鍘傚ID 楂樺叓浣 reg<<=8; - reg|=SCCB_RD_Reg(OV2640_SENSOR_PIDL); //读取厂家ID 低八位 + reg|=SCCB_RD_Reg(OV2640_SENSOR_PIDL); //璇诲彇鍘傚ID 浣庡叓浣 if(reg!=OV2640_PID) { printf("HID:%d\r\n",reg); @@ -69,34 +80,34 @@ uint8_t OV2640_Init(void) printf("OV2640_init SUCCESS\n"); return 0x00; //ok } -//OV2640切换为JPEG模式 +//OV2640鍒囨崲涓篔PEG妯″紡 void OV2640_JPEG_Mode(void) { uint16_t i=0; - //设置:YUV422格式 + //璁剧疆: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数据 + //璁剧疆:杈撳嚭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模式 +//OV2640鍒囨崲涓篟GB565妯″紡 void OV2640_RGB565_Mode(void) { uint16_t i=0; - //设置:RGB565输出 + //璁剧疆: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]); } printf("OV2640_RGB565 SET!\n"); } -//自动曝光设置参数表,支持5个等级 +//鑷姩鏇濆厜璁剧疆鍙傛暟琛,鏀寔5涓瓑绾 const static uint8_t OV2640_AUTOEXPOSURE_LEVEL[5][8]= { { @@ -130,7 +141,7 @@ const static uint8_t OV2640_AUTOEXPOSURE_LEVEL[5][8]= 0x26,0x92, }, }; -//OV2640自动曝光等级设置 +//OV2640鑷姩鏇濆厜绛夌骇璁剧疆 //level:0~4 void OV2640_Auto_Exposure(uint8_t level) { @@ -141,12 +152,12 @@ void OV2640_Auto_Exposure(uint8_t level) SCCB_WR_Reg(p[i*2],p[i*2+1]); } } -//白平衡设置 -//0:自动 -//1:太阳sunny -//2,阴天cloudy -//3,办公室office -//4,家里home +//鐧藉钩琛¤缃 +//0:鑷姩 +//1:澶槼sunny +//2,闃村ぉcloudy +//3,鍔炲叕瀹ffice +//4,瀹堕噷home void OV2640_Light_Mode(uint8_t mode) { uint8_t regccval=0X5E;//Sunny @@ -180,7 +191,7 @@ void OV2640_Light_Mode(uint8_t mode) SCCB_WR_Reg(0XCD,regcdval); SCCB_WR_Reg(0XCE,regceval); } -//色度设置 +//鑹插害璁剧疆 //0:-2 //1:-1 //2,0 @@ -196,7 +207,7 @@ void OV2640_Color_Saturation(uint8_t sat) SCCB_WR_Reg(0X7D,reg7dval); SCCB_WR_Reg(0X7D,reg7dval); } -//亮度设置 +//浜害璁剧疆 //0:(0X00)-2 //1:(0X10)-1 //2,(0X20) 0 @@ -211,7 +222,7 @@ void OV2640_Brightness(uint8_t bright) SCCB_WR_Reg(0x7d, bright<<4); SCCB_WR_Reg(0x7d, 0x00); } -//对比度设置 +//瀵规瘮搴﹁缃 //0:-2 //1:-1 //2,0 @@ -219,7 +230,7 @@ void OV2640_Brightness(uint8_t bright) //4,+2 void OV2640_Contrast(uint8_t contrast) { - uint8_t reg7d0val=0X20;//默认为普通模式 + uint8_t reg7d0val=0X20;//榛樿涓烘櫘閫氭ā寮 uint8_t reg7d1val=0X20; switch(contrast) { @@ -249,43 +260,43 @@ void OV2640_Contrast(uint8_t contrast) SCCB_WR_Reg(0x7d,reg7d1val); SCCB_WR_Reg(0x7d,0x06); } -//特效设置 -//0:普通模式 -//1,负片 -//2,黑白 -//3,偏红色 -//4,偏绿色 -//5,偏蓝色 -//6,复古 +//鐗规晥璁剧疆 +//0:鏅氭ā寮 +//1,璐熺墖 +//2,榛戠櫧 +//3,鍋忕孩鑹 +//4,鍋忕豢鑹 +//5,鍋忚摑鑹 +//6,澶嶅彜 void OV2640_Special_Effects(uint8_t eft) { - uint8_t reg7d0val=0X00;//默认为普通模式 + uint8_t reg7d0val=0X00;//榛樿涓烘櫘閫氭ā寮 uint8_t reg7d1val=0X80; uint8_t reg7d2val=0X80; switch(eft) { - case 1://负片 + case 1://璐熺墖 reg7d0val=0X40; break; - case 2://黑白 + case 2://榛戠櫧 reg7d0val=0X18; break; - case 3://偏红色 + case 3://鍋忕孩鑹 reg7d0val=0X18; reg7d1val=0X40; reg7d2val=0XC0; break; - case 4://偏绿色 + case 4://鍋忕豢鑹 reg7d0val=0X18; reg7d1val=0X40; reg7d2val=0X40; break; - case 5://偏蓝色 + case 5://鍋忚摑鑹 reg7d0val=0X18; reg7d1val=0XA0; reg7d2val=0X40; break; - case 6://复古 + case 6://澶嶅彜 reg7d0val=0X18; reg7d1val=0X40; reg7d2val=0XA6; @@ -298,9 +309,9 @@ void OV2640_Special_Effects(uint8_t eft) SCCB_WR_Reg(0x7d,reg7d1val); SCCB_WR_Reg(0x7d,reg7d2val); } -//彩条测试 -//sw:0,关闭彩条 -// 1,开启彩条(注意OV2640的彩条是叠加在图像上面的) +//褰╂潯娴嬭瘯 +//sw:0,鍏抽棴褰╂潯 +// 1,寮鍚僵鏉(娉ㄦ剰OV2640鐨勫僵鏉℃槸鍙犲姞鍦ㄥ浘鍍忎笂闈㈢殑) void OV2640_Color_Bar(uint8_t sw) { uint8_t reg; @@ -310,9 +321,9 @@ void OV2640_Color_Bar(uint8_t sw) if(sw)reg|=1<<1; SCCB_WR_Reg(0X12,reg); } -//设置图像输出窗口 -//sx,sy,起始地址 -//width,height:宽度(对应:horizontal)和高度(对应:vertical) +//璁剧疆鍥惧儚杈撳嚭绐楀彛 +//sx,sy,璧峰鍦板潃 +//width,height:瀹藉害(瀵瑰簲:horizontal)鍜岄珮搴(瀵瑰簲:vertical) void OV2640_Window_Set(uint16_t sx,uint16_t sy,uint16_t width,uint16_t height) { uint16_t endx; @@ -322,25 +333,25 @@ void OV2640_Window_Set(uint16_t sx,uint16_t sy,uint16_t width,uint16_t height) endy=sy+height/2; SCCB_WR_Reg(0XFF,0X01); - temp=SCCB_RD_Reg(0X03); //读取Vref之前的值 + 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位 + SCCB_WR_Reg(0X03,temp); //璁剧疆Vref鐨剆tart鍜宔nd鐨勬渶浣2浣 + SCCB_WR_Reg(0X19,sy>>2); //璁剧疆Vref鐨剆tart楂8浣 + SCCB_WR_Reg(0X1A,endy>>2); //璁剧疆Vref鐨別nd鐨勯珮8浣 - temp=SCCB_RD_Reg(0X32); //读取Href之前的值 + 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位 + SCCB_WR_Reg(0X32,temp); //璁剧疆Href鐨剆tart鍜宔nd鐨勬渶浣3浣 + SCCB_WR_Reg(0X17,sx>>3); //璁剧疆Href鐨剆tart楂8浣 + SCCB_WR_Reg(0X18,endx>>3); //璁剧疆Href鐨別nd鐨勯珮8浣 } -//设置图像输出大小 -//OV2640输出图像的大小(分辨率),完全由改函数确定 -//width,height:宽度(对应:horizontal)和高度(对应:vertical),width和height必须是4的倍数 -//返回值:0,设置成功 -// 其他,设置失败 +//璁剧疆鍥惧儚杈撳嚭澶у皬 +//OV2640杈撳嚭鍥惧儚鐨勫ぇ灏(鍒嗚鲸鐜),瀹屽叏鐢辨敼鍑芥暟纭畾 +//width,height:瀹藉害(瀵瑰簲:horizontal)鍜岄珮搴(瀵瑰簲:vertical),width鍜宧eight蹇呴』鏄4鐨勫嶆暟 +//杩斿洖鍊:0,璁剧疆鎴愬姛 +// 鍏朵粬,璁剧疆澶辫触 uint8_t OV2640_OutSize_Set(uint16_t width,uint16_t height) { uint16_t outh; @@ -352,23 +363,23 @@ uint8_t OV2640_OutSize_Set(uint16_t width,uint16_t height) 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的低八位 + 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(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,设置成功 -// 其他,设置失败 +//璁剧疆鍥惧儚寮绐楀ぇ灏 +//鐢:OV2640_ImageSize_Set纭畾浼犳劅鍣ㄨ緭鍑哄垎杈ㄧ巼浠庡ぇ灏. +//璇ュ嚱鏁板垯鍦ㄨ繖涓寖鍥翠笂闈㈣繘琛屽紑绐,鐢ㄤ簬OV2640_OutSize_Set鐨勮緭鍑 +//娉ㄦ剰:鏈嚱鏁扮殑瀹藉害鍜岄珮搴,蹇呴』澶т簬绛変簬OV2640_OutSize_Set鍑芥暟鐨勫搴﹀拰楂樺害 +// OV2640_OutSize_Set璁剧疆鐨勫搴﹀拰楂樺害,鏍规嵁鏈嚱鏁拌缃殑瀹藉害鍜岄珮搴,鐢盌SP +// 鑷姩璁$畻缂╂斁姣斾緥,杈撳嚭缁欏閮ㄨ澶. +//width,height:瀹藉害(瀵瑰簲:horizontal)鍜岄珮搴(瀵瑰簲:vertical),width鍜宧eight蹇呴』鏄4鐨勫嶆暟 +//杩斿洖鍊:0,璁剧疆鎴愬姛 +// 鍏朵粬,璁剧疆澶辫触 uint8_t OV2640_ImageWin_Set(uint16_t offx,uint16_t offy,uint16_t width,uint16_t height) { uint16_t hsize; @@ -380,31 +391,31 @@ uint8_t OV2640_ImageWin_Set(uint16_t offx,uint16_t offy,uint16_t width,uint16_t 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的低八位 + 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(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,设置成功 -// 其他,设置失败 +//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位 + 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;