微波EDA网,见证研发工程师的成长!
首页 > 研发问答 > 无线和射频 > 射频无线通信设计 > 有关红外解码的问题

有关红外解码的问题

时间:10-02 整理:3721RD 点击:
我用延时的方法已经实现了红外解码,但是不知为何用TIMER1计数却得到的脉冲数串口输出分析后,感觉有问题。我使用的主频是32M,计数器分频到128。也就是1/4M.也就是说每次计数加1就是4us。不知道输出的脉冲计数值都很大,按理来说应该就是脉冲应该基本在一千左右的数。但是我的计数值竟然上万了,请问是什么原因呢?希望搞过的一起相互讨论学习。现在我把代码贴出来以供大伙一起研究分析
//本解码程序适用于NEC的upd6121及其兼容芯片的解码,支持大多数遥控器 实验板采用32M晶振
#include<ioCC2530.h> //包含单片机寄存器的头文件
#define IR P1_0 //将IR位定义为P1.0引脚
#define bool char
#define unint unsigned int
#define unchar unsigned char
unsigned char flag;
unsigned char a[4]; //储存用户码、用户反码与键数据码、键数据反码
unsigned int LowTime,HighTime; //储存高、低电平的宽度
/*****************************************************
函数功能:延时1ms
***************************************************/
void delay1ms()
{
unsigned char i,j;
for(i=0;i<10;i++)
for(j=0;j<33;j++);
}
/*****************************************************
函数功能:延时若干毫秒
入口参数:n
***************************************************/
void delay(unsigned char n)
{
unsigned char i;
for(i=0;i<n;i++)
delay1ms();
}
/************************************************************
函数功能:对4个字节的用户码和键数据码进行解码
说明:解码正确,返回1,否则返回0
出口参数:dat
*************************************************************/
bool DeCode(void)
{
unsigned char i,j;
unsigned char temp; //储存解码出的数据
for(i=0;i<4;i++) //连续读取4个用户码和键数据码
{
for(j=0;j<8;j++) //每个码有8位数字
{
temp=temp>>1; //temp中的各数据位右移一位,因为先读出的是高位数据
T1CNTL=0; //定时器清0
T1CNTH=0; //定时器清0
T1CTL=0x01; //打开定时器T1
while(IR==0); //如果是低电平就等待 //低电平计时
T1CTL=0x00; //关闭定时器T1
LowTime=T1CNTH*256+T1CNTL; //保存低电平宽度
T1CNTL=0; //定时器清0
T1CNTH=0; //定时器清0
T1CTL=0x01; //打开定时器T1
while(IR==1); //如果是高电平就等待
T1CTL=0x00; //关闭定时器T1
HighTime=T1CNTH*256+T1CNTL; //保存高电平宽度
if((LowTime*4<520)||(LowTime*4>680))
return 0; //如果低电平长度不在合理范围,则认为出错,停止解码
if((HighTime*4>550)&&(HighTime*4<660)) //如果高电平时间在560微秒左右,即计数560/1=560次
temp=temp&0x7f; //(560-100=550, 560+100=660),则该位是0
if((HighTime*4>1350)&&(HighTime*4<1930)) //如果高电平时间在1680微秒左右,即计数1680/1=1680次
temp=temp|0x80; //(1680-250=1350,1680+250=1930),则该位是1
}
a=temp; //将解码出的字节值储存在a
}
if(a[2]=a[3]) //验证键数据码和其反码是否相等,一般情况下不必验证用户码
return 1; //解码正确,返回1
else
return 0; //解码失败,返回0
}
/*******************************************************************
函数功能:整形转化为ascii
函数参数:参数pulse为要转化的红外脉冲,参数str为转化后的脉冲字符串
函数返回值:void
********************************************************************/
void inttoasc(unint pulse, unchar * str )
{
*str=pulse/10000+'0'; //保存脉冲的万位
*(str+1)=(pulse%10000)/1000+'0';//保存脉冲的千位
*(str+2)=(pulse%1000)/100+'0';//保存脉冲的百位
*(str+3)=(pulse%100)/10+'0';//保存脉冲的十位
*(str+4)=pulse%10+'0';//保存脉冲的个位
*(str+5)='\n'; //换行
}
/****************************************************************
串口初始化函数
****************************************************************/
void initUARTSEND(void)
{
CLKCONCMD &= 0x40; //设置系统时钟源为32MHZ晶振
while(CLKCONSTA & 0x40); //等待晶振稳定
CLKCONCMD &= 0x47; //设置系统主时钟频率为32MHZ 定时器分频为1/4M
PERCFG = 0x00; //位置1 P0口
P0SEL = 0x3c; //P0_2,P0_3,P0_4,P0_5用作串口
P2DIR &= 0XC0; //P0优先作为UART0
U0CSR |= 0x80; //UART方式
U0GCR |= 9;
U0BAUD |= 59; //波特率设为19200
UTX0IF = 0; //UART0 TX中断标志初始置位0
}
/****************************************************************
串口发送字符串函数
****************************************************************/
void UartTX_Send_String(char *Data,int len)
{
int j;
for(j=0;j<len;j++)
{
U0DBUF = *Data++;
while(UTX0IF == 0);
UTX0IF = 0;
}
}
void IRDecode_init(void)
{
IEN2 |= 0X10; // 允许P1口中断使能;
P1IEN |= 0X1; //P10设置为中断使能位;
PICTL |= 0X2; // 下降沿触发
P1IFG = 0x00; // 初始化中断标志位
T1CTL=0x00; //关闭定时器T1
EA=1; //开启总中断
}
/************************************************************
函数功能:主函数
*************************************************************/
void main()
{
initUARTSEND();
IRDecode_init();
while(1); //等待红外信号产生的中断
}
/************************************************************
函数功能:红外线触发的外中断处理函数
*************************************************************/
#pragma vector = P1INT_VECTOR //格式:#pragma vector = 中断向量,紧接着是中断处理程序
__interrupt void P1_ISR(void)
{
static unchar str[6];
//EX0=0; //关闭外中断0,不再接收二次红外信号的中断,只解码当前红外信号
P1IEN &=0X1; //P10设置为中断使能位失效;
T1CNTL=0; //定时器清0
T1CNTH=0; //定时器清0
T1CTL=0x01; //打开定时器T1
while(IR==0); //如果是低电平就等待,给引导码低电平计时
T1CTL=0x00; //关闭定时器T1
LowTime=T1CNTH*256+T1CNTL; //保存低电平时间
T1CNTL=0; //定时器清0
T1CNTH=0; //定时器清0
T1CTL=0x01; //打开定时器T1
while(IR==1); //如果是高电平就等待,给引导码高电平计时
T1CTL=0x00; //关闭定时器T1
HighTime=T1CNTH*256+T1CNTL; //保存引导码的高电平长度
UartTX_Send_String("LOW:",sizeof("LOW:"));
inttoasc(LowTime,str);
UartTX_Send_String(str,sizeof(str));
UartTX_Send_String("HIGH:",sizeof("HIGH:"));
inttoasc(HighTime,str);
UartTX_Send_String(str,sizeof(str));
//if((LowTime*4>8500)&&(LowTime*4<9500)&&(HighTime*4>4000)&&(HighTime*4<5000))
if((LowTime*4>8500)&&(LowTime*4<9500))
{
//如果是引导码,就开始解码,否则放弃,引导码的低电平计时
//次数=9000us/1us=9000, 判断区间:9000-500=8500,9000+500=9500.
UartTX_Send_String("oye",sizeof("oye"));
if(DeCode()==1) // 执行遥控解码功能
{
UartTX_Send_String("OK",sizeof("OK"));
}
}
P1IEN |=0X1; //P10设置为中断使能位;
}

都快看晕了.....

无关的子程序贴出来干什么?
TIMER1在哪,为什么我找了半天没找到这个宏或者变量

你最好看英文的datasheet。就是在定时器那章节。

在中断入口设置断点,看是不是代码无法进入中断呀

进入了中断,我后来发现那个定时器有问题,貌似直接把T1CNTL=0; 无法把计数器值置为0,可是数据手册说,只要给它任何值就可以把这个计数器清到0.搞不懂为什么。那样导致计的高低电平的高八位不会清到。导致计数出错,我也是找了好久才发现。

Copyright © 2017-2020 微波EDA网 版权所有

网站地图

Top