本人是单片机初学求C语言红外遥控解码程序并用数码管显示带注悉

2024-11-23 10:32:46
推荐回答(1个)
回答(1):

#include
#include
#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 = 0; i<13; i++);
}
/********以下是延时函数********/
void Delay_ms(uint xms)
{
uint i,j;
for(i=xms;i>0;i--) //i=xms即延时约xms毫秒
for(j=110;j>0;j--);
}
/*********以下是蜂鸣器响一声函数********/
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=1;EX0=1; //允许总中断中断,使能 INT0 外部中断
IT0 = 1; //触发方式为脉冲负边沿触发
IRIN=1; //遥控输入脚置1
BEEP=1; RELAY=1; //关闭蜂鸣器和继电器
P0=0xff; P2=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=0;j<4;j++) //收集四组数据,即用户码低位、用户码高位、键值数据码和键值数码反码
{
for (k=0;k<8;k++) //每组数据有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
}