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

📄 camera.c

📁 用SMART2200低成本的实现OV9650摄像头驱动
💻 C
📖 第 1 页 / 共 2 页
字号:
	return value;
}	
/*********************************************************************************************************
** 函数名称: 
** 功能描述: 
** 输 入: 
**
** 输 出:
** 全局变量:
** 调用模块:
********************************************************************************************************/
void __inline ov9650_config(void)
{
	int i;
	for (i = 0; i < OV9650_REGS; i++) 
	{
		if (ov9650_reg[i].subaddr == CHIP_DELAY)
			Delay(ov9650_reg[i].value);
		else
			ov9650_sccb_sendbyte(ov9650_reg[i].subaddr & 0xff, ov9650_reg[i].value & 0xff);
	}

}


/********** start of S/W YUV2RGB ************/

#define XLATTABSIZE      256
#define MulDiv(x, y, z)	((long)((int) x * (int) y) / (int) z)

//#define CLIP(x)	min_t(int, 255, max_t(int, 0, (x)))
#define CLIP(x) {if(x<0) x=0;if(x>255) x=255;}

#define RED_REGION      0xf800
#define GREEN_REGION    0x07e0
#define BLUE_REGION     0x001f

int XlatY[XLATTABSIZE] = { 0 };
int XlatV_B[XLATTABSIZE] = { 0 };
int XlatV_G[XLATTABSIZE] = { 0 };
int XlatU_G[XLATTABSIZE] = { 0 };
int XlatU_R[XLATTABSIZE] = { 0 };

#define ORIG_XLAT 1
/*********************************************************************************************************
** 函数名称: 
** 功能描述: 
** 输 入: 
**
** 输 出:
** 全局变量:
** 调用模块:
********************************************************************************************************/
void init_yuvtable (void)
{
	int i, j;

	for (i = 0; i < XLATTABSIZE; i++) {
#if ORIG_XLAT
		j = min(253, max(16, i));
#else
		j = (255 * i + 110) / 220;	// scale up
		j = min(255, max(j, 16));
#endif
		// orig: XlatY[i] = (int ) j;
		XlatY[i] = j-16;
	}

	for (i = 0; i < XLATTABSIZE; i++) {
#if ORIG_XLAT
		j = min(240, max(16, i));
		j -= 128;
#else
		j = i - 128;		// make signed
		if (j < 0)
			j++;			// noise reduction
		j = (127 * j + 56) / 112;	// scale up
		j = min(127, max(-128, j));
#endif

		XlatV_B[i] = MulDiv (j, 1000, 564);	/* j*219/126 */
		XlatV_G[i] = MulDiv (j, 1100, 3328);
		XlatU_G[i] = MulDiv (j, 3100, 4207);
		XlatU_R[i] = MulDiv (j, 1000, 713);
	}
}

#define MORE_QUALITY 1
/*********************************************************************************************************
** 函数名称: 
** 功能描述: 
** 输 入: 
**
** 输 出:
** 全局变量:
** 调用模块:
********************************************************************************************************/
void __inline yuv_convert_rgb16(unsigned char *rawY, unsigned char *rawU,
	  	unsigned char *rawV, unsigned short *rgb, int size)
{
	unsigned short  buf1, buf3;
	int   red;
	int   blue;
	int   green;
	unsigned long   cnt;
	int    Y, U, V;
	unsigned short  data;
	unsigned short  data2;

	for ( cnt = 0 ; cnt < size; cnt +=2)
	{
		buf1 = rawY[cnt] & 0xff;  // Y data
		buf3 = rawY[cnt+1] & 0xff;  // Y data

		U = rawV[cnt/2] & 0xff;
		V = rawU[cnt/2] & 0xff;

#if MORE_QUALITY
		Y = buf1;
#else
		Y = ((buf1+buf3)/2);
#endif

		red = XlatY[Y] + XlatU_R[U];
		CLIP(red);
		green = XlatY[Y] - XlatV_G[V] - XlatU_G[U];
		CLIP(green);
		blue = XlatY[Y] + XlatV_B[V];
		CLIP(blue);

		data = ((red << 8) & RED_REGION)
				| ((green << 3) & GREEN_REGION)
				| (blue >> 3);

#if MORE_QUALITY
		Y = buf3;
		red = XlatY[Y] + XlatU_R[U];
		CLIP(red);
		green = XlatY[Y] - XlatV_G[V] - XlatU_G[U];
		CLIP(green);
		blue = XlatY[Y] + XlatV_B[V];
		CLIP(blue); 

		data2 = ((red << 8) & RED_REGION)
				| ((green << 3) & GREEN_REGION)
				| (blue >> 3);
#else
		data2 = data;
#endif

		rgb[2 * cnt] = data;
		rgb[2 * (cnt + 1)]= data2;
	}
}

/********** end of S/W YUV2RGB ******************/
/*********************************************************************************************************
** 函数名称: 
** 功能描述: 使用PWM4输出占空比可调的PWM波形。
** 输 入: 
**
** 输 出:
** 全局变量:
** 调用模块:
********************************************************************************************************/
void SetCAMClockDivider(void)
{
  PINSEL0 = (PINSEL0&0xFFFCFFFF)|0x00020000;		// 设置PWM4连接到P0.8管脚
   
   PWMPR = 0x00;			    // 不分频,计数频率为Fpclk
   PWMMCR = 0x02;			    // 设置PWMMR0匹配时复位PWMTC
   PWMMR0 = CYCLE_DATA;    		// 设置PWM周期
   PWMMR4 = DUTY_CYCLE_DATA;	// 设置PWM占空比
   
   PWMLER = 0x11;			    // PWMMR0、PWMMR4锁存
   PWMPCR = 0x1000;				// 允许PWM4输出,单边PWM
   PWMTCR = 0x09;			    // 启动定时器,PWM使能
}
/*********************************************************************************************************
** 函数名称: 
** 功能描述: 
** 输 入: 
**
** 输 出:
** 全局变量:
** 调用模块:
********************************************************************************************************/
int __inline check_ov9650(void)
{
	int ret = 0;
	int ov9650_mid = 0;
	int try_count =0;	//2 times

try_again:

	ov9650_mid = (ov9650_sccb_receivebyte(0x1c) << 8);
	ov9650_mid |= ov9650_sccb_receivebyte(0x1d);
	
	if (ov9650_mid != OV9650_PRODUCT_ID)
	 {
		if (!try_count++) goto try_again;
		
		ret = -2;
	 } else {
		
	}
	
	//--- hzh, for ov9650
	ov9650_mid = (ov9650_sccb_receivebyte(0x0a) << 8);
	ov9650_mid |= ov9650_sccb_receivebyte(0x0b);

	return ret;
}
/*********************************************************************************************************
** 函数名称: 
** 功能描述: 
** 输 入: 
**
** 输 出:
** 全局变量:
** 调用模块:
********************************************************************************************************/
int Test_OV9650(void)
{
	int ret;
	
	init_yuvtable();
	
	CamPortSet();	
	
	ov9650_Init();
	ret = check_ov9650() ;
	if (ret) {   
		return ret; //错误指示
	}
	
	ov9650_config();
	
	return 0;
}
/*********************************************************************************************************
** 函数名称: 
** 功能描述: 
** 输 入: 
**
** 输 出:
** 全局变量:
** 调用模块:
********************************************************************************************************/
int Test_CamPreview(void)
{ 
  unsigned int   i, j;
  TCOLOR  bakc; 


  yuv_convert_rgb16(Cam_outY, Cam_outU,Cam_outV, RGBBuffer, Preview_size); 
  for(i=0;i<SCR_YSIZE_TFT_240320;i++)
  {
    for(j=0;j<SCR_XSIZE_TFT_240320;j++)
    {
    bakc=(RGBBuffer[(2*j)]<<8) | (RGBBuffer[(2*j)+1]) ;//将RGB数据转化为16位索引值
    GUI_Point(j, i, bakc);
    }
  }

    return(1);
 
}
/*********************************************************************************************************
** 函数名称: 
** 功能描述: 
** 输 入: 
**
** 输 出:
** 全局变量:
** 调用模块:
********************************************************************************************************/
void Camera_Task(void *pdata)
 {
 int i;
 uint8  err;
 void  *flag;
 pdata = pdata; 
 OSTaskSuspend(3);
 OSTaskSuspend(4);
 OSTaskSuspend(5); 	
 CamMbox = OSMboxCreate(NULL);   // 建立一个邮箱,用于传递摄像头消息	
 #if (USED_CAM_TYPE==CAM_OV9650)	//hzh
    SetCAMClockDivider(); 
	i = Test_OV9650();
	if( i )
	{
		IO2CLR |= LED1;//Led_on1();//错误指示
		OSTaskResume(3);
		OSTaskResume(4);
		OSTaskResume(5);
		OSTaskDel(OS_PRIO_SELF);
		return ;
	}
 #endif

	Led_on2();//正确指示
	VICIntEnable = (1<<15)|(1<<16)|(1<<17);	         // 使EINT0中断 
 while(1)	
   {
   
    flag = OSMboxPend(CamMbox, 0, &err);
    switch((int)flag) 
    {
     case 00:          
     case 01:
           break;
     case CAM_FRAME_END:       
     VICIntEnClr=(1<<15)|(1<<16)|(1<<17); // 禁止EINT0中断
     Test_CamPreview();
     Frame_Flag=0;//一次显示完成
     OSTimeDly(OS_TICKS_PER_SEC / 10);
     VICIntEnable = (1<<15)|(1<<16)|(1<<17);	  // 使EINT0中断 
           break;
     default:
           break;
    }
   } 
   OSTaskResume(3);
   OSTaskResume(4);
   OSTaskResume(5);
   OSTaskDel(OS_PRIO_SELF);    
    
	// stop camera	//Init()Lcd_Tft
	
 }


⌨️ 快捷键说明

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