博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
uc/OS-II下ARM7定时器捕获实现红外解码
阅读量:6060 次
发布时间:2019-06-20

本文共 2090 字,大约阅读时间需要 6 分钟。

hot3.png

今天下午的时候,调试努力之下,终于把红外解码弄出来了。微笑其实以前有次比赛的时候就已经用到了红外,只是那次用的是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);			//发送信号量,进行码制转换任务,我的任务只是简单的实现了判断解码是否成功。			}		}	}
 
 
 
 
 
 

转载于:https://my.oschina.net/u/1587304/blog/399880

你可能感兴趣的文章
Kernel常见锁的原理和实现
查看>>
OPENCV 使用系列二 grabcut 的使用(简单但有用的图像分割)
查看>>
Python socket programming tutorial
查看>>
不常见的正则表达式
查看>>
类自定载入
查看>>
一次归档故障的解决(ORA-00257错误)
查看>>
跟我一步一步开发自己的Openfire插件
查看>>
AWES加密和解密
查看>>
近期情况记录
查看>>
cer文件转pem文件
查看>>
如何正确地处理时间
查看>>
Oracle的数据字典的解释
查看>>
2、nginx中使用Lua根据url参数长度跳转到不同的upstream
查看>>
ANR异常产生的原因及其解决办法
查看>>
JNI开发流程及HelloWorld
查看>>
TCP链接
查看>>
static_cast、dynamic_cast、reinterpret_cast、和const_cast
查看>>
Apache Slider
查看>>
浅析SkipList跳跃表原理及代码实现
查看>>
数学公式
查看>>