本人是单片机初学求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

}

#include<reg52h> //包含头文件,一般情况不需要改动,头文件包含特殊功能寄存器的定义

sbit IR=P3^2; //红外接口标志

#define DataPort P0 //定义数据端口 程序中遇到DataPort 则用P0 替换

sbit LATCH1=P2^2;//定义锁存使能端口 段锁存

sbit LATCH2=P2^3;// 位锁存

/------------------------------------------------

全局变量声明

------------------------------------------------/

unsigned char code dofly_DuanMa[10]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f};// 显示段码值0~9

unsigned char irtime;//红外用全局变量

bit irpro_ok,irok;

unsigned char IRcord[4];

unsigned char irdata[33];

/------------------------------------------------

函数声明

------------------------------------------------/

void Ir_work(void);

void Ircordpro(void);

/------------------------------------------------

定时器0中断处理

------------------------------------------------/

void tim0_isr (void) interrupt 1 using 1

{

irtime++; //用于计数2个下降沿之间的时间

}

/------------------------------------------------

外部中断0中断处理

------------------------------------------------/

void EX0_ISR (void) interrupt 0 //外部中断0服务函数

{

static unsigned char i; //接收红外信号处理

static bit startflag; //是否开始处理标志位

if(startflag)

{

if(irtime<63&&irtime>=33)//引导码 TC9012的头码,9ms+45ms

i=0;

irdata[i]=irtime;//存储每个电平的持续时间,用于以后判断是0还是1

irtime=0;

i++;

if(i==33)

{

irok=1;

i=0;

}

}

else

{

irtime=0;

startflag=1;

}

}

/------------------------------------------------

定时器0初始化

------------------------------------------------/

void TIM0init(void)//定时器0初始化

{

TMOD=0x02;//定时器0工作方式2,TH0是重装值,TL0是初值

TH0=0x00; //重载值

TL0=0x00; //初始化值

ET0=1; //开中断

TR0=1;

}

/------------------------------------------------

外部中断0初始化

------------------------------------------------/

void EX0init(void)

{

IT0 = 1; //指定外部中断0下降沿触发,INT0 (P32)

EX0 = 1; //使能外部中断

EA = 1; //开总中断

}

/------------------------------------------------

键值处理

------------------------------------------------/

void Ir_work(void)//红外键值散转程序

{

switch(IRcord[2])//判断第三个数码值

{

case 0x0c:DataPort=dofly_DuanMa[1];break;//1 显示相应的按键值

case 0x18:DataPort=dofly_DuanMa[2];break;//2

case 0x5e:DataPort=dofly_DuanMa[3];break;//3

case 0x08:DataPort=dofly_DuanMa[4];break;//4

case 0x1c:DataPort=dofly_DuanMa[5];break;//5

case 0x5a:DataPort=dofly_DuanMa[6];break;//6

case 0x42:DataPort=dofly_DuanMa[7];break;//7

case 0x52:DataPort=dofly_DuanMa[8];break;//8

case 0x4a:DataPort=dofly_DuanMa[9];break;//9

default:break;

}

irpro_ok=0;//处理完成标志

}

/------------------------------------------------

红外码值处理

------------------------------------------------/

void Ircordpro(void)//红外码值处理函数

{

unsigned char i, j, k;

unsigned char cord,value;

k=1;

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

{

for(j=1;j<=8;j++) //处理1个字节8位

{

cord=irdata[k];

if(cord>7)//大于某值为1,这个和晶振有绝对关系,这里使用12M计算,此值可以有一定误差

value|=0x80;

if(j<8)

{

value>>=1;

}

k++;

}

IRcord[i]=value;

value=0;

}

irpro_ok=1;//处理完毕标志位置1

}

/------------------------------------------------

主函数

------------------------------------------------/

void main(void)

{

EX0init(); //初始化外部中断

TIM0init();//初始化定时器

DataPort=0xfe; //取位码 第一位数码管选通,即二进制1111 1110

LATCH2=1; //位锁存

LATCH2=0;

while(1)//主循环

{

if(irok) //如果接收好了进行红外处理

{

Ircordpro();

irok=0;

}

if(irpro_ok) //如果处理好后进行工作处理,如按对应的按键后显示对应的数字等

{

Ir_work();

}

}

}

经过试验是可以的

那个N大于30是因为已经超出了0和1代表的时间长度。0和1所代表的高低电平时间不一样。当高电平时长超过n=8时,代表1否则代表0这个是和你红外设置的0,1代表时间长度有关系,请问你有时序图吗??那就一目了然了

 这个程序太简单了,我之前写过红外发射程序的,接收程序也很简单,你这个项目我2个小时都能帮你解决,但是89C52单片机发射38K不准需要把晶振加大,提高单片机的运行速度。

你的项目只要主机A发射红外协议后面加一个地址,单片机B接收的时候全部进入接收状态,判接收的地址是否符合对于单片机B的地址,如果地址符合,那就先回应一个数据例如:55FF55,主机接收到55FF55后后面开始接收数据,把接收到的数据直接写入单片机内EEPRM里面!

以上就是关于本人是单片机初学求C语言红外遥控解码程序并用数码管显示带注悉全部的内容,包括:本人是单片机初学求C语言红外遥控解码程序并用数码管显示带注悉、红外解码程序,但是单片机上电数码管不亮,更别说遥控器控制他了,求高手指点错误、谁能帮我解释一下这个有关51单片机的红外解码的部分程序等相关内容解答,如果想了解更多相关内容,可以关注我们,你们的支持是我们更新的动力!

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

原文地址:https://54852.com/zz/9697201.html

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

发表评论

登录后才能评论

评论列表(0条)

    保存