日期:2025-07-16 11:18:12 人气:1

    A+
热门评论

急需基于51单片机的红外遥控开关的设计原理图和程序(c语言版)

/*------------------------------------------------*/ #include //包含头文件,一般情况不需要改动,头文件包含特殊功能寄存器的定义 sbit IR=P3^2; //红外接口标志 #define DataPort P0 //定义数据端口 程序中遇到DataPort 则用P0 替换 sbit DUAN=P2^6;//定义锁存使能端口 段锁存 sbit WEI=P2^7;// 位锁存 /*------------------------------------------------ 全局变量声明 ------------------------------------------------*/ unsigned char code dofly_DuanMa[16]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71};// 显示段码值0~F unsigned char code dofly_WeiMa[]={0xfe,0xfd,0xfb,0xf7,0xef,0xdf,0xbf,0x7f};//分别对应相应的数码管点亮,即位码 unsigned char TempData[8]; //存储显示值的全局变量 unsigned char irtime;//红外用全局变量 bit irpro_ok,irok; unsigned char IRcord[4]; unsigned char irdata[33]; /*------------------------------------------------ 函数声明 ------------------------------------------------*/ void Ir_work(void); void Ircordpro(void); /*------------------------------------------------ 显示函数,用于动态扫描数码管 输入参数 FirstBit 表示需要显示的第一位,如赋值2表示从第三个数码管开始显示 如输入0表示从第一个显示。 Num表示需要显示的位数,如需要显示99两位数值则该值输入2 ------------------------------------------------*/ void Display(unsigned char FirstBit,unsigned char Num) { static unsigned char i=0; DataPort=0; //清空数据,防止有交替重影 DUAN=1; //段锁存 DUAN=0; DataPort=dofly_WeiMa[i+FirstBit]; //取位码 WEI=1; //位锁存 WEI=0; DataPort=TempData[i]; //取显示数据,段码 DUAN=1; //段锁存 DUAN=0; i++; if(i==Num) i=0; } /*------------------------------------------------ 定时器0中断处理 ------------------------------------------------*/ void tim0_isr (void) interrupt 1 using 1 { irtime++; //用于计数2个下降沿之间的时间 } /*------------------------------------------------ 定时器中断子程序 ------------------------------------------------*/ void Timer1_isr(void) interrupt 3 { TH1=(65536-2000)/256; //重新赋值 2ms TL1=(65536-2000)%256; Display(0,8); // 调用数码管扫描 } /*------------------------------------------------ 外部中断0中断处理 ------------------------------------------------*/ void EX0_ISR (void) interrupt 0 //外部中断0服务函数 { static unsigned char i; //接收红外信号处理 static bit startflag; //是否开始处理标志位 if(startflag) { if(irtime=33)//引导码 TC9012的头码,9ms+4.5ms i=0; irdata[i]=irtime;//存储每个电平的持续时间,用于以后判断是0还是1 irtime=0; i++; if(i==33) { irok=1; i=0; } } else { irtime=0; startflag=1; } } /*------------------------------------------------ 定时器0初始化 ------------------------------------------------*/ void TIM0init(void)//定时器0初始化 { TMOD=0x02;//定时器0工作方式2,TH0是重装值,TL0是初值 TH0=0x00; //重载值 TL0=0x00; //初始化值 ET0=1; //开中断 TR0=1; } /*------------------------------------------------ 定时器初始化子程序 ------------------------------------------------*/ void Init_Timer1(void) { TMOD |= 0x01; //使用模式1,16位定时器,使用"|"符号可以在使用多个定时器时不受影响 //TH1=0x00; //给定初值 //TL1=0x00; EA=1; //总中断打开 ET1=1; //定时器中断打开 TR1=1; //定时器开关打开 } /*------------------------------------------------ 外部中断0初始化 ------------------------------------------------*/ void EX0init(void) { IT0 = 1; //指定外部中断0下降沿触发,INT0 (P3.2) EX0 = 1; //使能外部中断 EA = 1; //开总中断 } /*------------------------------------------------ 键值处理 ------------------------------------------------*/ void Ir_work(void)//红外键值散转程序 { TempData[0]=dofly_DuanMa[IRcord[0]/16]; TempData[1]=dofly_DuanMa[IRcord[0]%16]; TempData[2]=dofly_DuanMa[IRcord[1]/16]; TempData[3]=dofly_DuanMa[IRcord[1]%16]; TempData[4]=dofly_DuanMa[IRcord[2]/16]; TempData[5]=dofly_DuanMa[IRcord[2]%16]; TempData[6]=dofly_DuanMa[IRcord[3]/16]; TempData[7]=dofly_DuanMa[IRcord[3]%16]; //Display(0,8); // 调用数码管扫描 irpro_ok=0;//处理完成标志 } /*------------------------------------------------ 红外码值处理 ------------------------------------------------*/ void Ircordpro(void)//红外码值处理函数 { unsigned char i, j, k; unsigned char cord,value; k=1; for(i=0;i<4;i++) //处理4个字节 { for(j=1;j<=8;j++) //处理1个字节8位 { cord=irdata[k]; if(cord>7)//大于某值为1,这个和晶振有绝对关系,这里使用12M计算,此值可以有一定误差 value|=0x80; if(j<8) { value>>=1; } k++; } IRcord[i]=value; value=0; } irpro_ok=1;//处理完毕标志位置1 } /*------------------------------------------------ 主函数 ------------------------------------------------*/ void main(void) { EX0init(); //初始化外部中断 TIM0init();//初始化定时器 Init_Timer1(); while(1)//主循环 { if(irok) //如果接收好了进行红外处理 { Ircordpro(); irok=0; } if(irpro_ok) //如果处理好后进行工作处理,如按对应的按键后显示对应的数字等 { Ir_work(); } } } 51P3^2是外部中断,红外接收管接这个引脚就能接收到数据然后显示在数码管上

阅读全文

基于51单片机红外遥控代码(C语言)

以下文件是51单片机实现遥控解码,通过数码管显示键码的程序,P0口驱动数码管段选,p2.6和p2.7为数码管位选,接收头连到P3.2口。此程序以通过验证,可以直接编译使用,另外还有一个继电器和蜂鸣器的控制,不用可以屏蔽掉。 ;******************************************************************************** ;* 描述: * ;* 遥控键值读取器 * ;* 数码管显示, P0口为数码管的数据口 * ;* * ;******************************************************************************** ;遥控键值解码-数码管显示 * ;********************************************************************************/ #include #include void IR_SHOW(); void delay(unsigned char x);//x*0.14MS void delay1(unsigned char ms); void beep(); sbit IRIN = P3^2; sbit BEEP = P3^7; sbit RELAY= P1^3; sbit GEWEI= P2^7; sbit SHIWEI= P2^6; unsigned char IRCOM[8]; unsigned char code table[16] = {0xC0,0xF9,0xA4,0xB0,0x99,0x92,0x82,0xF8,0x80,0x90,0x88,0x83,0xc6,0xa1,0x86,0x8e}; main() { IE = 0x81; //允许总中断中断,使能 INT0 外部中断 TCON = 0x1; //触发方式为脉冲负边沿触发 delay(1); IRIN=1; BEEP=1; RELAY=1; for(;;) { IR_SHOW(); } } //end main void IR_IN() interrupt 0 using 0 { unsigned char i,j,k,N=0; EA = 0; I1: for (i=0;i<4;i++) { if (IRIN==0) break; if (i==3) {EA =1;return;} } delay(20); if (IRIN==1) goto I1; //确认IR信号出现 while (!IRIN) //等 IR 变为高电平 {delay(1);} for (j=0;j<4;j++) { for (k=0;k<8;k++) { while (IRIN) //等 IR 变为低电平 {delay(1);} while (!IRIN) //等 IR 变为高电平 {delay(1);} while (IRIN) //计算IR高电平时长 { delay(1); N++; if (N>=30) {EA=1;return;} } IRCOM[j]=IRCOM[j] >> 1; if (N>=8) {IRCOM[j] = IRCOM[j] | 0x80;} N=0; }//end for k }//end for j if (IRCOM[2]!=~IRCOM[3]) {EA=1;return;} IRCOM[5]=IRCOM[2] & 0x0F; IRCOM[6]=IRCOM[2] & 0xF0; IRCOM[6]=IRCOM[6] >> 4; beep(); EA = 1; } void IR_SHOW() { P0 = table[IRCOM[5]]; GEWEI = 0; SHIWEI = 1; delay1(4); P0 = table[IRCOM[6]]; SHIWEI = 0; GEWEI = 1; delay1(4); } void beep() { unsigned char i; for (i=0;i<100;i++) { delay(5); BEEP=!BEEP; } BEEP=1; } void delay(unsigned char x)//x*0.14MS { unsigned char i; while(x--) { for (i = 0; i<13; i++) {} } } void delay1(unsigned char ms) { unsigned char i; while(ms--) { for(i = 0; i<120; i++) { _nop_(); _nop_(); _nop_(); _nop_(); } } }

阅读全文