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


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

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

定时器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;
}


在检测脉宽任务里,我只需要根据测定脉宽与本来编码原有的脉宽进行比较判断,然后进行相关移位数据操作,得到数据码值。

因为我的遥控器有点不同,地址码与地址反码不互反,所以不能进行地址的判断,所以滤除掉了引导码与地址码,直接进行了数据码的处理。

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

当然我还没有具体知道遥控器按键对应的具体码制是多少,而且还没有检测到连发码,留待下次把码制通过串口发送到上位机进行显示。



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

	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);			//发送信号量,进行码制转换任务,我的任务只是简单的实现了判断解码是否成功。
			}
		}
	}





你可能感兴趣的:(ios,exception,timer,OS,任务,平台)