📄 csi.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 + -