/*此程序是针对uPD6121系列遥控器的取码程序,解码值在Im[2]中,当IrOK=1时解码有效*/ /******************************************************************************/ /* 项目名称 : TX-1C扩展板 红外遥控器控舵机 */ /* 主控芯片 : STC89C52 */ /* 文件名称 : Inf_HelmMotor */ /* 文件功能 : 主函数 */ /* 文件版权 : 天祥电子 */ /* 文件版本 : */ /******************************************************************************/ /**********************************包含头文件**********************************/ #include /************************************宏定义************************************/ #define uchar unsigned char #define Imax 14000 //此处为晶振为11.0592时的取值, #define Imin 8000 //如用其它频率的晶振时, #define Inum1 1450 //要改变相应的取值。 #define Inum2 700 #define Inum3 3000 /************************************位定义************************************/ sbit dula = P2^6; sbit wela = P2^7; sbit pwm = P1^7 ; //PWM信号输出 /********************************定义变量和数组********************************/ uchar code table[] = {0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07, 0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71}; //数码管段码 uchar Im[4] = {0x00,0x00,0x00,0x00}; uchar f; uchar IrOK; uchar jd; //角度标识 uchar count; //0.5ms次数标识 unsigned long m,Tc; /******************************************************************************/ /* 函数名称 : delay */ /* 函数描述 : 延时函数 */ /* 输入参数 : 无 */ /* 参数描述 : 无 */ /* 返回值 : 无 */ /******************************************************************************/ void delay(uchar i) { uchar j,k; for(j = i;j > 0;j--) { for(k = 125;k > 0;k--); } } /******************************************************************************/ /* 函数名称 : display */ /* 函数描述 : 显示函数函数 */ /* 输入参数 : 无 */ /* 参数描述 : 无 */ /* 返回值 : 无 */ /******************************************************************************/ void display(void) { unsigned char bai,shi,ge; switch(jd) //根据角度标识显示相应的数值 { case 1: //为1,角度为0,前3个数码管显示000 bai = 0; shi = 0; ge = 0; break; case 2: //为2,角度为45,前3个数码管显示045 bai = 0; shi = 4; ge = 5; break; case 3: //为3,角度为90,前3个数码管显示090 bai = 0; shi = 9; ge = 0; break; case 4: //为1,角度为135,前3个数码管显示135 bai = 1; shi = 3; ge = 5; break; case 5: //为5,角度为180,前3个数码管显示180 bai = 1; shi = 8; ge = 0; break; default: break; } dula = 0; P0 = table[bai]; dula = 1; dula = 0; wela = 0; P0 = 0xfe; wela = 1; wela = 0; delay(5); P0 = table[shi]; dula = 1; dula = 0; P0 = 0xfd; wela = 1; wela = 0; delay(5); P0 = table[ge]; dula = 1; dula = 0; P0 = 0xfb; wela = 1; wela = 0; delay(5); } /******************************************************************************/ /* 函数名称 : intersvr1 */ /* 函数描述 : 外部中断解码程序 */ /* 输入参数 : 无 */ /* 参数描述 : 无 */ /* 返回值 : 无 */ /******************************************************************************/ void intersvr1(void) interrupt 2 using 1 { Tc = TH0 * 256 + TL0; //提取中断时间间隔时长 TH0 = 0; TL0 = 0; //定时中断重新置零 if((Tc > Imin) && (Tc < Imax)) { m = 0; f = 1; return; } //找到启始码 if(f == 1) { if(Tc > Inum1 && Tc < Inum3) { Im[m / 8] = Im[m / 8] >> 1 | 0x80; m++; } if(Tc > Inum2 && Tc < Inum1) { Im[m / 8] = Im[m / 8] >> 1; m++; //取码 } if(m == 32) { m = 0; f = 0; if(Im[2] ==~ Im[3]) { IrOK =1 ; } else { IrOK = 0; //取码完成后判断读码是否正确 } } } } /******************************************************************************/ /* 函数名称 : Inf_Dispose */ /* 函数描述 : 红外接收处理函数 */ /* 输入参数 : 无 */ /* 参数描述 : 无 */ /* 返回值 : 无 */ /******************************************************************************/ void Inf_Dispose(void) { if(IrOK == 1) { switch(Im[2]) { case 0x09: //遥控器+键按下 角度加45 jd++; //角度标识加1 count = 0; //按键按下 则20ms周期从新开始 if(jd == 6) { jd = 5; //已经是180度,则保持 } break; case 0x15: //遥控器-键按下 角度减45 jd--; //角度标识减1 count = 0; if(jd == 0) { jd = 1; //已经是0度,则保持 } break; default: break; } IrOK = 0; } } /******************************************************************************/ /* 函数名称 : Time0_Init */ /* 函数描述 : 定时器0初始化函数 */ /* 输入参数 : 无 */ /* 参数描述 : 无 */ /* 返回值 : 无 */ /******************************************************************************/ void Time0_Init() //定时器初始化 { TMOD |= 0x01; //定时器0工作在方式1 IE |= 0x82; TH0 = 0xfe; TL0 = 0x33; //11.0592MZ晶振,0.5ms TR0 = 1; //定时器开始 } /******************************************************************************/ /* 函数名称 : Time0_Int */ /* 函数描述 : 定时器0中断函数 */ /* 输入参数 : 无 */ /* 参数描述 : 无 */ /* 返回值 : 无 */ /******************************************************************************/ void Time0_Int() interrupt 1 //中断程序 { TH0 = 0xfe; //重新赋值 TL0 = 0x33; count++; if(count == jd) //对应的角度输出低电平 { pwm = 0; } if(count == 40) //20ms周期到达后 { pwm = 1; //输出高电平 count = 0; } } /******************************************************************************/ /* 函数名称 : main */ /* 函数描述 : 主函数 */ /* 输入参数 : 无 */ /* 参数描述 : 无 */ /* 返回值 : 无 */ /******************************************************************************/ void main(void) { m = 0; f = 0; EA = 1; IT1 = 1; EX1 = 1; TMOD = 0x11; TH0 = 0; TL0 = 0; TR0 = 1; jd = 1; count = 0; pwm = 0; Time0_Init(); pwm = 1; while(1) { Inf_Dispose(); //红外接收处理 display(); //数码管显示 } } /******************************************************************************/