基于51单片机的红外遥控信号的发射和接收
本讲内容:
介绍红外遥控的知识,通过例程展示红外遥控程序的编写方法。
红外线简介:
在光谱中波长自760nm至400um的电磁波称为红外线,它是一种不可见光。目前几乎所有的视频和音频设备都可以通过红外遥控的方式进行遥控,比如电视机、空调、影碟机等,都可以见到红外遥控的影子。
这种技术应用广泛,相应的应用器件都十分廉价,因此红外遥控是我们日常设备控制的理想方式。
接收头输出的波形正好和遥控芯片输出的相反。
在这里红外通信采用NEC协议,它的特征如下:
红外遥控信号接收管接口电路:
红外信号发射电路 红外信号接收电路
例程:
红外遥控信号发射:
/******************红外通信——发射******************
*单片机型号:STC89C52RC
*开发环境:KEIL
*名称:红外通信发射
*功能:按下按键S4,S5,S6,S8,S9,S10,S11,S13,S14发射对应键值,
可以与红外通信——接收程序配套使用
*********************************************************/
#include <REG51.h>
#include <intrins.h>
#define uchar unsigned char
#define uint unsigned int
#define SBM 0x80 //识别码
#define m9 (65536-8294) //约9mS
#define m4_5 (65536-4147) //约4.5mS
#define m1_6 (65536-1521) //约1.65mS
#define m_65 (65536-599) //约0.65mS
#define m_56 (65536-516) //约0.56mS
#define m40 (65536-36864) //约40mS
#define m56 (65536-51610) //56mS
#define m2_25 (65536-2074) //约2.25mS
const uchar TabHL1[9]={0x0c,0x18,0x5e,0x08,0x1c,0x5a,0x42,0x52,0x4a};
sbit IR=P1^5; //定义发射引脚
sbit BEEP=P2^3;
void keyscan();
void ZZ(uchar x);
void Z0(uchar temp);
void TT0(bit BT,uint x);
void delay(int In,int Out);
/*┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈
函数功能:主函数
┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈/
void main(void)
{
TMOD=0x01; //T0 16位工作方式
IR=1; //发射端口常态为高电平
while(1){keyscan();}
}
/*┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈
函数功能:发送主程序
┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈/
void ZZ(uchar x)
{
TT0(1,m9); //高电平9mS
TT0(0,m4_5); //低电平4.5mS
/*┈ 发送4帧数据 ┈*/
Z0(SBM);
Z0(~SBM);
Z0(x);
Z0(~x);
/*┈┈ 结束码 ┈┈*/
TT0(1,m_65);
TT0(0,m40);
}
/*┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈
函数功能:单帧发送程序
入口参数:1帧数据
┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈/
void Z0(uchar temp)
{
uchar v;
for (v=0;v<8;v++) //循环8次移位
{
TT0(1,m_65); //高电平0.65mS
if(temp&0x01) TT0(0,m1_6); //发送最低位
else TT0(0,m_56);
temp >>= 1; //右移一位
}
}
/*┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈
函数功能:38KHz脉冲发射 + 延时程序
入口参数:(是否发射脉冲,延时约 x (uS))
┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈/
void TT0(bit BT,uint x)
{
TH0=x>>8; //输入T0初始值
TL0=x;
TF0=0; //清0
TR0=1; //启动定时器0
if(BT==0)while(!TF0);
//BT=0时不发射38KHz脉冲只延时;BT=1发射38KHz脉冲且延时;
else while(1) //38KHz脉冲,占空比5:26
{
IR = 0;
if(TF0)break;
if(TF0)break;
IR = 1;
if(TF0)break;
if(TF0)break;
if(TF0)break;
if(TF0)break;
if(TF0)break;
if(TF0)break;
if(TF0)break;
if(TF0)break;
if(TF0)break;
if(TF0)break;
}
TR0=0; //关闭定时器0
TF0=0; //标志位溢出则清0
IR =1; //脉冲停止后,发射端口常态为高电平
}
void keyscan() //按键扫描函数
{
uchar buffer;
/***************************************************/
P3=0xfe; //扫描S3,S4,S5,S6;
buffer=P3;
buffer=buffer & 0xf0;
if(buffer!=0xf0)
{
delay(5,10);
if(buffer!=0xf0)
{
buffer=P3;
switch(buffer)
{
case 0xee:{;}break;
case 0xde:{ZZ(TabHL1[0]);}break;
case 0xbe:{ZZ(TabHL1[1]);}break;
case 0x7e:{ZZ(TabHL1[2]);}break;
}
while(buffer != 0xf0)
{
buffer=P3;
buffer=buffer&0xf0;
BEEP=0;
}
BEEP=1;
}
}
/****************************************************/
P3=0xfd; //扫描S8,S9,S10,S11
buffer=P3;
buffer=buffer & 0xf0;
if(buffer!=0xf0)
{
delay(5,10);
if(buffer!=0xf0)
{
buffer=P3;
switch(buffer)
{
case 0xed:{ZZ(TabHL1[3]);}break;
case 0xdd:{ZZ(TabHL1[4]);}break;
case 0xbd:{ZZ(TabHL1[5]);}break;
case 0x7d:{ZZ(TabHL1[6]);}break;
}
while(buffer!=0xf0)
{
buffer=P3;
buffer=buffer&0xf0;
BEEP=0;
}
BEEP=1;
}
}
/****************************************************/
P3=0xfb; //扫描S13,S14,S15,S16
buffer=P3;
buffer=buffer&0xf0;
if(buffer!=0xf0)
{
delay(5,10);
if(buffer!=0xf0)
{
buffer=P3;
switch(buffer)
{
case 0xeb:{ZZ(TabHL1[7]);}break;
case 0xdb:{ZZ(TabHL1[8]);}break;
}
while(buffer!=0xf0)
{
buffer=P3;
buffer=buffer&0xf0;
BEEP=0;
}
BEEP=1;
}
}
}
void delay(int In,int Out) //定义延时函数
{
int i,j;
for(i=0;i<In;i++)
{for(j=0;j<Out;j++){;}}
}
红外遥控信号接收:
/*****************红外通信–接收******************
*单片机型号:STC89C52RC
*开发环境:KEIL
*功能:在液晶LCD1602上显示接收到的数值
****************************************************/
#include<reg52.h>
#define LCD_Data P0
#define Busy 0x80
sbit IR=P3^2;
sbit LCD_RS=P1^0;
sbit LCD_RW=P1^1;
sbit LCD_E=P2^5;
void TIM0init(void);
void EX0init(void);
void SYSinit(void);
void delay(int In,int Out);
void Delay5Ms(void);
void Ir_work(void);
void Ircordpro(void);
void WriteDataLCD(unsigned char WDLCD);
void WriteCommandLCD(unsigned char WCLCD,BuysC);
unsigned char ReadDataLCD(void);
unsigned char ReadStatusLCD(void);
void LCDInit(void);
void DisplayOneChar(unsigned char X,unsigned char Y,unsigned char DData);
void DisplayListChar(unsigned char X,unsigned char Y,unsigned char code *DData);
void Info_display(void);
bit IRpro_ok;
bit IR_ok;
unsigned char IRcord[4];
unsigned char IRdata[33];
unsigned char code
dofly_DuanMa[10]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f};
unsigned char irtime;
unsigned char speed_num=0;
unsigned char code
mb_table[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0x77,0x7c,0x39,
0x5e,0x79,0x71};
unsigned char code welcome[]={"YOU ARE WELCOME"};
unsigned char code ir_reve[]={"IR_RECEIVE: "};
/*******************5ms延时函数*********************/
void Delay5Ms(void)
{unsigned int TempCyc=3552;while(TempCyc–);}
void delay(int In,int Out)
{
int i,j;
for(i=0;i<In;i++)
{for(j=0;j<Out;j++){;}}
}
/***********************写数据函数***********************/
void WriteDataLCD(unsigned char WDLCD)
{
ReadStatusLCD();
LCD_Data=WDLCD;
LCD_RS=1;
LCD_RW=0;
LCD_E=0;
LCD_E=0;
LCD_E=1;
}
/**********************写指令函数************************/
void WriteCommandLCD(unsigned char WCLCD,BuysC)
{
if(BuysC)ReadStatusLCD();
LCD_Data=WCLCD;
LCD_RS=0;
LCD_RW=0;
LCD_E=0;
LCD_E=0;
LCD_E=1;
}
/***********************读状态函数************************/
unsigned char ReadStatusLCD(void)
{
LCD_Data=0xFF;
LCD_RS=0;
LCD_RW=1;
LCD_E=0;
LCD_E=0;
LCD_E=1;
while(LCD_Data & Busy);
return(LCD_Data);
}
/************************LCD初始化************************/
void LCDInit(void)
{
LCD_Data=0;
WriteCommandLCD(0x38,0);Delay5Ms();
WriteCommandLCD(0x38,0);Delay5Ms();
WriteCommandLCD(0x38,0);Delay5Ms();
WriteCommandLCD(0x38,1);
WriteCommandLCD(0x08,1);
WriteCommandLCD(0x01,1);
WriteCommandLCD(0x06,1);
WriteCommandLCD(0x0C,1);
}
/*******************按指定位置显示一个字符******************/
void DisplayOneChar(unsigned char X,unsigned char Y,unsigned char DData)
{
Y&=0x1;X&=0xF;
if(Y)X|=0x40;
X|=0x80;
WriteCommandLCD(X,0);
WriteDataLCD(DData);
}
/*******************按指定位置显示一串字符******************/
void DisplayListChar(unsigned char X,unsigned char Y,unsigned char code *DData)
{
unsigned char ListLength;ListLength=0;
Y&=0x1;X&=0xF;
while(DData[ListLength]>=0x20)
{
if(X<=0xF)
{
DisplayOneChar(X,Y,DData[ListLength]);
ListLength++;
X++;
}
}
}
/***********************定时器0初始化***********************/
void TIM0init(void)
{TMOD=0x02;TH0=0x00;TL0=0x00;ET0=1;TR0=1;}
/**********************外部中断0初始化**********************/
void EX0init(void){IT0=1;EX0=1;EA=1;}
/*************************系统初始化*************************/
void SYSinit(void){TIM0init();EX0init();LCDInit();}
/********************红外信号接收相关函数********************/
void Ir_work(void)
{
switch(IRcord[2])
{
case 0x0C:{DisplayOneChar(12,1,0×31);}break;
case 0x18:{DisplayOneChar(12,1,0×32);}break;
case 0x5e:{DisplayOneChar(12,1,0×33);}break;
case 0x08:{DisplayOneChar(12,1,0×34);}break;
case 0x1c:{DisplayOneChar(12,1,0×35);}break;
case 0x5a:{DisplayOneChar(12,1,0×36);}break;
case 0x42:{DisplayOneChar(12,1,0×37);}break;
case 0x52:{DisplayOneChar(12,1,0×38);}break;
case 0x4a:{DisplayOneChar(12,1,0×39);}break;
default:break;
}
}
void Ircordpro(void)
{
unsigned char i,j,k;
unsigned char cord,value;
k=1;
for(i=0;i<4;i++)
{
for(j=1;j<=8;j++)
{
cord=IRdata[k];
if(cord>7)value|=0x80;
if(j<8){value>>=1;}
k++;
}
IRcord[i]=value;
value=0;
}
IRpro_ok=1;
}
/********************红外信号接收相关函数********************/
void main(void)
{
SYSinit();delay(5,100);
DisplayListChar(0,0,welcome);
DisplayListChar(0,1,ir_reve);
while(1)
{
if(IR_ok){Ircordpro();IR_ok=0;}
if(IRpro_ok){Ir_work();}
}
}
/********************定时器0中断处理函数********************/
void tim0_isr (void) interrupt 1 using 1
{irtime++;}
/*******************外部中断0中断处理函数*******************/
void EX0_ISR (void) interrupt 0
{
static unsigned char i;
static bit startflag;
if(startflag)
{
if(irtime<63&&irtime>=33)
i = 0;
IRdata[i]=irtime;
irtime=0;
i++;
if(i==33){IR_ok=1;i=0;}
}
else{irtime=0;startflag=1;}
}
最后,求求看到的此文的小伙伴点赞和关注支持一下下哦。毕竟,码字不容易哦,您的支持是我最大的动力呀!!!呜呜呜~~~