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

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

以下文件是51单片机实现遥控解码,通过数码管显示键码的程序,P0口驱动衫春数巧斗码管段选,p2.6和p2.7为数码管位选,接收头连到P3.2口。此程序以通过验证,可以直接编译使用,另外还有一个继电器和蜂鸣器的控制,不用可以屏蔽掉。

********************************************************************************

* 描述: *

* 遥控键值读取器*

* 数码管显示, P0口为数码管的数据口 *

* *

********************************************************************************

遥控键值解码-数码管显示*

********************************************************************************/

#include <reg51.h>

#include <intrins.h>

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=0i<4i++)

{

if (IRIN==0) break

if (i==3) {EA =1return}

}

delay(20)

if (IRIN==1) goto I1 //确认IR信号出现

while (!IRIN)//等 IR 变为高电平

{delay(1)}

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

{

for (k=0k<8k++)

{

while (IRIN)//等 IR 变为低电平

{delay(1)}

while (!IRIN) //等 IR 变或宽耐为高电平

{delay(1)}

while (IRIN) //计算IR高电平时长

{

delay(1)

N++

if (N>=30) {EA=1return}

}

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=1return}

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=0i<100i++)

{

delay(5)

BEEP=!BEEP

}

BEEP=1

}

void delay(unsigned char x)//x*0.14MS

{

unsigned char i

while(x--)

{

for (i = 0i<13i++) {}

}

}

void delay1(unsigned char ms)

{

unsigned char i

while(ms--)

{

for(i = 0i<120i++)

{

_nop_()

_nop_()

_nop_()

_nop_()

}

}

}

程序太长,须仔细研究。

#define main_GLOBALS

#include <reg51.h>

#include "main.h"

#include "SAA3010.h"

unsigned char counter

unsigned char temp

sbit P2_0 = 0xA0

sbit P2_1 = 0xA1

sbit P2_2 = 0xA2

sbit P2_3 = 0xA3

void decode_init(void)

{

load_code_detected=0

repeat_code_detected=0

decode_error=0

temp1=0

temp2=0

temp3=0

temp4=0

TH1=0

TL1=0

TR1=0

}

void main(void)

{  

EX0=1

IT0=1

TMOD=0x11

ET0=1

TH0=128

TL0=0

TR0=1

P0=0

TH1=0

TL1=0

decode_init()

EA=1

counter=0

data_available=0

while(1)

{

if(data_available==1)

{

            if (key_code==01) //display "1"

            {

P2_0=0 //选中四个数码管  

P2_1=0  

P2_2=0 

P2_3=0   

P0=0xf9 

            }

            if (key_code==0x02) //display "2"

            {

P2_0=0 //选中四个数码管  

P2_1=0  

P2_2=0 

P2_3=0   

P0=0xa4 

            }

  则手          if (key_code==0x03) //display "3"

            {

P2_0=0 //选中四个数码管  

P2_1=0  

P2_2=0 

P2_3=0   

P0=0xb0 

            }

            if (key_code==0x04) //display "4"

            {

P2_0=0 //选中四个数码管  

P2_1=0  

P2_2=0 

P2_3=0  绝如 

P0=0x99 

            }

            if (key_code==0x05) //display "5"

            {

P2_0=0 //选中四个数码管  

P2_1=0  

P2_2=0 

P2_3=0   

P0=0x92 

            }

            if (key_code==0x06) //display "6"

            {

P2_0=0 //选中四个数码管  

P2_1=0  

P2_2=0 

P2_3=0   

P0=0x82 

            }

            if (key_code==0x07) //display "7"

            {

P2_0=0 //选中四个数码管  

P2_1=0  

P2_2=0 

P2_3=0   

P0=0xf8

            }

            if (key_code==0x08) //display "8"

            {

P2_0=0 //选中四个数码管  

P2_1=0  

P2_2=0 

P2_3=0   

P0=0x80 

            }

            if (key_code==0x09) //display "9"

            {

P2_0=0 //选中四个数码管  

P2_1=0  

P2_2=0 

P2_3=0   

P0=0x90 

            }

            if (key_code==0x00) //display "0"

            {

P2_0=0 //选中四个数码管  

P2_1=0  

P2_2=0 

P2_3=0   

P0=0xc0 

            }

data_available=0

}

}

}

//**********************************************************************************************************************

void key_isr(void) interrupt 0

{

EX0=0                                 // 立即关闭外并盯启部中断,转为查询方式解码

led=0                                 // 开LED表示收到红外信号

    temp=SAA3010_decode()   // 解码

if(temp==1) goto key_isr_exit

counter=0

key_isr_exit:

decode_init()

led=1

EX0=1

}

void Timer0_isr(void) interrupt 1

{

counter++

if(counter>3)

{

if(led==0) led=1

counter=0

}

ET0=1

}

#define SAA3010_GLOBALS

#include <reg51.h>

#include "SAA3010.h"

#include "main.h"

//===========================================================================================================

// 该函数的作用是每调用一次就在temp1-4组成的32bit长度的最低位上移入

// 一个0或者1,数据由bitdata确定

void SAA3010_cycle_data(unsigned char bitdata)

{

temp4=temp4<<1

if((temp3&0x80)==1) temp4=temp4|0x01

else temp4=temp4&0xfe

temp3=temp3<<1

if((temp2&0x80)==1) temp3=temp3|0x01

else temp3=temp3&0xfe

temp2=temp2<<1

if((temp1&0x80)==1) temp2=temp2|0x01

else temp2=temp2&0xfe

temp1=temp1<<1

if(bitdata==1) temp1=temp1|0x01

else temp1=temp1&0xfe

}

//===========================================================================================================

// 解码出错返回1,对则返回0

unsigned char SAA3010_decode(void)

{

//-----------------------------------------------------------------------------------------------------------

unsigned char count=0

TR1=1                                 // 启动计时

while(1)

{

while(ir_receive==0)                  // 等待电平变高,不需要超时监测

TR1=0                                 // 高电平(对发射电路而言)测试结束

high_level_time=TH1*256+TL1           // 记录高电平的数据

//-----------------------------------------------------------------------------------------------------------

TH1=0 TL1=0 TR1=1                  // 启动对低电平的测试

//-----------------------------------------------------------------------------------------------------------

// 处理低电平

if((high_level_time<750)||(high_level_time>1800)) return 1    // 不是合格的电平

if((high_level_time>750)&&(high_level_time<1000)){SAA3010_cycle_data(0)count+=1} // 移入一个0

if((high_level_time>1500)&&(high_level_time<1800)) {SAA3010_cycle_data(0)SAA3010_cycle_data(0)count+=2} // 移入两个0

while(ir_receive==1)                   // 等待电平变低

{

if(TH1>0x08) break                // 高电平超时,正常情况下是测试结束,异常时则是出错

}

       

TR1=0                                 // 低电平(对发射电路而言)测试结束

if(TH1>0x08) {break}

low_level_time=TH1*256+TL1            // 保存低电平的数据

TH1=0 TL1=0 TR1=1  // 为增加计时的准确性,数据的处理都是在计时过程里

//-----------------------------------------------------------------------------------------------------------

// 处理高电平

if((low_level_time<750)||(low_level_time>1800)) return 1    // 不是合格的电平

if((low_level_time>750)&&(low_level_time<1000)) {SAA3010_cycle_data(1) count+=1} // 移入一个0

if((low_level_time>1500)&&(low_level_time<1800)) {SAA3010_cycle_data(1) SAA3010_cycle_data(1)count+=2} // 移入两个0

}                           

if(count==26) {SAA3010_cycle_data(1) count++}

if(count!=27) return 1

led=0

// 提取按健信息

key_code=0

if((temp1>>1)&0x01) key_code=key_code|0x01

else key_code=key_code&0xfe

if((temp1>>3)&0x01) key_code=key_code|0x02

else key_code=key_code&0xfd

if((temp1>>5)&0x01) key_code=key_code|0x04

else key_code=key_code&0xfb

if((temp1>>7)&0x01) key_code=key_code|0x08

else key_code=key_code&0xf7

if((temp2>>1)&0x01) key_code=key_code|0x10

else key_code=key_code&0xef

if((temp2>>3)&0x01) key_code=key_code|0x20

else key_code=key_code&0xdf

// 提取系统信息

sys_code=0

if((temp2>>5)&0x01) sys_code=sys_code|0x01

else sys_code=sys_code&0xfe

if((temp2>>7)&0x01) sys_code=sys_code|0x02

else sys_code=sys_code&0xfd

if((temp3>>1)&0x01) sys_code=sys_code|0x04

else sys_code=sys_code&0xfb

if((temp3>>3)&0x01) sys_code=sys_code|0x08

else sys_code=sys_code&0xf7

if((temp3>>5)&0x01) sys_code=sys_code|0x10

else sys_code=sys_code&0xef

if((temp3>>7)&0x01) sys_code=sys_code|0x20

else sys_code=sys_code&0xdf

data_available=1

return 0

}

//===========================================================================================================

给你一个我编的红外解码的程序,这个程序会将接收到的红外编码中的8位码通过串口发送到上位机,你可以通过串口调试助手来看看,程序是正确的,希望对你有参考价值。 ////////////////////////////////////////////////////////////////// //////////////////////////yorkWorldDream//////////////////////搭咐/// ///////////////////////////////////////////////////////////////// #include"reg52.h" #define uchar unsigned char #define uint unsigned int  //tc9012 uchar flag=0//是否接到起始位标志 未接到为0 接到为1 uchar traflag=0//翻译是否完成标记 完成为1 uchar rec[33]//接收遥控器发送的所有数据 用来记录两个下降沿之间的时间 uchar recok=0//是否接收完一帧数据标记 接收完为1 uchar sendok=0//是否发送完毕标记 发送完成为1 uchar num=0//变相记录时间   uchar n=0//rec[]中的数组定位 void timerinit()//定时器0初始化    void ruptinit()//外部中断0初始化   void tradata()//一帧数据的翻译 即把时间记录转换成0/1 void send()//把收到的数据发给上位机    void delay()//////////////////////////定时器 中断初始化///////////////////////////////// void timerinit()//定时器0 {  TMOD=0x02//定时器0使用方式2  TH0=0x00 TL0=0x00 EA=1 ET0=1//定时器中断开   TR0=1//计时开     } void ruptinit()//外部中断0 {  EA=1 EX0=1//外部中断开      IT0=1//下降沿触发 0是电平触发   } ////////////////////////////定时器 中断函数////////////////////////////// void timer() interrupt 1 //系统从0x00记到0xff 每记一次时间大概为1us 记256次 即256us中断一次 {  num++//num记录的是256us的个数 总时间=num*256us } void rupt() interrupt 0   //外部中断0 当遇到下降沿时触发    {  if(flag==1)//flag为1 说明收到了起始位 接下来要开始进行记录了     {   if(num>32)//时间为32*256us=8.2ms是整个起始位的时间      { n=0 }   rec[n]=num//记录两个下降沿之间的num值 这样也就相当于记录了其间的时间   num=0  n++  if(n==33)//因为前面是n++ 所以当n=33时 数组已经从0记到了32 已经记满了   {    recok=1//标记 接收一帧数据完成         n=0      }    }  else//首次得到下降沿到达这里 使flag变1 用来说明收到了起始位  {    flag=1 } } /////////////////////////////时间翻译函数/////////////////////////////////////// void tradata()//一帧数据的翻译 即把时间记录转换成0/1 {  uchar i for(i=1i/0的数据时间是num=4.4 1的数据时间是num=8.8   {     //记住要从rec[1]开始 因为rec[0]记录的是引导码的num值    if(rec[i]>6)//使用6做中间值 小于则为0 大于为1 用0/1替换rec中的数据 这样就进行了翻译   { rec[i]='1' }//因为要以字符串发送 所以这里用字符形式    else    rec[i]='0'    }  traflag=1//翻译完成标记  } /////////////////////////////发送数据函数//////////////////////////////////// void send()//把收到的数据发送给上位机 具体细节不懂看串口通信 mcu to pc {   uchar i TMOD=0x20 TH1=0xfd TL1=0xfd TR1=1 SM0=0 SM1=1 REN=1 for(i=25i/选择要发送出去的数据 这里是从25开始发送的     {  SBUF=rec[i] while(!TI) TI=0 }  sendok=1}               搏燃                               //////////////////////////////////////////////////////////////////////// void delay()//1ms {  unsigned char a,b,c    for(c=1c>0c--)         for(b=142b>0b--)             for(a=2a>0a--)} void main() {  timerinit()//定时器0初始化     ruptinit()//外部中断0初始化    while(1)  {   if(recok==1)//接收一帧数据完成      {    P1=0xfe//灯亮一下 为了指示是否收到了数据       tradata()//翻译数据     }   delay()  if(traflag==1)//翻译完成      {    send()//发送       基枝虚   }   delay()  if(sendok==1)//发送完成       {    flag=0   traflag=0   recok=0   sendok=0   P1=0xff   timerinit()   ruptinit()  }      //全部恢复初始    }


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

原文地址:https://54852.com/yw/12374867.html

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

发表评论

登录后才能评论

评论列表(0条)

    保存