⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 csi.c

📁 用OV7720制作摄像头的详细电路原理图
💻 C
字号:
// =============================================================
// 文件名称:CSI.c
// 功能描述: CSI设置、运动帧测
// 维护记录: 2007-9-22 by chengju modify
// =============================================================

#include "SPCE3200_Register.h"
#include "SPCE3200_Constant.h"
#include "CSI.h"
#include "string.h"

unsigned int nDiff_buf_ldm[1200] __attribute__ ((section (".ar_LDM")));
unsigned int nMD_Frame_int;
unsigned int nDiff_buf[1200];
unsigned int Xsize, Ysize;
unsigned int nDiff_value;

unsigned int IntCount;


// =============================================================
// 语法格式:	void CSI_ADDR_Set(unsigned int FB1_Addr, unsigned int FB2_Addr, unsigned int FB3_Addr)
// 实现功能:	CSI帧缓冲区地址的设置
// 参数:		FB1_Addr、FB2_Addr、FB3_Addr:	CSI 帧缓冲区地址
// 返回值:		无
// =============================================================
void CSI_ADDR_Set(unsigned int FB1_Addr, unsigned int FB2_Addr, unsigned int FB3_Addr)
{
	*P_CSI_BUFFER_SA1 = FB1_Addr;				// 设置缓冲区1首地址
	*P_CSI_BUFFER_SA2 = FB2_Addr;				// 设置缓冲区2首地址
	*P_CSI_BUFFER_SA3 = FB3_Addr;				// 设置缓冲区3首地址		
}

// =============================================================
// 语法格式:	void CSI_Mode_Set(unsigned int MODE, unsigned int ColorModeIN, unsigned int ColorModeOUT)
// 实现功能:	CSI模式的设置
// 参数:		MODE:						VGA 或者 QVGA;
//				ColorModeIN:				YUVIN 或者 RGB565IN
//				ColorModeOUT:				YUNOUT 或者 RGB565OUT
// 返回值:		无
// =============================================================
void CSI_Mode_Set(unsigned int MODE, unsigned int ColorModeIN, unsigned int ColorModeOUT)
{
	unsigned int cr_set = 0;
	
	cr_set 	|= C_CSI_CSI_EN 					// 使能CSI模块
			| C_CSI_TG_CCIR656 					// 选择CSI的CCIR656接口格式
			| C_CSI_CLKINV_INV ;				// CSI时钟方式选择反向输入
	
	cr_set 	|= C_CSI_QVGA27_EN
			| C_CSI_DATA_TYPE2;					// 默认选择30FPS
	
	if(MODE == VGA)								// VGA or QVGA
	{
		cr_set 	|= C_CSI_TG_VGA;		
	}
	else
	{
		cr_set 	|= C_CSI_TG_QVGA;
	}
	
	if(ColorModeIN == YUVIN)						// 根据颜色模式进行设置
	{
		cr_set 	|= C_CSI_IN_YUV
				| C_CSI_YUV_YUYV;
	}
	else if(ColorModeIN == RGB565IN)
	{
		cr_set 	|= C_CSI_IN_RGB565;
	}
	if(ColorModeOUT == YUVOUT)						// 根据颜色模式进行设置
	{
		cr_set 	|= C_CSI_OUT_YUV422
				| C_CSI_YUV_YUYV;
	}

	*P_CSI_TG_CTRL	 = cr_set;
	
	OV7720_Mode_Set(MODE, ColorModeIN);				// 初始化摄像头OV7720的模式
}

// =============================================================
// 语法格式:	void CSI_Init(unsigned int MODE, unsigned int ColorModeIN, unsigned int ColorModeOUT, unsigned int FB1_Addr, unsigned int FB2_Addr, unsigned int FB3_Addr)
// 实现功能:	CSI的初始化,CSI帧缓冲地址的设置,CSI模式的设置
// 参数:		MODE:							VGA 或者 QVGA;
//				ColorModeIN:					YUVIN 或者 RGB565IN;
//				ColorModeOUT:					YUVOUT 或者 RGB565OUT;
//				FB1_Addr、FB2_Addr、FB3_Addr:	CSI Frame Buffer地址
// 返回值:		无
// =============================================================
void CSI_Init(unsigned int MODE, unsigned int ColorModeIN, unsigned int ColorModeOUT, unsigned int FB1_Addr, unsigned int FB2_Addr, unsigned int FB3_Addr)
{
	*P_CSI_INTERFACE_SEL |= C_CSI_PORT_CCIR656;			// 选择CSI的接口格式为:CCIR656
	*P_CSI_CLK_CONF = C_CSI_CLK_EN						// 使能时钟
					 |C_CSI_RST_DIS;					// 时钟不复位
	*P_CSI_CLK_SEL =  C_CSI_PIXELCLK_SRC;				// 选择CMOS传感器的时钟作为象素时钟
	
	CSI_ADDR_Set(FB1_Addr, FB1_Addr, FB1_Addr);			// 设置CSI的缓冲区地址
	
	CSI_Mode_Set(MODE, ColorModeIN, ColorModeOUT);		// 设置CSI的模式
}

// =============================================================
// 语法格式:	void Motion_Detect_Square_Fill(unsigned int nfb_start, unsigned int nX, unsigned int nY, unsigned int nSize, unsigned int nColor, unsigned int Mode) 
// 实现功能:	填充相应块
// 参数:		nfb_start:					缓冲区起始地址;
//				nX, nY:						X, Y偏移;
//				nSize:						填充大小
//				nColor:						填充颜色
//				Mode:						VGA或者QVGA
// 返回值:		无
// =============================================================
void Motion_Detect_Square_Fill(unsigned int nfb_start, unsigned int nX, unsigned int nY, unsigned int nSize, unsigned int nColor, unsigned int Mode) 
{
	int i, j;
	unsigned int nStart_addr;
	unsigned int nSize2;

 	if (Mode)
		nStart_addr = nfb_start + (nY*640) + nX*2;
	else 
		nStart_addr = nfb_start + (nY*1280) + nX*2;
	
	if (*(unsigned int*)(nStart_addr) != nColor) 
	{

		nSize2 = nSize * 2;
		for (i=0;i<nSize;i++) 
		{
			for (j=0;j<nSize2;j=j+4) 
				*(unsigned int*)(nStart_addr + j) = nColor;
 			if (Mode)
				nStart_addr += 640;
			else 
				nStart_addr += 1280;
		}
	}
	
}

// =============================================================
// 语法格式:	void Motion_Detect_Init(unsigned int Mode, unsigned int Size, unsigned int SampleMode, unsigned int Sensitivity)
// 实现功能:	CSI运动帧测初始化
// 参数:		MODE:							VGA 或者 QVGA;
//				Size:							SIZE16x16 或者 SIZE8x8
//				SampleMode:						每几帧采样一次进行比较,1~4
//				Sensitivity:					灵敏度,0x01~0x7f
// 返回值:		无
// =============================================================
void Motion_Detect_Init(unsigned int Mode, unsigned int Size, unsigned int SampleMode, unsigned int Sensitivity)
{
	
	while(Mode == VGA && Size == 8);								// 当选择VGA模式时,8x8的检测是不支持的
	
	*P_LDM_CLK_CONF = C_LDM_CLK_EN									// LDM时钟使能、不复位
					| C_LDM_RST_DIS;
					
	*P_INT_MASK_CTRL1 &= ~C_INT_MD_FRAME;							// 打开CSI相关中断

	*P_CSI_INT_CTRL = C_CSI_FRAME_END 								// 使能帧结束中断和数据溢出中断	
					| C_CSI_TG_OF;	
	
	*P_CSI_RECOGNITION_SA = (unsigned int)nDiff_buf;				// 设置识别起始地址
	*P_CSI_MD_CTRL =  C_CSI_MD_DIFF 								// 设置运动帧测模式
					| ((SampleMode - 1) << 2)						// 每几帧检测一次
					| (Sensitivity << 9);							// 灵敏度设置
	if(Size == SIZE16x16)											// 16x16 或者 8x8模式
		*P_CSI_MD_CTRL |= C_CSI_SAMP_TYPE16;
	else
		*P_CSI_MD_CTRL |= C_CSI_SAMP_TYPE8;

	nMD_Frame_int = 0;												// 初始化运动帧测标志
	
    *P_CSI_INT_CTRL |= C_CSI_FRAME_DIS 								// 使能帧无效中断、运动帧测结束中断、运动帧测缓冲区欠载中断
    				| C_CSI_MD_FRAME 
    				| C_CSI_MD_UF;

	Xsize = (Mode == QVGA ? 320 : 640) / Size;						// 计算X和Y方向的运动帧测块数
	Ysize = (Mode == QVGA ? 240 : 480) / Size;
																	
	*P_LDM_MIU_SA = (unsigned int)nDiff_buf;						// 设置将识别结果移到LDM,提高速度
	*P_LDM_MIU_EA = (unsigned int)nDiff_buf + ((Mode == QVGA ? 320 * 240 : 640 * 480)) / (Size * Size);
	*P_LDM_START_ADDR = (unsigned int)nDiff_buf_ldm;
	*P_LDM_END_ADDR = (unsigned int)nDiff_buf_ldm + ((Mode == QVGA ? 320 * 240 : 640 * 480)) / (Size * Size);
		
}

// =============================================================
// 语法格式:	void Motion_Detect(unsigned int Mode, unsigned int Size)
// 实现功能:	CSI运动检测
// 参数:		MODE:							VGA 或者 QVGA;
//				Size:							SIZE16x16 或者 SIZE8x8
// 返回值:		无
// =============================================================
void Motion_Detect(unsigned int Mode, unsigned int Size)
{
	unsigned int i, j, k;
	while (1) 
	{
		while (nMD_Frame_int == 0);
		nMD_Frame_int = 0;

		*P_LDM_MODE_CTRL = C_LDM_CTRL_EN							// 设置LDM模式
						 | C_LDM_MIU_LDM
						 | C_LDM_32BIT_BURST;			
		

		while (*P_LDM_INT_STATUS == 0);								// 等待LDM完成一次操作
		*P_LDM_INT_STATUS = C_LDM_INT_CLEAR;
		*P_LDM_MODE_CTRL = 0;
		
		k=0;
																	// 根据识别结果填充相应块
		for (i=0;i<Ysize;i++) 
		{
			for (j=0;j<Xsize;j++) 
			{
				if ((k&0x3) == 0)
				{
					nDiff_value = nDiff_buf_ldm[(k/4)] & 0xF;
				}	
				
				if ((nDiff_value & 0x1) != 0)
				{
					Motion_Detect_Square_Fill(CSI_FB1_ADDR, j*Size, i*Size, Size, FillColor_Red, Mode);	//  填充发生运动的块,用于标识。
					IntCount ++;
				}
				k++;
				nDiff_value = (nDiff_value>>1);
			}
		}
	}
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -