集成电路原理与设计专题报告.docx
《集成电路原理与设计专题报告.docx》由会员分享,可在线阅读,更多相关《集成电路原理与设计专题报告.docx(18页珍藏版)》请在冰点文库上搜索。
集成电路原理与设计专题报告
集成电路原理与设计专题报告
关于单片机红外控制的研究
1、专题背景
红外遥控是一种无线、非接触控制技术,具有抗干扰能力强,信息传输可靠,功耗低,成本低,易实现等显著优点,被诸多电子设备特别是家用电器广泛采用,并越来越多的应用到计算机系统中。
由于红外线遥控不具有像无线电遥控那样穿过障碍物去控制被控对象的能力,所以,在设计家用电器的红外线遥控器时,不必要像无线电遥控器那样,每套(发射器和接收器)要有不同的遥控频率或编码(否则,就会隔墙控制或干扰邻居的家用电器),所以同类产品的红外线遥控器,可以有相同的遥控频率或编码,而不会出现遥控信号“串门”的情况。
这对于大批量生产以及在家用电器上普及红外线遥控提供了极大的方便。
由于红外线为不可见光,因此对环境影响很小,再由红外光波动波长远小于无线电波的波长,所以红外线遥控不会影响其他家用电器,也不会影响临近的无线电设备。
2、思路总结
为了解红外遥控技术,我们选取单片机作为研究对象。
我们以红外遥控控制单片机上一LED灯亮灭这一简单操作为目的,并以LED亮的不同时间来区分不同按键。
所以这里我们需要做的主要是:
掌握红外遥控原理和不同按键代码
1、红外遥控原理
红外遥控的发射电路是采用红外发光二极管来发出经过调制的红外光波;红外接收电路由红外接收二极管、三极管或硅光电池组成,它们将红外发射器发射的红外光转换为相应的电信号,再送后置放大器。
当某个按键按下时,系统首先发射一个完整的全码(示意图如下),一个完整的全码=引导码+用户码+用户码+数据码+数据反码。
其中,引导码由9ms的起始码和4.5ms的结果码组成;系统码8位,数据码8位,共32位;其中前16位为用户识别码,能区别不同的红外遥控设备,防止不同机种遥控码互相干扰。
后16位为8位的操作码和8位的操作反码,用于核对数据是否接收准确。
收端根据数据码做出应该执行什么动作的判断。
连发代码是在持续按键时发送的码,如果键按下超过108ms仍未松开,接下来发射的代码(连发代码)将仅由起始码(9ms)和结束码(2.5ms)组成,它告知接收端,某键是在被连续地按着。
全码示意图
解码的关键是如何识别“0”和“1”。
“0”、“1”均以0.56ms的低电平开始,不同的是高电平的宽度不同。
“0”为0.56ms,“1”为1.68ms,所以必须根据高电平的宽度区别“0”和“1”。
如果从0.56ms低电平过后,开始延时,0.56ms以后,若读到的电平为低,说明该位为“0”,反之则为“1”,为了可靠起见,延时必须比0.56ms长些,但又不能超过1.12ms,否则如果该位为“0”,读到的已是下一位的高电平,因此取(1.12ms+0.56ms)/2=0.84ms最为可靠,一般取0.84ms左右均可。
2、如何知道遥控发射的不同代码
这里我们用LCD屏来显示按键的代码(LDE显示原理这里不做介绍),在得到每个按键的代码后,我们将代码写进程序,并用其来实现不同的操作。
(具体程序见电子档附录)
3、红外遥控的应用
红外线遥控是目前使用最广泛的一种通信和遥控手段。
由于红外线遥控装置具有体积小、功耗低、功能强、成本低等特点,因而,继彩电、录像机之后,在录音机、音响设备、空凋机以及玩具等其它小型电器装置上也纷纷采用红外线遥控。
工业设备中,在高压、辐射、有毒气体、粉尘等环境下,采用红外线遥控不仅完全可靠而且能有效地隔离电气干扰。
由于其无法穿透墙壁,所以不同房间的家用电器可使用通用遥控器而不会产生相互干扰;电路调试简单,只要按给定电路连接无误,一般不需任何调试即可投入工作;编解码容易,可进行多路遥控。
现在红外遥控在家用电器、室内近距离遥控中得到了广泛的应用。
另外模块还可以用在其他红外遥控系统中,应用前景十分广阔。
附录:
LCD.H头文件:
#ifndef__LCD_H_
#define__LCD_H_
/**********************************
当使用的是4位数据传输的时候定义,
使用8位取消这个定义
**********************************/
#defineLCD1602_4PINS
/**********************************
包含头文件
**********************************/
#include
//---重定义关键词---//
#ifndefuchar
#defineucharunsignedchar
#endif
#ifndefuint
#defineuintunsignedint
#endif
/**********************************
PIN口定义
**********************************/
#defineLCD1602_DATAPINSP0
sbitLCD1602_E=P2^7;
sbitLCD1602_RW=P2^5;
sbitLCD1602_RS=P2^6;
/**********************************
函数声明
**********************************/
/*在51单片机12MHZ时钟下的延时函数*/
voidLcd1602_Delay1ms(uintc);//误差0us
/*LCD1602写入8位命令子函数*/
voidLcdWriteCom(ucharcom);
/*LCD1602写入8位数据子函数*/
voidLcdWriteData(uchardat);
/*LCD1602初始化子程序*/
voidLcdInit();
#endif
LCD.C文件:
*输出:
无
*说名:
该函数是在12MHZ晶振下,12分频单片机的延时。
*******************************************************************************/
voidLcd1602_Delay1ms(uintc)//误差0us
{
uchara,b;
for(;c>0;c--)
{
for(b=199;b>0;b--)
{
for(a=1;a>0;a--);
}
}
}
/*******************************************************************************
*函数名:
LcdWriteCom
*函数功能:
向LCD写入一个字节的命令
*输入:
com
*输出:
无
*******************************************************************************/
#ifndefLCD1602_4PINS//当没有定义这个LCD1602_4PINS时
voidLcdWriteCom(ucharcom)//写入命令
{
LCD1602_E=0;//使能
LCD1602_RS=0;//选择发送命令
LCD1602_RW=0;//选择写入
LCD1602_DATAPINS=com;//放入命令
Lcd1602_Delay1ms
(1);//等待数据稳定
LCD1602_E=1;//写入时序
Lcd1602_Delay1ms(5);//保持时间
LCD1602_E=0;
}
#else
voidLcdWriteCom(ucharcom)//写入命令
{
LCD1602_E=0;//使能清零
LCD1602_RS=0;//选择写入命令
LCD1602_RW=0;//选择写入
LCD1602_DATAPINS=com;//由于4位的接线是接到P0口的高四位,所以传送高四位不用改
Lcd1602_Delay1ms
(1);
LCD1602_E=1;//写入时序
Lcd1602_Delay1ms(5);
LCD1602_E=0;
//Lcd1602_Delay1ms
(1);
LCD1602_DATAPINS=com<<4;//发送低四位
Lcd1602_Delay1ms
(1);
LCD1602_E=1;//写入时序
Lcd1602_Delay1ms(5);
LCD1602_E=0;
}
#endif
/*******************************************************************************
*函数名:
LcdWriteData
*函数功能:
向LCD写入一个字节的数据
*输入:
dat
*输出:
无
*******************************************************************************/
#ifndefLCD1602_4PINS
voidLcdWriteData(uchardat)//写入数据
{
LCD1602_E=0;//使能清零
LCD1602_RS=1;//选择输入数据
LCD1602_RW=0;//选择写入
LCD1602_DATAPINS=dat;//写入数据
Lcd1602_Delay1ms
(1);
LCD1602_E=1;//写入时序
Lcd1602_Delay1ms(5);//保持时间
LCD1602_E=0;
}
#else
voidLcdWriteData(uchardat)//写入数据
{
LCD1602_E=0;//使能清零
LCD1602_RS=1;//选择写入数据
LCD1602_RW=0;//选择写入
LCD1602_DATAPINS=dat;//由于4位的接线是接到P0口的高四位,所以传送高四位不用改
Lcd1602_Delay1ms
(1);
LCD1602_E=1;//写入时序
Lcd1602_Delay1ms(5);
LCD1602_E=0;
LCD1602_DATAPINS=dat<<4;//写入低四位
Lcd1602_Delay1ms
(1);
LCD1602_E=1;//写入时序
Lcd1602_Delay1ms(5);
LCD1602_E=0;
}
#endif
/*******************************************************************************
*函数名:
LcdInit()
*函数功能:
初始化LCD屏
*输入:
无
*输出:
无
*******************************************************************************/
#ifndefLCD1602_4PINS
voidLcdInit()//LCD初始化子程序
{
LcdWriteCom(0x38);//开显示
LcdWriteCom(0x0c);//开显示不显示光标
LcdWriteCom(0x06);//写一个指针加1
LcdWriteCom(0x01);//清屏
LcdWriteCom(0x80);//设置数据指针起点
}
#else
voidLcdInit()//LCD初始化子程序
{
LcdWriteCom(0x32);//将8位总线转为4位总线
LcdWriteCom(0x28);//在四位线下的初始化
LcdWriteCom(0x0c);//开显示不显示光标
LcdWriteCom(0x06);//写一个指针加1
LcdWriteCom(0x01);//清屏
LcdWriteCom(0x80);//设置数据指针起点
}
#endif
主函数:
/*******************************************************************************
*实验名:
1602显示红外线值实验
*使用的IO:
电机用P1口,键盘使用P3.0、P3.1、P3.2、P3.3
*实验效果:
LCD1602显示出读取到的红外线的值
*注意:
*******************************************************************************/
#include
#include"lcd.h"
#defineled_onled=0;
#defineled_offled=1;
sbitIRIN=P3^2;
sbitled=P2^0;
intkey=0;
charkey_flag=0;
unsignedcharval_1=0;
unsignedcharval_2=0;
unsignedintTime;
unsignedcharcodeCDIS1[13]={"RedControl"};
unsignedcharcodeCDIS2[13]={"IR-CODE:
--H"};
unsignedcharIrValue[6];
unsignedlongcounter;
voidIrInit();
voidDelayMs(unsignedint);
voidTimer_0_Configuration();
/*******************************************************************************
*函数名:
main
*函数功能:
主函数
*输入:
无
*输出:
无
*******************************************************************************/
voidmain()
{
unsignedchari;
Timer_0_Configuration();
IrInit();
LcdInit();
LcdWriteCom(0x80);
for(i=0;i<13;i++)
{
LcdWriteData(CDIS1[i]);
}
LcdWriteCom(0x80+0x40);
for(i=0;i<13;i++)
{
LcdWriteData(CDIS2[i]);
}
while
(1)
{
IrValue[4]=IrValue[2]>>4;//高位
IrValue[5]=IrValue[2]&0x0f;//低位
if(IrValue[2]!
=0){val_1=IrValue[4];
val_2=IrValue[5];}
if(val_1>9)
{
LcdWriteCom(0xc0+0x09);//设置显示位置
LcdWriteData(0x37+val_1);//将数值转换为该显示的ASCII码
}
else
{
LcdWriteCom(0xc0+0x09);
LcdWriteData(val_1+0x30);//将数值转换为该显示的ASCII码
}
if(val_2>9)
{
LcdWriteCom(0xc0+0x0a);
LcdWriteData(val_2+0x37);//将数值转换为该显示的ASCII码
}
else
{
LcdWriteCom(0xc0+0x0a);
LcdWriteData(val_2+0x30);//将数值转换为该显示的ASCII码
}
key_flag=IrValue[4]*10+IrValue[5];
if(key!
=key_flag)
{
key=key_flag;
switch(key)
{
//case45:
led_off;TR0=0;counter=0;IrValue[2]=0;break;//直接灭
case44:
led_on;TR0=1;counter=0;IrValue[2]=0;break;//秒灭
case7:
led_on;TR0=1;counter=0;break;//3分钟
case16:
led_on;TR0=1;counter=0;break;//5分钟
case12:
led_on;TR0=1;counter=0;break;//10分钟
case8:
led_on;TR0=1;counter=0;break;//20分钟
case42:
led_on;TR0=1;counter=0;break;//30分钟
//case90:
led_on;TR0=1;counter=0;break;//30分钟
default:
led_off;TR0=0;counter=0;IrValue[2]=0;break;
}
}
if(key==7&&counter==50){led_off;TR0=0;counter=0;IrValue[2]=0;}
if(key==16&&counter==6000){led_off;TR0=0;counter=0;IrValue[2]=0;}
if(key==12&&counter==12000){led_off;TR0=0;counter=0;IrValue[2]=0;}
if(key==8&&counter==24000){led_off;TR0=0;counter=0;IrValue[2]=0;}
if(key==42&&counter==36000){led_off;TR0=0;counter=0;IrValue[2]=0;}
}
}
/*******************************************************************************
*函数名:
DelayMs()
*函数功能:
延时
*输入:
x
*输出:
无
*******************************************************************************/
voidDelayMs(unsignedintx)//0.14ms误差0us
{
unsignedchari;
while(x--)
{
for(i=0;i<13;i++)
{}
}
}
/*******************************************************************************
*函数名:
IrInit()
*函数功能:
初始化红外线接收
*输入:
无
*输出:
无
*******************************************************************************/
voidIrInit()
{
IT0=1;//下降沿触发
EX0=1;//打开中断0允许
EA=1;//打开总中断
IRIN=1;//初始化端口
}
voidTimer_0_Configuration()//配置定时器
{
TMOD=0x01;//选择工作方式1
TH0=0x3C;//设置初始值,定时50MS
TL0=0xB0;
EA=1;//打开总中断
ET0=1;//打开定时器0中断
//TR0=1;//启动定时器0
}
voidTimer0()interrupt1//定时器0中断函数
{
TH0=0x3C;//设置初始值
TL0=0xB0;
counter++;
}
/*******************************************************************************
*函数名:
ReadIr()
*函数功能:
读取红外数值的中断函数
*输入:
无
*输出:
无
*******************************************************************************/
voidReadIr()interrupt0
{
unsignedcharj,k;
unsignedinterr;
Time=0;
DelayMs(70);
if(IRIN==0)//确认是否真的接收到正确的信号
{
err=1000;//1000*10us=10ms,超过说明接收到错误的信号
/*当两个条件都为真是循环,如果有一个条件为假的时候跳出循环,免得程序出错的时
侯,程序死在这里*/
while((IRIN==0)&&(err>0))//等待前面9ms的低电平过去
{
DelayMs
(1);
err--;
}
if(IRIN==1)//如果正确等到9ms低电平
{
err=500;
while((IRIN==1)&&(err>0))//等待4.5ms的起始高电平过去
{
DelayMs
(1);
err--;
}
for(k=0;k<4;k++)//共有4组数据
{
for(j=0;j<8;j++)//接收一组数据
{
err=60;
while((IRIN==0)&&(err>0))//等待信号前面的560us低电平过去
//while(!
IRIN)
{