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

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

#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,急、急、急......等相关内容解答,如果想了解更多相关内容,可以关注我们,你们的支持是我们更新的动力!

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

原文地址: http://outofmemory.cn/zz/10141965.html

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

发表评论

登录后才能评论

评论列表(0条)

保存