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

📄 irdll.cpp

📁 嵌入式wince下进行红外码的采集和压缩,平台:wince42 xscale pxa225
💻 CPP
📖 第 1 页 / 共 2 页
字号:
#include "stdafx.h"
#include "IrDll.h"
#include "Pkfuncs.h"
#include <Afxwin.h>
extern "C" DWORD RequestSysIrq(DWORD DeviceIrq);
#define SYSINTR_ADVIR	0x48	//中断地址
#define SYSINTR_ADVIRUP	0x49	//中断地址
#define SYSINTR_ADVOEM	0x4a	//中断地址

#define SYSINTR_ADVOEM	0x4a	//中断地址
#define INT_TIMEOUT		30		//中断超时,单位毫秒
#define INTER_OF_FRAME	16000		//帧间隔标准,单位微秒

#define USER_WAITTIMES	15		//等待用户操作的时间(秒)
#define END_TIMES		1000			//1000ms内无信号则退出。
#define TIME_TARGET		1000000		//先假设目标单位为微秒
#define TIME_OUT_TARGET		614402		//先输出目标单位为1.6276us

#define TIME_MAX		60000		//最大宽度,超过这个宽度的电平都削减为此值
//
#define PRECISION_HIGH	80	//脉冲中高电平的精确度80%
#define PRECISION_PULSE	80	//脉冲宽度的精确度(高电平+低电平)80%
#define PULSE_KIND_MAX	8		//脉冲种类最大数
#define PULSE_MAX	512		//脉冲最大数
#define FRAME_MAX	100		//最大帧数
#define PULSE_FAILURE	20	//20us,认为失败的标准
#define PULSE_MIN		10	//5个脉冲对

//定义输出限制
#define OUT_PULSE_MAXKIND	8
#define OUT_PULSE_MAX		120	
#define OUT_START_PULSE		4	//脉冲起始位置
#define OUT_BUF_MIN			(OUT_START_PULSE+4 * OUT_PULSE_MAXKIND + OUT_PULSE_MAX/2)
#define OUT_START_INDEX		(OUT_START_PULSE +  4*OUT_PULSE_MAXKIND)	//脉冲索引起始位置
typedef struct tagPULSE{
	int ushHigh;
	int ushLow;
	int nWidth;
	int lTotalHigh;
	int lTotalLow;
	int nNum;	//本类型脉冲的数目
}Pulse_str,*pPulse_str;
typedef struct tagPULSE_COMPRESS{
	Pulse_str PulseList[PULSE_KIND_MAX];
	char cPulse[PULSE_MAX];							//先以一个byte来作为索引,可以有256个脉冲
	//附加的分析信息
	int nFrame;		//帧数量
	int nFramePos[FRAME_MAX];		//存放帧开始的脉冲索引
	int nPulseNum;			//有效脉冲数量
	int nPulseKindNum;		//有效脉冲种类

}Pulse_Compress_str,*pPulse_Compress_str;
//
int g_nRet;		//
#define IROUT_LENGTH	120
char g_cBuf[IROUT_LENGTH]={
	0x00,0x00,0x24,0x00,
	0x01,0x00,0x2,0x00,
	0x01,0x00,0x2,0x00,
	0x01,0x00,0x2,0x00,
	0x01,0x00,0x2,0x00,
	0x01,0x00,0x2,0x00,
	0x01,0x00,0x2,0x00,
	0x01,0x00,0x2,0x00,
	0x08,0x00,0x2,0x00,
	0x11,0x00,0x2,0x00,
	0x11,0x00,0x2,0x00,
	0x11,0x00,0x2,0x00,
	0x11,0x00,0x2,0x00,
	0x11,0x00,0x2,0x00,
	0x11,0x00,0x2,0x00,
	0x11,0x00,0x2,0x00,
	0x11,0x00,0x2,0x00,
};
BOOL g_bDioRuning =FALSE;
CWinThread *pThreadIr=NULL;
/*
功能:使用DIO进行数据采集
*/
#define IOCTL_GET_DI	0x1002
#define IOCTL_GET_DO	0x1003
#define IOCTL_SET_DO	0x1005
UINT ThreadIRDIO(char *pbuf,int nLen);
UINT ThreadIR( LPVOID pParam );
//	HANDLE	g_hAdvOEMHandle;

void writebuginfo(WCHAR *p);
int CompressData(int *pbuf,int nlen,char *pout,int noutlen);

BOOL APIENTRY DllMain( HANDLE hModule, 
                       DWORD  ul_reason_for_call, 
                       LPVOID lpReserved
					 )
{
    switch (ul_reason_for_call)
	{
		case DLL_PROCESS_ATTACH:
			g_nRet=ERR_IRDLL_NEVERSTUDY;
			memset(g_cBuf,0,IROUT_LENGTH);
			break;
		case DLL_THREAD_ATTACH:
		case DLL_THREAD_DETACH:
		case DLL_PROCESS_DETACH:
			break;
    }
    return TRUE;
}
IRDLL_API void BeginIrStudy()
{
	if(g_bDioRuning)
		return ;
//	printf("begin ir study!");
	g_nRet=ERR_IRDLL_RUNNING;
	g_bDioRuning =TRUE;
	memset(g_cBuf,0,IROUT_LENGTH);
	pThreadIr=AfxBeginThread(ThreadIR,NULL,0);

//	g_nRet=54;
}
IRDLL_API void StopIrStudy()
{
	if(g_bDioRuning)
	{
	//	SetEvent(g_hAdvOEMHandle);
		g_bDioRuning =FALSE;
		DWORD dwExit;
		do{
			if(!GetExitCodeThread(pThreadIr->m_hThread,&dwExit))
				break;
		}while(dwExit==STILL_ACTIVE);
	}else
	{
	}

}

IRDLL_API int GetIrData(char *pbuf,int nlen)
{
	if(g_bDioRuning)
	{
//		printf("return %d!",ERR_IRDLL_RUNNING);
		return ERR_IRDLL_RUNNING;
	}
	if(g_nRet <1)
	{
//		printf("return %d!",g_nRet);
		return g_nRet;
	}
	if(nlen < IROUT_LENGTH)
	{
//		printf("return %d!",ERR_IRDLL_BUFMIN);
		return ERR_IRDLL_BUFMIN;
	}
	memcpy(pbuf,g_cBuf,g_nRet>nlen?nlen:g_nRet);
//	printf("return %d!",g_nRet);
	if(g_nRet>IROUT_LENGTH)
		return ERR_IRDLL_OVERBUF;
	return g_nRet;
}
UINT ThreadIR( LPVOID pParam )
{
//	printf("begin ir Thread!");
	WCHAR wTemp[1024];
	int DataList[PULSE_MAX * 2];
	int i;
	int nret =ThreadIRDIO((char *)DataList,PULSE_MAX*sizeof(int)*2);
	{
	//	printf("study return %d!",g_nRet);
	}
	if(nret <=0)
	{
		g_nRet=nret;
		g_bDioRuning =FALSE;
		return -1;
	}
	g_nRet=CompressData(DataList,nret,g_cBuf,IROUT_LENGTH);
	unsigned short *psh=(unsigned short *)g_cBuf+2;
/*	for(i=0;i<IROUT_LENGTH-3;i+=4)
	{
		if(i<36)
			swprintf(wTemp,L"%d - %d",*(unsigned short*)(g_cBuf+i),*(unsigned short*)(g_cBuf+i+2));
		else
			swprintf(wTemp,L"%02X-%02x-%02x-%02x--",*(g_cBuf+i),*(g_cBuf+i+1),*(g_cBuf+i+2),*(g_cBuf+i+3));
		writebuginfo(wTemp);
	}
*/	for(i=0;i<16;i++,psh++)
	{
		*psh = *psh / 1.6276;
	}
/*	for(i=0;i<IROUT_LENGTH-3;i+=4)
	{
		if(i<36)
			swprintf(wTemp,L"%d - %d",*(unsigned short*)(g_cBuf+i),*(unsigned short*)(g_cBuf+i+2));
		else
			swprintf(wTemp,L"%02X-%02x-%02x-%02x--",*(g_cBuf+i),*(g_cBuf+i+1),*(g_cBuf+i+2),*(g_cBuf+i+3));
		writebuginfo(wTemp);
	}
	writebuginfo(L"=========End ==========");
*/
	g_bDioRuning =FALSE;
	return 1;
}

UINT ThreadIRDIO(char *pbuf,int nLen)
{

	HANDLE hCurThread=GetCurrentThread();
	int nPiority = GetThreadPriority(hCurThread);
	DWORD dwQuant=CeGetThreadQuantum(hCurThread);
	int Index=0,nValue,nOld;
	//打开DIO
	HANDLE hDio=NULL;
	DWORD nDi=0,dwTemp;
	LARGE_INTEGER lnFreq,lnTemp,lnPulseList[PULSE_MAX*2];
	memset(lnPulseList,0,sizeof(LARGE_INTEGER)*PULSE_MAX*2);

	hDio = CreateFile(TEXT("DIO1:"),GENERIC_READ | GENERIC_WRITE,0,NULL,OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL,NULL);
	if(hDio == INVALID_HANDLE_VALUE)
	{
	//	printf("Dio driver fail");
		return -1;
	}

//接收GPIO来启动测试
		DWORD   gSysIntr = 0,dwStat=0;
	HANDLE	hAdvOEMHandle;
	int i,nTimeOut=0,nLastTimeOut=0;
//	LARGE_INTEGER lnFreq,lnPulseList[PULSE_MAX*2];
//	memset(lnPulseList,0,sizeof(LARGE_INTEGER)*PULSE_MAX*2);
	
	// Initial interrupt event
	hAdvOEMHandle = CreateEvent(NULL,FALSE,FALSE,NULL);
	if( hAdvOEMHandle == NULL )
	{	
		g_bDioRuning=FALSE;
		return ERR_IRDLL_CREATEEVENT;
	}

	// Register system interrupt SYSINTR_ADVOEM
	gSysIntr=RequestSysIrq(SYSINTR_ADVIR);
	
	// ensure this interrupt has been disabled
	InterruptDisable(gSysIntr);

	CeSetThreadPriority(hCurThread,0);
	CeSetThreadQuantum(hCurThread,0);
	// This initialization register an event and enable the interrupt
	if (InterruptInitialize( gSysIntr, hAdvOEMHandle, NULL, 0) )
	{
		while(1)
		{
			RETAILMSG (1, (TEXT("Wait for Interrupt !!\r\n")));
			dwStat = WaitForSingleObject( hAdvOEMHandle, USER_WAITTIMES*1000);
			//	CloseHandle(hAdvOEMHandle);
			if( WAIT_OBJECT_0 == dwStat )   
			{
				break;
			}else
			{
				SetThreadPriority(hCurThread,nPiority);
				CeSetThreadQuantum(hCurThread,dwQuant);
				return ERR_IRDLL_OVERTIME;
			}
		}
	}else
	{
		SetThreadPriority(hCurThread,nPiority);
		CeSetThreadQuantum(hCurThread,dwQuant);
	//	CloseHandle(g_hAdvOEMHandle);
		return -1;
	}
//	printf("----------------------------------start\n");//add by gaoj test
	DeviceIoControl(hDio,IOCTL_GET_DI,&nDi,sizeof(DWORD),&nValue,sizeof(int),&dwTemp,NULL);
	nOld=nValue;		
	QueryPerformanceCounter(lnPulseList+Index);
	Index++;
	while(g_bDioRuning)
	{
		DeviceIoControl(hDio,IOCTL_GET_DI,&nDi,sizeof(DWORD),&nValue,sizeof(int),&dwTemp,NULL);
		if(nOld != nValue)
		{
			QueryPerformanceCounter(lnPulseList+Index);
			if(Index !=0)
			{
				lnPulseList[Index].QuadPart=(lnPulseList[Index].QuadPart +lnTemp.QuadPart)/2;
			}

			nOld = nValue;
			Index++;
			if(Index >= PULSE_MAX*2)
				break;
			QueryPerformanceCounter(&lnTemp);
			continue ;
		}
		QueryPerformanceCounter(&lnTemp);
	//	if(Index ==0)
	//	{
	//		if((lnTemp.QuadPart - lnPulseList[Index].QuadPart) /3686 >10000)
	//		{//等待10秒没有响应
	//			printf("not action====");
	//			break;
	//		}
	//	}else 
			if(Index >=1 && (lnTemp.QuadPart - lnPulseList[Index-1].QuadPart) /3686 >2000)
		{//等待2秒
			QueryPerformanceCounter(lnPulseList+Index);
			Index++;

⌨️ 快捷键说明

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