51单片机红外遥控程序是什么?

51单片机红外遥控程序是什么?,第1张

#include<reg52.h>

#include<intrins.h>

#define uchar unsigned char

#define uint unsigned int

sbit lcden = P2^7

sbit lcdrs = P2^6

sbit lcdwr = P2^5

sbit IR = P3^2

uchar IRCOM[6]//数组,用于存储红外编码

uchar code table1[] = "remote control"

uchar code table2[] = "CODE:"

void delayms(uchar x)// 延时x*0.14ms

{

uchar i

while(x--)

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

}

void delay(uchar x) //延时xms

{

uchar i,j

for(i=xi>0i--)

for(j=110j>0j--)

}

/****************************LCD部分***********************************************/

void write_com(uchar com)

{

lcden = 0

lcdrs = 0

lcdwr = 0

P0 = com

delay(5)

lcden = 1

delay(5)

lcden = 0 //别忘了lcden拉低

}

void write_date(uchar date)

{

lcden = 0

lcdrs = 1

lcdwr = 0

P0 = date

delay(5)

lcden = 1

delay(5)

lcden = 0

}

void lcd_init(void)

{

lcden = 0

lcdrs = 0

lcdwr = 0

delay(5)

write_com(0x38)

write_com(0x0c)

write_com(0x06)

write_com(0x01)

}

/*****************main()************************/

void main(void)

{

uchar count=0

IR = 1

lcd_init()

write_com(0x80)

while(table1[count]!='\0')

{

write_date(table1[count])

count++

delay(5)

}

count = 0

write_com(0x80+0x40)

while(table2[count]!='\0')

{

write_date(table2[count])

count++

delay(5)

}

IE = 0x81//开中断

TCON = 0x01//脉冲负边沿触发

while(1)

}

/*********************红外中断**************************/

void IR_time() interrupt 0

{

uchar i,j,TimeNum=0//TimeNum用来计IR高电平次数 从而判断是0还是1

EX0 = 0//关闭中断

delayms(5)

if(1 == IR)

{

EX0 = 1

return

}

while(!IR) //跳过9ms前导低电平

delayms(1)

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

{

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

{

while(IR) //跳过4.5ms的前导高电平

delayms(1)

while(!IR) //跳过0.56ms的低电平

delayms(1)

while(IR)

{

TimeNum++//计时高电平时间从而判断读取的是0还是1

delayms(1)

}

if(TimeNum>=30)//按键按下时间过长 跳过

{

EX0 = 1

return

}

IRCOM[i] = IRCOM[i]>>1

if(TimeNum >= 8) //8*0.14ms 这时读取的是1;

{

IRCOM[i] = IRCOM[i]|0x80

}

TimeNum = 0

}

}

if(IRCOM[2]!=~IRCOM[3])//判断八位数据和八位数据反码是否相等

{

EX0 = 1

return

}

IRCOM[4] = IRCOM[2]&0x0f//取低四位

IRCOM[5] = IRCOM[2]>>4 //IRCOM[5]取IRCOM[2]高四位

if(IRCOM[4] >9) //转换成字符

{

IRCOM[4] = IRCOM[4] + 0x37

}

else

IRCOM[4] = IRCOM[4] + 0x30

if(IRCOM[5] >9)

{

IRCOM[5] = IRCOM[5] + 0x37

}

else

IRCOM[5] = IRCOM[5] + 0x30

delay(5)

write_com(0x80 + 0x40 + 5)

write_date(IRCOM[5])

write_date(IRCOM[4])

EX0 = 1//重新开启外部中断

}

程序太长,须仔细研究。

#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

}

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


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

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

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

发表评论

登录后才能评论

评论列表(0条)

    保存