S3C2440A串口驱动-----WINCE6.0下通过串口和外设进行数据通信(二)

三,串口中断服务线程

串口中断产生以后,具体的数据处理将在中断服务线程里面完成,以BSP包中camera的中断线程为例

DWORD CameraCaptureThread(void)
{
	unsigned char tmp=0;
	static unsigned int time,old_time;
	static unsigned int cam_intr;
	
	DWORD	dwCause;

	//dwDisplayTimeout = INFINITE;

	SetProcPermissions((DWORD)-1);
	
	while(TRUE)
	{
		RETAILMSG(0,(TEXT("[CAM_HW] InterruptThread : Waiting For a Single Object\n\r")));
		
		dwCause = WaitForSingleObject(CameraEvent, dwDisplayTimeout);
		
		RETAILMSG(MSG_EN_1,(_T("CameraCaptureThread(%d)++\r\n"), frame_count));
		
		if (dwCause == WAIT_OBJECT_0)
		{
			Lock();

			__try
			{

				if (s2440INT->INTSUBMSK & ( 1 << IRQ_SUB_CAM_C ))
				{
					frame_count++;
					cam_intr |= ( 1 << IRQ_SUB_CAM_C );
				    
					s2440INT->SUBSRCPND  =  (1<<IRQ_SUB_CAM_C);
					s2440INT->INTSUBMSK &= ~(1<<IRQ_SUB_CAM_C);
					//RETAILMSG(1,(_T("CAM_C, ts %d\r\n"), GetTickCount()));
				}

				if (s2440INT->INTSUBMSK & ( 1 << IRQ_SUB_CAM_P ))
				{
					cam_intr |= ( 1 << IRQ_SUB_CAM_P );
					
					s2440INT->SUBSRCPND  =  (1<<IRQ_SUB_CAM_P);
					s2440INT->INTSUBMSK &= ~(1<<IRQ_SUB_CAM_P);
					//RETAILMSG(1,(_T("CAM_P, ts %d\r\n"), GetTickCount()));
				}

				if (((s2440INT->INTSUBMSK & ( 1 << IRQ_SUB_CAM_C )) == 0) && ((s2440INT->INTSUBMSK & ( 1 << IRQ_SUB_CAM_P )) == 0))
				{
					RETAILMSG(MSG_EN_1,(_T("[CAM]NOP\r\n")));					
				}
			
				InterruptDone(g_CamSysIntr);				
			
				//time = GetTickCount();
				//RETAILMSG(1,(TEXT("+time:%d\r\n"),(time - old_time)));
	
				// Handle any interrupts on the input source
				if (cam_intr & ( 1 << IRQ_SUB_CAM_P ))
				{
					// display the image	
					if (DRIVER_PREVIEW_ENABLE == 1)
					Display_Cam_Image(LCD_XSIZE_TFT-PREVIEW_X,0,PREVIEW_X, PREVIEW_Y, PORT_A);

					Buffer_preview_info_update();
					cam_intr &= ~( 1 << IRQ_SUB_CAM_P );
				}
					
				if (cam_intr & ( 1 << IRQ_SUB_CAM_C ))
				{
					Buffer_codec_info_update();
					cam_intr &= ~( 1 << IRQ_SUB_CAM_C );
				}

				// Enable camera interrupt
				//s2440INT->INTSUBMSK &= ~(( 1 << IRQ_SUB_CAM_P )|( 1 << IRQ_SUB_CAM_C ));
				//s2440INT->INTMSK &= ~( 1 << IRQ_CAM );

				//old_time = GetTickCount();
				//RETAILMSG(1,(TEXT("-time:%d\r\n"),(old_time-time)));

			}
			__except(EXCEPTION_EXECUTE_HANDLER)
			{
				RETAILMSG(PM_MSG, (TEXT("Camera.DLL:InterruptThread() - EXCEPTION: %d"), GetExceptionCode()));
			}
				
			Unlock();
			
		}
		else if (dwCause == WAIT_TIMEOUT)
		{
			Lock();
			
			RETAILMSG(PM_MSG,(_T("[CAM_HW] InterruptThread Timeout : %d msec\r\n"), dwDisplayTimeout));
			
			dwDisplayTimeout = INFINITE;				// reset timeout until Camera Interrupt occurs
			bIdlePwrDown = TRUE;					// Codec is off

			CamInterface_PowerDown();
			RETAILMSG(PM_MSG, (TEXT("[CAM_HW] InterruptThread : bIdlePwrDown = TRUE\r\n")));

			Unlock();
		}
		else
		{
			RETAILMSG(PM_MSG, (TEXT("[CAM_HW] InterruptThread : Exit %d, Cause %d\r\n"), GetLastError(), dwCause));
		}
	}

	return 0;
}
WaitForSingleObject()函数等待中断事件的方式。既是用在串口中断线程初始化时绑定的事件和逻辑中断 。函数的第二个参数表示等待事件发生的时间,INFINITE表示一直等待。中断触发以后设置中断标志变量cam_intr并且进行开中断的操作。OAL层的中断函数在common目录下的intr.c中实现。子中断寄存器的控制可以在OAL目录下的intr.c中实现。

四,S3C2440A串口寄存器的配置

用到了串口的FIFO模式传输数据,所以关键是配置UFCON和UCON。UFCON设置串口FIFO的中断触发值,如图


第4为用于使能FIFO模式和复位FIFO,高4位设置中断触发值,要是设置成0 ,就相当于没有使用FIFO模式。

UCON中和FIFO相关的是第8和第9位用于设置中断触发模式为LEVEL还是PULSE


Pulse模式的意思是当FIFO中的数据量刚达到你要求的时候就会产生中断. 但是注意,该中断只授那一刻产生,如果那时候你正在处理上一次的中断而把该中断mask掉,那么该中断就会被丢掉,FIFO中数据就会一直增加直到溢出;

Level模式的意思是只要FIFO中的数据量达到你要求的时候就会产生中断,包括比你要求的多的时候.

对于串口接收数据丢失的情况,一般我们设置FIFO接收中断的触发阀值为0,中断触发方式为LEVEL;即当FIFO中的值大于或者等于0个,都会触发接收中断,从而让中断服务线程及时的接收走数据。此外,为了更及时的响应中断,我们可以将中断服务线程中的InterruptDone函数改成自己写入清中断标志和使能中断代替,提高中断效率。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值