高分请教高人,红外遥控解码程序C语言,要求每一行都解释为什么什么作用。非常感谢!!先给100分,好再加

高分请教高人,红外遥控解码程序C语言,要求每一行都解释为什么什么作用。非常感谢!!先给100分,好再加,第1张

#include <reg52.h> //特殊寄存器头文件

#define c(x) (x*110592/120000) //是晶振值,为计数器计一下所需要的微秒数,120000为12M,110592为11.0592M

sbit Ir_Pin=P3^3 //位声明,把P3.3/外部中断1的状态读到Ir_Pin中

unsigned char code Led_Tab[]={0xC0,0xF9,0xA4,0xB0,0x99,0x92,0x82,

0xf8,0x80,0x90,0x88,0x83,0xC6,0xA1,0x86,0x8E} //共阳极数码显示码0-F.

unsigned char code Led_Sel[]={0xe,0xd,0xb,0x7}//位选编码

unsigned char Led_Buf[4]//显示缓冲区

char Led_Index //位选信号定义

unsigned char Ir_Buf[4]//用于保存解码结果

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

//数码管扫描

timer0() interrupt 1 using 1 //定时器中断零程序

{

TH0=(65536-1000)/256

TL0=(65536-1000)%256 //定时器0设定约1000us中断一次搭搜颤,用于数码管扫描

P0=0xff//数码管初始显示零

P2=Led_Sel[Led_Index] //位选

P0=Led_Tab[Led_Buf[Led_Index]] //段选

if(++Led_Index>3) Led_Index=0 //四个扫描完了,到第一个数码管

}

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

unsigned int Ir_Get_Low()//脉冲为低电平的时间

{

TL1=0

TH1=0 //为定时器1赋初值

TR1=1 //开启定时器1

while(!Ir_Pin &&(TH1&0x80)==0) //判断,如果P3.3口为低电平则执行TR1=0

TR1=0 //知败关闭定时器1

return TH1*256+TL1//返回TH1*256+TL1的值

}

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

unsigned int Ir_Get_High()//脉冲高电平时间

{

TL1=0

TH1=0 //为定时器1赋初漏坦值

TR1=1 //开启定时器1

while(Ir_Pin &&(TH1&0x80)==0) //判断,如果P3.3口为低电平则执行TR1=0

TR1=0//关闭定时器1

return TH1*256+TL1 //返回TH1*256+TL1的值

}

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

main()

{

unsigned int temp

char i,j

Led_Index=1

TMOD=0x11

TL0=(65536-1000)%256

TH0=(65536-1000)/256 //定时器0设定约1000us中断一次,用于数码管扫描

EA=1 //开总中断

ET0=1 //定时计数器0的开放控制位

TR0=1 //定时器0的运行控制位

Led_Buf[0]=0

Led_Buf[1]=0

Led_Buf[2]=0

Led_Buf[3]=0 //显示区设成0

do{

restart:

while(Ir_Pin) //判断P3.3口

temp=Ir_Get_Low() //取脉冲为低电平的时间

if(temp<c(8500) || temp>c(9500)) continue //引导脉冲低电平9000

temp=Ir_Get_High()//取脉冲高电平时间

if(temp<c(4000) || temp>c(5000)) continue //引导脉冲高电平4500

for(i=0i<4i++)//4个字节

for(j=0j<8j++)//每个字节8位

{

temp=Ir_Get_Low()

if(temp<c(200) || temp>c(800)) goto restart //根据编码格式,低电平小于0.2ms大于0.8ms视为无效电平,重新检测

temp=Ir_Get_High()

if(temp<c(200) || temp>c(2000)) goto restart//根据编码格式,低电平小于0.2ms大于2ms视为无效电平,重新检测

Ir_Buf[i]>>=1 //把Ir_Buf[i]右移一位,然后赋值给Ir_Buf[i]

if(temp>c(1120)) Ir_Buf[i]|=0x80//根据编码格式,如果电平大于1.12ms,则把0x80赋值给Ir_Buf[i]

}

Led_Buf[0]=Ir_Buf[2]&0xf

Led_Buf[1]=(Ir_Buf[2]/16)&0xf

Led_Buf[2]=Ir_Buf[3]&0xf

Led_Buf[3]=(Ir_Buf[3]/16)&0xf//显示结果

}while(1)

}

#include <reg51.h>

#include <intrins.h>

#define uchar unsigned char

#define uint unsigned int

sbit IRIN = P3^2 //遥控输入脚

sbit BEEP = P3^7 //蜂鸣器

sbit RELAY= P3^6 //继电器

uchar IR_buf[4]={0x00,0x00,0x00,0x00}//IR_buf[0]、IR_buf[1]为用户码低位、用户码高位接收缓冲区

// IR_buf[2]、IR_buf[3]为键数据码和键数据码反码接收缓冲区

uchar disp_buf[2]={0x10,0x10} //显示缓冲单元,初值为0x10(即16),指向显示码的第16个"-"

uchar code seg_data[]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90,0x88,0x83,0xc6,0xa1,0x86,0x8e,0xbf}

//0~F和"-"符的显示码(字形码)

/********以下是0.14ms的x倍延时函数********/

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

{

uchar i

while(x--)

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

}

/********以下是延饥培时函数********/

void Delay_ms(uint xms)

{

uint i,j

for(i=xmsi>0i--) //i=xms即延时约xms毫秒

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

}

/*********以下是蜂鸣器响一声函数********/

void beep()

{

BEEP=0 //蜂鸣器响

Delay_ms(100)

BEEP=1 //关闭蜂鸣器

Delay_ms(100)

}

/********以下是显示函数********/

void Display()

{

P0=(seg_data[disp_buf[0]])

P2=0x7f

Delay_ms(1)

P0=(seg_data[disp_buf[1]])

P2=0xbf

Delay_ms(1)

}

/前源********以下是主函数********/

main()

{

EA=1EX0=1//允许总中断中断,使能 INT0 外部中断

IT0 = 1 //触发方式为脉冲负边沿触发

IRIN=1 //遥控输入脚置1

BEEP=1RELAY=1 //关闭蜂鸣器和继电器

P0=0xffP2=0xff //P0和P2口置1

Display() //调显示函数

while(1)

{

if(IR_buf[2]==0x02) //02H键(键值码为02H)

RELAY=0 //继电器吸合

if(IR_buf[2]==0x01) // 01H键(键值码为01H)

RELAY=1 //继电器关闭

Display()

}

}

/********以下是外中断0函数********/

void IR_decode() interrupt 0

{

uchar j,k,count=0

EX0 = 0 //暂时关闭外中断0中断请求

delay(20) //延时20*0.14=2.8ms

if (IRIN==1) //等待 IRIN低电平出现

{

EX0 =1 //开外中断0

return //中断返回

}

while (!IRIN) delay(1) //等待IRIN变为高电平,跳过9ms的慧肢态低电平引导码

for (j=0j<4j++) //收集四组数据,即用户码低位、用户码高位、键值数据码和键值数码反码

{

for (k=0k<8k++) //每组数据有8位

{

while (IRIN)//等待IRIN变为低电平,跳过4.5ms的高电平引导码信号。

delay(1)

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

delay(1)

while (IRIN) //对IRIN高电平时间进行计数

{

delay(1) //延时0.14ms

count++ //对0.14ms延时时间进行计数

if (count>=30)

{

EX0=1 //开外中断0

return //0.14ms计数过长则返回

}

}

IR_buf[j]=IR_buf[j] >>1 //若计数小于6,数据最高位补"0",说明收到的是"0"

if (count>=6) {IR_buf[j] = IR_buf[j] | 0x80} //若计数大于等于6,数据最高位补"1",说明收到的是"1"

count=0 //计数器清0

}

}

if (IR_buf[2]!=~IR_buf[3]) //将键数据反码取反后与键数据码码比较,若不等,表示接收数据错误,放弃

{

EX0=1

return

}

disp_buf[0]=IR_buf[2] &0x0f//取键码的低四位送显示缓冲

disp_buf[1]=IR_buf[2] >>4 //右移4次,高四位变为低四位送显示缓冲

Display() //调显示函数

beep() //蜂鸣器响一声

EX0 = 1 //开外中断0

}

下面是一个用C写的遥控器漏巧漏程序.能在数码管上显示键码.

#include <reg52.h>

#define c(x) (x*110592/120000)

sbit Ir_Pin=P3^3

unsigned char code Led_Tab[]={0xC0,0xF9,0xA4,0xB0,0x99,0x92,0x82,

0xf8,0x80,0x90,0x88,0x83,0xC6,0xA1,0x86,0x8E} //共阳极数码显示码0-F.

unsigned char code Led_Sel[]={0xe,0xd,0xb,0x7}

unsigned char Led_Buf[4]//宽桐显示缓冲区

char Led_Index //位选

unsigned char Ir_Buf[4]//用于保存解码结果

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

//数码管扫描

timer0() interrupt 1 using 1

{

TL0=65536-1000

TH0=(65536-1000)/256//定时器0设定约1000us中断一次,用于数码管扫描

P0=0xff

P2=Led_Sel[Led_Index] //位选

P0=Led_Tab[Led_Buf[Led_Index]] //段选

if(++Led_Index>3) Led_Index=0 //四个扫描完了,到第一个数码管

}

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

unsigned int Ir_Get_Low()

{

TL1=0

TH1=0

TR1=1

while(!Ir_Pin &&(TH1&0x80)==0)

TR1=0

return TH1*256+TL1

}

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

unsigned int Ir_Get_High()

{

TL1=0

TH1=0

TR1=1

while(Ir_Pin &&(TH1&0x80)==0)

TR1=0

return TH1*256+TL1

}

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

main()

{

unsigned int temp

char i,j

Led_Index=1

TMOD=0x11

TL0=65536-1000

TH0=(65536-1000)/256//定时器0设定约1000us中断一次,用于数码管扫描

EA=1

ET0=1

TR0=1

Led_Buf[0]=0

Led_Buf[1]=0

Led_Buf[2]=0

Led_Buf[3]=0//显示区返烂设成0

do{

restart:

while(Ir_Pin)

temp=Ir_Get_Low()

if(temp<c(8500) || temp>c(9500)) continue//引导脉冲低电平9000

temp=Ir_Get_High()

if(temp<c(4000) || temp>c(5000)) continue//引导脉冲高电平4500

for(i=0i<4i++) //4个字节

for(j=0j<8j++) //每个字节8位

{

temp=Ir_Get_Low()

if(temp<c(200) || temp>c(800)) goto restart

temp=Ir_Get_High()

if(temp<c(200) || temp>c(2000)) goto restart

Ir_Buf[i]>>=1

if(temp>c(1120)) Ir_Buf[i]|=0x80

}

Led_Buf[0]=Ir_Buf[2]&0xf

Led_Buf[1]=(Ir_Buf[2]/16)&0xf

Led_Buf[2]=Ir_Buf[3]&0xf

Led_Buf[3]=(Ir_Buf[3]/16)&0xf//显示结果

}while(1)

}


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

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

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

发表评论

登录后才能评论

评论列表(0条)

保存