基于51单片机的红外遥控开关的C 程序

基于51单片机的红外遥控开关的C 程序,第1张

这个简单就是一个解码函灵敏而已!

int jiema()

{

unsigned int data,temp;

RESET:

for( i=0;i<8;i++ ) //9ms

{

delay_nms(1);

if((PIND&0B00000100)==0B00000100 )

goto RESET; //是检测在8毫秒内如果出现高电平就退出解码程序

}

temp = 8000;

while( ( (PIND&0B00000100)==0B00000000 ) && (temp!=0) )

{temp--;}

// 等待45ms高电平的到来,避开9毫秒低电平引导脉冲

// temp--需025us, temp=8000可实现2ms延时,防止干扰脉冲造成的死机。

delay_nus(1804); //45ms

for( j=0;j<4;j++)

{

for( i=0;i<8;i++ )

{

temp = 4000;

while( ((PIND&0B00000100)==0B00000000 ) && (temp!=0) )

{temp--;}

delay_nus(334);

if((PIND&0B00000100)==0B00000100 ) // 检测到高电平1的话说明该位为1,延时1毫秒等待脉冲高电平结束

{

data |= (1<<i); // dataH= ~data dataL= data

delay_nus(379);

}

else data &= ~(1<<i); // 检测到低电平0的话,说明该位为0,继续检测下一位

}

IR_BUF[j]=data;

}

if(IR_BUF[2] = ~IR_BUF[3]) //校验

{

PORTA=IR_BUF[2];

delay_nms(500);

}

#include\x0d\#include\x0d\#define uchar unsigned char\x0d\#define uint unsigned int\x0d\sbit lcden = P2^7;\x0d\sbit lcdrs = P2^6;\x0d\sbit lcdwr = P2^5;\x0d\sbit IR = P3^2;\x0d\uchar IRCOM[6];//数组,用于存储红外编码\x0d\uchar code table1[] = "remote control";\x0d\uchar code table2[] = "CODE:";\x0d\void delayms(uchar x)// 延时x014ms\x0d\{\x0d\uchar i;\x0d\while(x--)\x0d\for(i=0;i//延时xms\x0d\{\x0d\uchar i,j;\x0d\for(i=x;i>0;i--)\x0d\for(j=110;j>0;j--);\x0d\}\x0d\/LCD部分/\x0d\void write_com(uchar com)\x0d\{\x0d\lcden = 0;\x0d\lcdrs = 0;\x0d\lcdwr = 0;\x0d\P0 = com;\x0d\delay(5);\x0d\lcden = 1;\x0d\delay(5);\x0d\lcden = 0;//别忘了lcden拉低\x0d\}\x0d\void write_date(uchar date)\x0d\{\x0d\lcden = 0;\x0d\lcdrs = 1;\x0d\lcdwr = 0;\x0d\P0 = date;\x0d\delay(5);\x0d\lcden = 1;\x0d\delay(5);\x0d\lcden = 0;\x0d\}\x0d\void lcd_init(void)\x0d\{\x0d\lcden = 0;\x0d\lcdrs = 0;\x0d\lcdwr = 0;\x0d\delay(5);\x0d\write_com(0x38);\x0d\write_com(0x0c);\x0d\write_com(0x06);\x0d\write_com(0x01);\x0d\}\x0d\/main()/\x0d\void main(void)\x0d\{\x0d\uchar count=0;\x0d\IR = 1;\x0d\lcd_init();\x0d\write_com(0x80);\x0d\while(table1[count]!='\0')\x0d\{\x0d\write_date(table1[count]);\x0d\count++;\x0d\delay(5);\x0d\}\x0d\count = 0;\x0d\write_com(0x80+0x40);\x0d\while(table2[count]!='\0')\x0d\{\x0d\write_date(table2[count]);\x0d\count++;\x0d\delay(5);\x0d\}\x0d\\x0d\IE = 0x81; //开中断\x0d\TCON = 0x01;//脉冲负边沿触发\x0d\while(1);\x0d\\x0d\}\x0d\/红外中断/\x0d\void IR_time() interrupt 0 \x0d\{\x0d\uchar i,j,TimeNum=0;//TimeNum用来计IR高电平次数 从而判断是0还是1\x0d\EX0 = 0; //关闭中断\x0d\delayms(5);\x0d\if(1 == IR)\x0d\{\x0d\EX0 = 1;\x0d\return;\x0d\}\x0d\while(!IR) //跳过9ms前导低电平\x0d\delayms(1);\x0d\for(i=0;i{\x0d\for(j=0;j{\x0d\while(IR) //跳过45ms的前导高电平\x0d\delayms(1);\x0d\while(!IR) //跳过056ms的低电平\x0d\delayms(1);\x0d\\x0d\while(IR) \x0d\{\x0d\TimeNum++; //计时高电平时间从而判断读取的是0还是1\x0d\delayms(1);\x0d\}\x0d\if(TimeNum>=30)//按键按下时间过长 跳过\x0d\{\x0d\EX0 = 1;\x0d\return;\x0d\}\x0d\IRCOM[i] = IRCOM[i]>>1;\x0d\if(TimeNum >= 8) //8014ms 这时读取的是1;\x0d\{\x0d\IRCOM[i] = IRCOM[i]|0x80;\x0d\}\x0d\TimeNum = 0;\x0d\}\x0d\}\x0d\if(IRCOM[2]!=~IRCOM[3])//判断八位数据和八位数据反码是否相等\x0d\{\x0d\EX0 = 1;\x0d\return;\x0d\}\x0d\IRCOM[4] = IRCOM[2]&0x0f;//取低四位\x0d\IRCOM[5] = IRCOM[2]>>4; //IRCOM[5]取IRCOM[2]高四位\x0d\if(IRCOM[4] > 9) //转换成字符\x0d\{\x0d\IRCOM[4] = IRCOM[4] + 0x37;\x0d\}\x0d\else\x0d\IRCOM[4] = IRCOM[4] + 0x30;\x0d\if(IRCOM[5] > 9)\x0d\{\x0d\IRCOM[5] = IRCOM[5] + 0x37;\x0d\}\x0d\else\x0d\IRCOM[5] = IRCOM[5] + 0x30;\x0d\delay(5);\x0d\write_com(0x80 + 0x40 + 5);\x0d\write_date(IRCOM[5]);\x0d\write_date(IRCOM[4]);\x0d\EX0 = 1; //重新开启外部中断\x0d\}

这是一段把红外遥控接收后用数码管显示出来的程序,你参考一下吧。

程序已经通过编译了。

;遥控器读码程序(晶振为110592),该程序能读出遥控器的控制码,并通过LED显示出来

;OMEN 2005/1/16于TCL

;

A_BIT EQU 20H ;数码管个位数存放内存位置

B_BIT EQU 21H ;数码管十位数存放内存位置

NO_OUT EQU 24H ;最终控制号码存放单元

A_NO EQU 25H ;数码管个位数对应代码存放内存位置

B_NO EQU 26H ;数码管十位数对应代码存放内存位置

;22H,23H为控制码及其反码的存放单元

;<<主程序>>

ORG 0000H

AJMP 0030H

ORG 0003H ;外部中断P32脚INT0入口地址

AJMP INT ;转入外部中断服务子程序(解码程序)

ORG 0030H

AJMP MAIN ;转入主程序

;

MAIN: MOV NO_OUT,#0H

SETB EA ;打开CPU总中断请求

SETB IT0 ;设定INT0的触发方式为脉冲负边沿触发

SETB EX0 ;打开INT0中断请求

LOOP: MOV A,NO_OUT;将按键的键值通过P1口的8个LED显示出来!

CPL A ;由于P1发光二极管显示的是电平的反状态,所以取反

MOV P1,A ;发光二极管显示输出

LCALL DISPLAY;LED数码管显示输出

AJMP LOOP;循环

;<<中断接受遥控程序>>

;以下为进入P32脚外部中断子程序,也就是解码程序

INT:

PUSH ACC

PUSH PSW ;将PSW和ACC推入堆栈保护

CLR EA ;暂时关闭CPU的所有中断请求

MOV R6,#10

SB: LCALL DL865;调用865微秒延时子程序

JB P32,EXIT;延时865微秒后判断P32脚是否出现高电平如果有就退出解码程序

DJNZ R6, SB;重复10次,目的是检测在8650微秒内如果出现高电平就退出解码程序

;以上完成对遥控信号的9000微秒的初始低电平信号的识别。

JNB P32, $ ;等待高电平避开9毫秒低电平引导脉冲

LCALL DL4737 ;延时474毫秒避开45毫秒的结果码

MOV R7,#16;忽略前26位系统识别码

JJJJA:JNB P32,$;等待地址码第一位的高电平信号

LCALL DL865;高电平开始后用865微秒的时间尺去判断信号此时的高低电平状态

MOV C,P32;将P32引脚此时的电平状态0或1存入C中

JNC UUUA;如果为0就跳转到UUUA

LCALL DL1000;检测到高电平1的话延时1毫秒等待脉冲高电平结束

UUUA: DJNZ R7,JJJJA

MOV R1,#22H ;设定22H为起始RAM区

MOV R2,#2;接收从22H到23H的2个内存,用于存放 *** 作码和 *** 作反码

PP: MOV R3,#8;每组数据为8位

JJJJ: JNB P32,$;等待地址码第一位的高电平信号

LCALL DL865;高电平开始后用865微秒的时间尺去判断信号此时的高低电平状态

MOV C,P32;将P32引脚此时的电平状态0或1存入C中

JNC UUU;如果为0就跳转到UUU

LCALL DL1000;检测到高电平1的话延时1毫秒等待脉冲高电平结束

UUU: MOV A,@R1;将R1中地址的给A

RRC A;将C中的值0或1移入A中的最低位

MOV @R1,A;将A中的数暂时存放在R1数值的内存中

DJNZ R3,JJJJ;接收满8位换一个内存

INC R1;对R1中的值加1,换下一个RAM

DJNZ R2,PP ;接收完8位数据码和8位数据反码,存放在22H/23H中

MOV A,22H

CPL A;对22H取反后和23H比较

CJNE A,23H,EXIT;如果不等表示接收数据发生错误,放弃

MOV A,22H

MOV NO_OUT,A

;LCALL EEPROM_C ;清除以前的保存的码

;LCALL DL4737

;LCALL EEPROM_W ;把码存在单片机内部的EEPROM里

;LCALL DL4737

CLR P36;蜂鸣器鸣响-嘀嘀嘀-的声音,表示解码成功

LCALL DL4737

LCALL DL4737

LCALL DL4737

SETB P36;蜂鸣器停止

lcall DL4737

EXIT: SETB EA ;允许中断

POP PSW

POP ACC ;将PSW和ACC推入堆栈保护

RETI ;退出解码子程序

;<<LED数码管显示子程序>>

DISPLAY:

MOV A,NO_OUT ;将NO_OUT分成个位和16位

ANL A,#0FH ;取低四位放在a_bit

MOV A_BIT,A ;个位

MOV A,NO_OUT ;

RR A

RR A

RR A

RR A ;四次移动,把高四位移到低四位

ANL A,#0FH;取高四位放在B_bit

MOV B_BIT,A ;个位在b

MOV DPTR,#NUMTAB ;指定查表启始地址

MOV A,A_BIT ;取个位数

MOVC A,@A+DPTR ;查个位数的7段代码

MOV A_NO,A

MOV A,B_BIT ;取十位数

MOVC A,@A+DPTR ;查十位数的7段代码

MOV B_NO,A

DPLOP:MOV A,A_NO

MOV P0,A ;送出个位的7段代码

;SETB P21;关闭十位显示,防止鬼影

CLR P20 ;开个位显示

LCALL DL40 ;显示4737微秒

SETB P20;关闭个位显示,防止鬼影

MOV A,B_NO

MOV P0,A ;送出十位的7段代码

CLR P21 ;开十位显示

LCALL DL40 ;显示4737微秒

SETB P21;关闭十位显示,防止鬼影

RET

;<<延时程序>>

DL865: MOV R4,#12 ; 109(2R5+4)R4+2延时子程序1,精确延时865微秒

D1: MOV R5,#31

DJNZ R5,$

DJNZ R4,D1

RET

DL4737: MOV R4,#12 ;延时子程序2,精确延时4737微秒

D2: MOV R5,#179

DJNZ R5,$

DJNZ R4,D2

RET

DL1000: MOV R4,#17;延时程序3,精确延时1000微秒

D3: MOV R5,#25

DJNZ R5,$

DJNZ R4,D3

RET

DL40: MOV R4,#1;延时程序4,精确延时40/17微秒

D4: MOV R5,#1

DJNZ R5,$

DJNZ R4,D4

RET

;

;如果是共阳数码管的显示代码 1-F 16个代码

NUMTAB: DB 0C0H,0F9H,0A4H,0B0H,99H,92H,82H,0F8H,80H,90H,88H,83H,0C6H,0A1H,86H,8EH ;STC新板的

END

单片机采用外部中断P33管脚和红外接收头的信号线相连,中断方式为边沿触发方式。并用定时器0计算中断的间隔时间,来区分前导码、二进制的“1”、“0”码。并将8位 *** 作码提取出来在数码管上显示。

// 解码值在Im[2]中,当IrOK=1时解码有效。 

/ 51单片机红外遥控解码程序 /

//用遥控器对准红外接收头,按下遥控器按键,在数码管前两位上就会显示对应按键的编码

#include <reg52h>

#define uchar unsigned char 

sbit dula=P2^6;

sbit wela=P2^7;

uchar code table[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,

                        0x07,0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71};

uchar f;

#define Imax 14000    //此处为晶振为110592时的取值, 

#define Imin 8000    //如用其它频率的晶振时,

#define Inum1 1450    //要改变相应的取值。

#define Inum2 700 

#define Inum3 3000

unsigned char Im[4]={0x00,0x00,0x00,0x00};

uchar show[2]={0,0};

unsigned long m,Tc;

unsigned char IrOK;

void delay(uchar i)

{

  uchar j,k; 

  for(j=i;j>0;j--)

    for(k=125;k>0;k--);

}

void display()

{

   dula=0;

   P0=table[show[0]];

   dula=1;

   dula=0;

   wela=0;

   P0=0xfe;

   wela=1;

   wela=0;

   delay(5);

   P0=table[show[1]];

   dula=1;

   dula=0;

   P0=0xfd;

   wela=1;

   wela=0;

   delay(5);

} //外部中断解码程序

void intersvr1(void) interrupt 2 using 1

{

 Tc=TH0256+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;   //取码完成后判断读码是否正确

     }

               //准备读下一码

   }

}

/演示主程序/

void main(void)

{

    unsigned int  a;

 m=0;

    f=0;

 EA=1;

 IT1=1;EX1=1;

 TMOD=0x11;  

 TH0=0;TL0=0;

 TR0=1;//ET0=1;

 while(1)

 {

       if(IrOK==1) 

  {

      show[1]=Im[2] & 0x0F;     //取键码的低四位

           show[0]=Im[2] >> 4;  

           IrOK=0;

  }

           for(a=100;a>0;a--)

          {

    display();

   }

 }

}

解码程序这个就能实现

以上就是关于基于51单片机的红外遥控开关的C 程序全部的内容,包括:基于51单片机的红外遥控开关的C 程序、51单片机红外遥控程序是什么、红外遥控解码程序等相关内容解答,如果想了解更多相关内容,可以关注我们,你们的支持是我们更新的动力!

欢迎分享,转载请注明来源:内存溢出

原文地址:https://54852.com/zz/9726751.html

(0)
打赏 微信扫一扫微信扫一扫 支付宝扫一扫支付宝扫一扫
上一篇 2023-05-01
下一篇2023-05-01

发表评论

登录后才能评论

评论列表(0条)

    保存