本文引用地址:http://butianyuan.cn/article/201611/321674.htm// 攝像接口初始化
// 輸入?yún)?shù)分別為預(yù)覽目標寬和高(即 LCD 尺寸),以及水平和垂直偏移量
void CamInit(U32 PrDstWidth, U32 PrDstHeight, U32 WinHorOffset, U32 WinVerOffset)
{
U32 WinOfsEn;
U32 MainBurstSizeRGB, RemainedBurstSizeRGB;
U32 H_Shift, V_Shift, PreHorRatio, PreVerRatio, MainHorRatio, MainVerRatio;
U32 SrcWidth, SrcHeight;
U32 ScaleUp_H_Pr, ScaleUp_V_Pr;
// 判斷是否需要設(shè)置偏移量
if(WinHorOffset==0 && WinVerOffset==0)
WinOfsEn=0;
else
WinOfsEn=1;
SrcWidth=640-WinHorOffset*2;
SrcHeight=480-WinVerOffset*2;
// 判斷尺寸是放大還是縮小
if(SrcWidth>=PrDstWidth)
ScaleUp_H_Pr=0;//down
else
ScaleUp_H_Pr=1;//up
if(SrcHeight>=PrDstHeight)
ScaleUp_V_Pr=0;
else
ScaleUp_V_Pr=1;
rCIGCTRL |= (1<<26)|(0<<27);//PCLK 極性反轉(zhuǎn),外部攝像處理器輸入
rCIWDOFST = (1<<30)|(0xf<<12);// 清 FIFO 溢出
rCIWDOFST = 0;// 恢復(fù)正常模式
rCIWDOFST=(WinOfsEn<<31)|(WinHorOffset<<16)|(WinVerOffset);// 設(shè)置偏移量
rCISRCFMT=(1<<31)|(0<<30)|(0<<29)|(640<<16)|(0<<14)|(480);
// 設(shè)置內(nèi)存首地址,因為是直接顯示,所以設(shè)置為 LCD 緩存數(shù)組首地址
rCIPRCLRSA1 = (U32)LCD_BUFFER;
rCIPRCLRSA2 = (U32)LCD_BUFFER;
rCIPRCLRSA3 = (U32)LCD_BUFFER;
rCIPRCLRSA4 = (U32)LCD_BUFFER;
// 設(shè)置目標尺寸,并且不進行鏡像和旋轉(zhuǎn)處理
rCIPRTRGFMT=(PrDstWidth<<16)|(0<<14)|(PrDstHeight);
// 計算并設(shè)置突發(fā)長度
CalculateBurstSize(PrDstWidth*2, &MainBurstSizeRGB, &RemainedBurstSizeRGB);
rCIPRCTRL=(MainBurstSizeRGB<<19)|(RemainedBurstSizeRGB<<14);
// 計算水平和垂直縮放比率和位移量,以及主水平、垂直比率
CalculatePrescalerRatioShift(SrcWidth, PrDstWidth, &PreHorRatio, &H_Shift);
CalculatePrescalerRatioShift(SrcHeight, PrDstHeight, &PreVerRatio, &V_Shift);
MainHorRatio=(SrcWidth<<8)/(PrDstWidth<MainVerRatio=(SrcHeight<<8)/(PrDstHeight<
// 設(shè)置縮放所需的各類參數(shù)
rCIPRSCPRERATIO=((10-H_Shift-V_Shift)<<28)|(PreHorRatio<<16)|(PreVerRatio);
rCIPRSCPREDST=((SrcWidth/PreHorRatio)<<16)|(SrcHeight/PreVerRatio);
rCIPRSCCTRL=(1<<31)|(1 <<30)|(ScaleUp_H_Pr<<29)|(ScaleUp_V_Pr<<28)|(MainHorRatio<<16)|(MainVerRatio);
// 設(shè)置面積
rCIPRTAREA= PrDstWidth*PrDstHeight;
}
// 攝像中斷,在這里,除了清中斷標志,沒有其他操作
void __irq CamIsr(void)
{
rSUBSRCPND |= 1<<12;
rSRCPND |= 1<<6;
rINTPND |= 1<<6;
}
//UART 中斷
void __irq uartISR(void)
{
unsigned char ch;
rSUBSRCPND |= 0x3;
rSRCPND = 0x1<<28;
rINTPND = 0x1<<28;
ch = rURXH0; // 接收字節(jié)數(shù)據(jù)
switch(ch)
{
case 0x11:// 正常顯示視頻
com=1;
break;
case 0x22:// 定格圖像
com=2;
break;
case 0x33:// 放大尺寸
com=3;
break;
case 0x44:// 縮小尺寸
com =4;
break;
}
rUTXH0 = ch;
}
void Main(void)
{
int HOffset,VOffset;
// 初始化 UPLL ,以得到 OV9650 的系統(tǒng)時鐘
rUPLLCON = (56<<12) | (2<<4) | 1;//UPLL 為 96MHz
rCLKDIVN |= (1<<3);//UCLK = UPLL/2=48MHz
rCAMDIVN = (rCAMDIVN & ~(0xf))|(1<<4)|(2);// 設(shè)置攝像接口時鐘分頻
…………
LCD_Init();// 初始化 LCD ,其中 LCD 的顯示格式為 24 位 RGB 格式
rLCDCON1|=1;// 開啟 LCD
// 配置攝像接口引腳
rGPJCON = 0x2aaaaaa;
rGPJDAT = 0;
rGPJUP = 0;// 上拉使能
// 硬件復(fù)位攝像頭
rGPJDAT |= 1<<12;
delay(100);
rGPJDAT &= ~(1<<12);
// 軟件復(fù)位攝像接口
rCIGCTRL |= (1<<31);
delay(100);
rCIGCTRL &= ~(1<<31);
delay(100);
// 軟件復(fù)位攝像頭
rCIGCTRL |= (1<<30);
delay(300);
rCIGCTRL &= ~(1<<30);
delay(20000);
config_ov9650();// 配置 OV9650 寄存器
HOffset=0;
VOffset=0;
// 初始化攝像接口
CamInit(320,240,HOffset,VOffset);
// 開啟攝像接口中斷,
rSUBSRCPND |= 1<<12;
rSRCPND |= 1<<6;
rINTPND |= 1<<6;
rINTSUBMSK &= ~(1<<12);
rINTMSK &= ~(1<<6);
pISR_CAM = (U32)CamIsr;
rCIPRSCCTRL|=(1<<15);// 預(yù)覽縮放開啟
rCIIMGCPT =(1<<31)|(1<<29);// 預(yù)覽縮放捕捉使能
com=0;
while(1)
{
switch(com)
{
case 1:// 正常顯示
com=0;
rCIPRSCCTRL|=(1<<15);
rCIIMGCPT =(1<<31)|(1<<29);
break;
case 2:// 定格圖像
com=0;
rCIPRSCCTRL&=~(1<<15);
rCIIMGCPT &=~((1<<31)|(1<<29));
break;
case 3:// 放大視頻
com=0;
if(HOffset==160)
break;
HOffset += 8;
VOffset += 8;
rCIPRSCCTRL&=~(1<<15);
rCIIMGCPT &=~((1<<31)|(1<<29));
CamInit(320,240,HOffset,VOffset);
rCIPRSCCTRL|=(1<<15);
rCIIMGCPT =(1<<31)|(1<<29);
break;
case 4:// 縮小視頻
com=0;
if(HOffset==0)
break;
HOffset -= 8;
VOffset -= 8;
rCIPRSCCTRL&=~(1<<15);
rCIIMGCPT &=~((1<<31)|(1<<29));
CamInit(320,240,HOffset,VOffset);
rCIPRSCCTRL|=(1<<15);
rCIIMGCPT =(1<<31)|(1<<29);
break;
}
}
}
評論