#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)
}
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)