• 回复
  • 收藏
  • 点赞
  • 分享
  • 发新帖

PIC16F877A 单片机 红外线遥控 解码函数求解答?

买了本学习PIC单片机的书,光盘中带的函数如下,但是现在不能正常解码,求各位大师傅们能给解惑。指导一下RVC红外扫描译码部分的函数。
#include
__CONFIG(0x2F02);
//芯片配置字,看门狗关,上电延时开,掉电检测关,低压编程关,加密,4M晶体HS振荡
#define uchar  unsigned char
#define uint   unsigned int
#define bitset(var,bitno)((var)|=1<<(bitno))
#define bitclr(var,bitno)((var)&=~(1<<(bitno)))
//下面这段程序用的是结构体的位域,方便进行位操作
union {
	struct
	{
unsigned b0: 1;
unsigned b1: 1;
unsigned b2: 1;
unsigned b3: 1;
unsigned b4: 1;
unsigned b5: 1;
unsigned b6: 1;
unsigned b7: 1;
	}
	oneBit;
	unsigned char allBits;
} myFlag;
#define CNT2_1  myFlag.oneBit.b1
#define CNT2_2  myFlag.oneBit.b2
#define CNT2_3  myFlag.oneBit.b3
#define CNT2   myFlag .allBits

static bit FLAGS ;
static bit Bitin;

union Csr
{ unsigned long i;
	unsigned char Csra[4];
}myCsra;

#define  RMT   RE2	                            // ;遥控接收输入脚位地址(RA。1)
#define  BITIN  7                               //遥控接收数据位位标志
uchar CNT0, CNT3, CNT4;                         //用户临时寄存器1--4
uint CNT1;
uchar TABADD;                                  //数码管显示码取码用寄存器
uchar CSR0;                                    //;遥控键码反码寄存器
uchar CSR1;                                    //;遥控器键码寄存器
uchar CSR2;                                    //;遥控器用户码高8位寄存器
uchar CSR3;                                    //;遥控器用户码低8位寄存器
uchar FLAGS2;                                  //;临时寄存器
uchar CSR2A ;                                  //遥控接收32位数据暂存寄存器
const unsigned char table[] = {0x3f, 0x6, 0x5b, 0x4f, 0x66, 0x6d, 0x7d, 0x7, 0x7f, 0x6f, 0x77, 0x7c, 0x39, 0x5e, 0x79, 0x71};

// 0,     1,    2,   3,    4,   5,    6,   7,   8,   9,   a,   b,    c,   d,    e,    f,
//*************延时函数*************
void delay(uint xms,uint xus)
{
	int i,j;
	for(i=0;i>xms;i--);
	{for(j=0;j>xus;j--);}
}
/****************************************************************************
* 名    称:initial 
* 功    能:系统初始化子程序
****************************************************************************/
void initial (void)
{	
	T2CON=0X07;
	ADCON1 = 0x07;                	//设置RA口全部为普通数字IO口
	TRISA = 0x00;					//RA设置为输出模式
	PORTA = 0X00;					//RA输出低电位
	TRISE2 = 1 ;					//将RMT设置为输入,其它所有IO口设置为输出
	TRISD = 0X00;                  	//RC口全部为输出
	PORTD = 0xFF;              		//先让数码管全部不显示
	TRISC = 0xf0;					//RC高四位为输入,低四位为输出
	PORTC = 0x11;
}
/****************************************************************************
* 名    称:RCV() 
* 功    能:红外扫描译码
****************************************************************************/
void RCV()
{
	if (!RMT)
	{
		CNT1 = 640;   			//4*256*10us  640*16=10。24ms
		CNT2 = 0;				//RCV1
//		delay(10,240);
		do
		{   					// ;先检测引导码的9MS低电平_____┏┓
								// ;每一个循环16US
			if (RMT)
				CNT2 = CNT2++;
			if (!RMT)
				CNT2 = 0;
			if (CNT2_2)    	//高电平大于8*10US=80US则为有效高电平,
				break;     	//否则是一些干扰信号16*4=64us
		}
		while (CNT1--);    	//低电平大于4*256*10US=10.24MS则是错误脉冲
		//RCV2
		if (CNT2_2 && (0 < CNT1) && (CNT1 < 320)) //;低电平小于2*256*10US=5.12MS┏┒____//320*16=5。12ms则是错误脉冲
		{                                       
			CNT1 = 480;                            //;3*256*10us  480*16=7.68
//			delay(7,680);
			CNT2 = 0;
			//RCV3          //;每一个循环16US
			do
			{
				if (!RMT)
					CNT2 = CNT2++;
				if (RMT)
					CNT2 = 0;
				if (CNT2_2)                       // 低电平大于8*10US=80US则为有效低电平,否则是一些干扰信号
					break;                         //RCV4,否则是一些干扰信号16*4=64us
				// 高电平大于3*256*10US=7.68MS则是错误的
			}
			while (CNT1--);

			//RCV4

			if (CNT2_2 && (0 < CNT1) && (CNT1 < 320)) //高电平小于1*256*10US=2.56MS则是错误的
			{                                 //480-320=160 *16= 2.56ms
				CNT3 = 32;                   //接收数据共32位,16位用户码,8位控制码加8位控制码的反码
				//RCV5
				do
				{
					CNT2 = 0;
					CNT0 = 86;                  //低电平大于256-170=86*10US=860US错误 86*10 __┌┐
					CNT4 = 200;                 //高电平大于256-56=200*10US=2MS错误   200*10
					//RCV5_HI
					do
					{                    //;每一个循环10US
						if (RMT)
							CNT2 = CNT2++;
						if (!RMT)
							CNT2 = 0;
						if (CNT2_3)         //;高电平大于8*10US=80US则为有效高电平
							break;          //RCV6否则是一些干扰信号16*4=64us

						//;低电平大于860US则是错误的
					}
					while (CNT0--);
					//CV6
					if ((CNT0 == 0) || (CNT2_3 == 0)) break;

					CNT2 = 0;
					//RCV6_LO
					do
					{                    //┌┐__
						if (!RMT)
							CNT2 = CNT2++;
						if (RMT)
							CNT2 = 0;
						if (CNT2_3)    //低电平大于10*8US=80US则是有效低电平
							break ;      // COMPARE 否则是一些干扰信号16*4=64us
					}
					while (CNT4--); //高电平大于256-56=200*10US=2MS错误

					if ((CNT4 == 0) || (CNT2_3 == 0)) break;

					//OMPARE
					CNT0 = (86 - CNT0) + (200 - CNT4) ;
					//;减CNT0的值  等于实际低电平计数值
					// ;减CNT4的值  等于实际高电平计数值
					// ;将高低电平的计数加在一起并存入CNT0,通过比较高低电平总的时间来确定是1还是0
					// ;总的值大于255(即时间大于255*10US=2.55MS)则错误  255*10=2.55
					// ;总的时间小于70*10US=700US则是错误的            70*10=700
					if (( (70 < CNT0) && (CNT0 < 130)) || ((160 < CNT0) && (CNT0 < 230) ) ) // ;130*10=1.3MS
					{
						if ((70 < CNT0) && (CNT0 < 130))
							//COMPARE_H   // ;时间大于1.3MS转去确定是否1
							Bitin = 0;           //;时间在700US-1.3MS之间则是0
						else // if (160> 1;      //;将每一位移入相应寄存器
						if (Bitin)
							bitset ( myCsra. Csra[3], 7);
						else bitclr ( myCsra. Csra[3], 7);
					}
					else break;
				}
				while (CNT3--); //;是否接收完32位
				CSR3 = myCsra. Csra[0];
				CSR2 = myCsra. Csra[1];
				CSR1 = myCsra. Csra[2];
				CSR0 = myCsra. Csra[3];
				CSR2A = ~CSR0;  //;比较键码的反码取反后是否等于键码
				//;不等于则接收到的是错误的信息
				// 将键码送显示
			}

		}

	}

}

/****************************************************************************
* 名    称:display() 
* 功    能:数码管显示
****************************************************************************/
void display()
{
	int i, j;                  	//定义查表变量
	i = CSR1 & 0x0f;
	PORTD = table[i];         	//送D口显示,并加上小数点
	PORTA = 0x10;
	NOP();                   	//延长一段时间,保证亮度
	for (j = 0;j < 50;j++);

	i = CSR1 & 0xf0;
	i = i >> 4;					//向左移四位
	PORTD = table[i];         	//送D口显示
	PORTA = 0x20;
	NOP();                 		//延长一段时间,保证亮度
	for (j = 0;j < 50;j++);

}

/****************************************************************************
* 名    称:main
* 功    能:主程序
****************************************************************************/
void main(void)
{
	initial ();                //系统初始化子程序
	while (1)
	{
		RCV();               //遥控接收程序
		display();           //解码显示程序
	}
}

全部回复(1)
正序查看
倒序查看
2016-06-21 10:34
帮你顶,来大神解答哇~
0
回复