uc/OS-II下ARM7定时器捕获实现红外解码


今天下午的时候,调试努力之下,终于把红外解码弄出来了。微笑其实之前有次比赛的时候就已经用到了红外,只是那次用的是51单片机,用的是外部中断和延时检测脉宽来进行解码,由于51的时钟这些比较简单,因此解码很容易就正确了。可是如今换到了ARM7平台下,因为对它的不是很熟悉,怎么用普通语句实现精确延时对我来讲是个难点。最后考虑用两个方案来实现红外的解码。方案一是用外部中断加定时器延时检测脉宽进行解码,可是结果并无我想的那样美好,调试了半天也没有实现正确的解码,我的认为是任务节拍的影响,可是确实不知道该怎么修改,最后放弃方案一,改用方案二,用定时器捕获实现红外的解码,并最终实现。函数

LPC2103芯片带有定时器捕获,能够设置为降低沿,上升沿或双边沿捕获中断。由于结合到此款红外编码方式,因此采用降低沿进行捕获。定时器0由于用做了系统节拍定时器,因此我选择了定时器1的捕获。ui

定时器1进行以下的初始化。编码

void SetTimer(void)
{
	T1TCR = 0x02;						//关闭复位定时器1
	T1PR = 10;						//11分频,约1us计时一次(外设时钟11.0592MHZ)
	T1CCR = 0x06;						//降低沿捕获并产生中断
	T1IR = 0x10;						//清除定时器1捕获0中断
	T1TCR = 0x01;						//开启定时器1
	
	VICVectAddr1 = (uint32)Timer1_Handler;			//中断向量相关设置
   	VICVectCntl1 = (0x20 | 0x05);
	VICIntEnable |= (1 << 5);
}



而后在定时器1中断服务函数里,就算出相邻两次降低沿之间的差值。而后经过消息邮箱把消息发送到脉宽检测任务进行处理。


void Timer1_Exception()
{
	static uint32 tOld; 		//保存旧的降低沿捕获值
	uint32 tNew;			//保存新的降低沿捕获值
	static i;
	
	OS_ENTER_CRITICAL();
	T1IR = 0x10;			//清除定时器1捕获0中断
	
	tNew = T1CR0;			
	tValue = tNew - tOld;		//获得两次降低沿之间的差值
	tOld = tNew; 			//以便下次中断处理
	OSMboxPost(Msg,(void*)tValue); 	//发送消息邮箱,行为同步
	OS_EXIT_CRITICAL();
	VICVectAddr = 0x00;
}


在检测脉宽任务里,我只须要根据测定脉宽与原本编码原有的脉宽进行比较判断,而后进行相关移位数据操做,获得数据码值。spa

由于个人遥控器有点不一样,地址码与地址反码不互反,因此不能进行地址的判断,因此滤除掉了引导码与地址码,直接进行了数据码的处理。调试

只要数据码与数据反码取反相同,则调试LED闪烁一下。code

固然我尚未具体知道遥控器按键对应的具体码制是多少,并且尚未检测到连发码,留待下次把码制经过串口发送到上位机进行显示。同步


 

这是检测脉宽任务的核心代码:it

	while (1)
	{
		OSMboxPend(Msg, 0, &err);			//等待脉宽检测消息

		if(tValue>2145  && tValue<2345)			//进行脉宽检测
		{	
			ucTemp = 1;				//逻辑1	
		}
		
		else if(tValue>1025 && tValue<1225)
		{
			ucTemp = 0;				//逻辑0
		}
		
		else if(tValue>13400  && tValue<13600)
		{
			ucCounter = 0;				//引导码
			usData0 = 0;
			usData1	= 0;
			flag = 1;
		}
		else
		{
			continue;
		}
		if(flag)					//数据处理过程
		{
			ucCounter++;
			if(ucCounter<16)
			{
				usData0 |= (uint16)ucTemp;
				usData0 <<= 1;
			}
			else if(ucCounter == 16)
			{
				usData0 |= (uint16)ucTemp;
			}
			else if(ucCounter < 32)
			{
				usData1 |= (uint16)ucTemp;
				usData1 <<= 1;
			}
			else if(ucCounter == 32)
			{
				usData1 |= (uint16)ucTemp;
				flag = 0;
				OSSemPost(Sem);			//发送信号量,进行码制转换任务,个人任务只是简单的实现了判断解码是否成功。
			}
		}
	}
相关文章
相关标签/搜索