求一个简单的单片机红外遥控控制led灯的收发程序

求一个简单的单片机红外遥控控制led灯的收发程序,第1张

这是我以前写的红外遥控器。。。你看看,有帮助的

#include <AT89X51.h>

static bit

OP //红外发射管的亮灭

static unsigned int

count //延时计数器

static unsigned int endcount//终止延时计数

static unsigned char

flag //红外发送标志

char

iraddr1 //十六位地址的第一个字节

char iraddr2 //十六位地址的第二个字节

void SendIRdata(char p_irdata)

void delay()

void main(void)

{

count = 0

flag = 0

OP = 0

P3_4 = 0

EA = 1//允许CPU中断

TMOD = 0x11//设定时器0和1为16位模式1

ET0 = 1//定时器0中断允许

TH0 = 0xFF

TL0 = 0xE6//设定时值0为38K 也就是每隔26us中断一次

TR0 = 1//开始计数

iraddr1=3

iraddr2=252

do{

delay()

SendIRdata(12)

}while(1)

}

//定时器0中断处理

void

timeint(void) interrupt

1

{

TH0=0xFF

TL0=0xE6//设定时值为38K 也就是每隔26us中断一次

count++

if (flag==1)

{

OP=~OP

}

else

{

OP = 0

}

P3_4 = OP

}

void

SendIRdata(char p_irdata)

{

int i

char irdata=p_irdata

//发送9ms的起始码

endcount=223

flag=1

count=0

do{}while(count<endcount)

//发送4.5ms的结果码

endcount=117

flag=0

count=0

do{}while(count<endcount)

//发送十六位地址的前八位

irdata=iraddr1

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

{

//先发送0.56ms的38KHZ红外波(即编码中0.56ms的低电平)

endcount=10

flag=1

count=0

do{}while(count<endcount)

//停止发送红外信号(即编码中的高电平

if(irdata-(irdata/2)*2)

//判断二进制数个位为1还是0

{

endcount=41

//1为宽的高电平

}

else

{

endcount=15 //0为窄的高电平

}

flag=0

count=0

do{}while(count<endcount)

irdata=irdata>>1

}

//发送十六位地址的后八位

irdata=iraddr2

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

{

endcount=10

flag=1

count=0

do{}while(count<endcount)

if(irdata-(irdata/2)*2)

{

endcount=41

}

else

{

endcount=15

}

flag=0

count=0

do{}while(count<endcount)

irdata=irdata>>1

}

//发送八位数据

irdata=p_irdata

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

{

endcount=10

flag=1

count=0

do{}while(count<endcount)

if(irdata-(irdata/2)*2)

{

endcount=41

}

else

{

endcount=15

}

flag=0

count=0

do{}while(count<endcount)

irdata=irdata>>1

}

//发送八位数据的反码

irdata=~p_irdata

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

{

endcount=10

flag=1

count=0

do{}while(count<endcount)

if(irdata-(irdata/2)*2)

{

endcount=41

}

else

{

endcount=15

}

flag=0

count=0

do{}while(count<endcount)

irdata=irdata>>1

}

endcount=10

flag=1

count=0

do{}while(count<endcount)

flag=0

}

void delay()

{

int i,j

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

{

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

{

}

}

}

#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//重新开启外部中断

}


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

原文地址: http://outofmemory.cn/yw/11955628.html

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

发表评论

登录后才能评论

评论列表(0条)

保存