#include <reg51h>
#include <intrinsh>
#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和"-"符的显示码(字形码)
/以下是014ms的x倍延时函数/
void delay(uchar x) //延时x014ms
{
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); //延时20014=28ms
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变为低电平,跳过45ms的高电平引导码信号。
delay(1);
while (!IRIN) //等待IRIN变为高电平
delay(1);
while (IRIN) //对IRIN高电平时间进行计数
{
delay(1); //延时014ms
count++; //对014ms延时时间进行计数
if (count>=30)
{
EX0=1; //开外中断0
return; //014ms计数过长则返回
}
}
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
}
我用Keil c51 编译的。在程序开头部分加上下面的的头文件:
#include"reg51h"
另外,工程的文件夹下要包含头文件:
#include"beeph"
这样就没有错误了。
//这是IRh提供给外部调用的函数
#ifndef _IR_H_
#define _IR_H_
#include<reg52h>
#define uchar unsigned char
#define uint unsigned int
void ir_init(void);
void ir_run(void);
#endif
下面使用说明:
void ir_init(void);//红外初始化
void ir_run(void);//红外运行
extern uchar ir_code[2];//键盘码
例子:
void main()
{
ir_init();
while(1)
{
ir_run();
write_smg(0,ir_code[2]/16);//写数码管0显示
write_smg(1,ir_code[2]%16);//写数码管1显示
}
}
可到百度文库下载源码IRc(搜索关键字:IR红外解码模块)
感兴趣的还有:WDT看门狗模块
很好用!!!
IrValue[k]>>=1; //k表示第几组数据 这是把变量整体右移一位,由于是无符号最高位补0
if(Time>=8) //如果高电平出现大于565us,那么是1
{
IrValue[k]|=0x80; //变量最高位置一
}
Time=0; //用完时间要重新赋值
这样如果判断是1了就把最高位置一,0的话不用清零,因为右移的时候已经补0了
//////////////////////////////////////
//晶振频率为6MHz 一个机器周期2us //
//实现按键地址码、指令码的数码管显示//
//2010-06-01 //
//////////////////////////////////////
#include<reg52h>
#define uchar unsigned char
#define uint unsigned int
sbit dula=P2^6;
sbit wela=P2^7;
bit overflag,dataover;//开始接收数据,数据处理完毕
uchar timedata;//定时器0溢出次数
uchar chubus[33];//33Byte数据 timedata组成的数组
uchar jieguos[4];//地址码,地址反码,数据码,数据反码;
void initial()//初始化
{
IT0=1;EX0=1;//负边沿触发
TMOD=0x01;ET0=1;TR0=1;//模式1,十六位定时器
TH0=0xff;TL0=0x06;//05ms溢出
EA=1; //开总中断
}
void time0() interrupt 1//定时器0中断
{TH0=0xff;TL0=0x06;
timedata++;
}
void ex0() interrupt 0//外部中断0,接收数据
{
static bit startflag;//开始接收
static uchar i;
if(startflag)
{
if(timedata<32&&timedata>=16) i=0;
chubus[i]=timedata;
timedata=0;
i++;
if(i==33){overflag=1;i=0;}
}
else
{
startflag=1;
timedata=0;
}
}
void chulidata()
{
uchar chubu;//初步数据
uchar jieguo;//结果数据
uchar x,y,z=1;
for(x=0;x<4;x++)//处理四组数据
{
for(y=1;y<=8;y++)//处理一组数据8Byte
{
chubu=chubus[z];
jieguo=jieguo>>1;
if(chubu>3) jieguo=jieguo|0x80;//大于15mS为1
z++;
}
jieguos[x]=jieguo;
jieguo=0;
}
dataover=1;
}
void delay(uint z)
{
uint x ,y;
for(x=z;x>0;x--)
for(y=110;y>0;y--);
}
void display()
{
uchar gao,gao1;
uchar di,di1;
uchar code table[]={
0x3f,0x06,0x5b,0x4f,
0x66,0x6d,0x7d,0x07,
0x7f,0x6f,0x77,0x7c,
0x39,0x5e,0x79,0x71};
gao1=table[jieguos[0]/16];
di1=table[jieguos[0]%16];
gao=table[jieguos[2]/16];
di=table[jieguos[2]%16];
dula=1;
P0=gao1;
dula=0;
P0=0xff;
wela=1;
P0=0x7e;
wela=0;
delay(2);
dula=1;
P0=di1;
dula=0;
P0=0xff;
wela=1;
P0=0xfd;
wela=0;
delay(2);//地址码
dula=1;
P0=gao;
dula=0;
P0=0xff;
wela=1;
P0=0x77;
wela=0;
delay(2);
dula=1;
P0=di;
dula=0;
P0=0xff;
wela=1;
P0=0x6f;
wela=0;
delay(2);//指令码
}
void main()
{
initial();//初始化
while(1)
{
if(overflag)//数据接收完毕
{
chulidata();//处理数据,完成标志dataover
overflag=0;
}
if(dataover)
{
display();//数码管显示
}
}
}
思维:
先接9毫秒的高电平,45毫秒的低电平!在接收时,如果不为9毫秒和45毫秒即可退出!(当然,它们可以有范围的高电平可以放宽到8到10毫秒左右,因为有能量损失!)解码数据时!先解码
高电平(056毫秒)在解码没有信号(1125)为0,没有信号(225)为1,将数据存入寄存器就OK!32位数据接收完成后!判断是否为别的遥控器!判断用户码是否为一直的!在读出数据,散装到要执行的 *** 作!
以上就是关于本人是单片机初学求C语言红外遥控解码程序并用数码管显示带注悉全部的内容,包括:本人是单片机初学求C语言红外遥控解码程序并用数码管显示带注悉、一个红外遥控器的解码51单片机的程序,有些错误、51单片机DX们请帮忙看下红外解码的程序问题出在哪里按键无反应,发射芯片是HS5104,急、急、急......等相关内容解答,如果想了解更多相关内容,可以关注我们,你们的支持是我们更新的动力!
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)