红外光通信装置-电赛报告————————————————————————————————作者:————————————————————————————————日期:[键入文档标题]红外光通信装置(F题)【本科组】2013年9月6日目录摘要 (3)1.系统方案设计 (5)1.1设计任务 (5)1.2方案的设计与论证 (5)1.2.1红外光通信装置总体方案设计 (5)1.2.2单片机模块的选择 (6)1.2.3红外发射接收装置模块的选择 (7)1.2.4语音采集模块方案的选择 (7)2.单元硬件电路设计 (7)2.1发射部分电路的设计 (7)2.2中转部分电路的设计 (8)2.3接收部分电路的设计 (8)3.程序设计 (9)3.1发射装置程序流程图 (9)3.2接收装置程序流程图 (10)4.系统测试 (10)5.理论分析与计算 (11)6.结论 (12)参考文献 (12)附录 (13)摘要随着红外技术的发展,红外光通信已经成为越来越普及的无线通信方式。
在本次设计作品中,红外光通信装置采用红外光传输及无线工作机制,其组成结构主要包括:红外发射装置、中继转发节点、红外接收装置三部分组成。
红外发射装置主要是由声音采集系统经单片机存储后发射,红外接收装置接收到的信息经单片机存储后再经过D/A转换播放。
通过采用A/D,D/A 转换的方法达到了本次作品设计的目的。
在电子消费领域当中,红外产品的使用较为普遍,它多用于简单的近距离控制,如家电、玩具、各种抄表系统、工业控制、娱乐设施等领域。
所以,其具有很强的现实意义。
关键词:红外通信发射接收 A/D转换 D/A转换AbstractWith the development of infrared, and infrared optical communication has become more and more popular way of wireless communication.This design works, infra-red communication devices use infrared light transmission and wireless working mechanisms, its composition include: infrared emitting device, relay node, an infrared receiver unit is composed of three parts. Infrared Launcher corresponds with sound collection system by single-chip computer memory after the launch, IR receiver receives the information via a single-chip storage, and then after d/a conversion play. Through the use of a/d,d/a conversion way to achieve the purpose of the production design.In the field of consumer electronics, using infrared products are more prevalent, it is used for simple control at close range, such as household appliances, toys, metering systems, industrial control, recreational facilities, and other fields. So, it has a lot of practical significance.Key words: Infrared Communication launch receive A/D conversion D/A conversion1系统方案设计1.1设计任务根据命题要求,设计并制作一个红外光通信装置。
红外光通信装置利用红外发光管和红外接收模块作为收发器件用来定向传输语音信号,传输距离为2m.传输的语音信号频率范围为300–3400HZ,接收的声音应无明显失真。
此外,增加一路数字信道,实时传输发射端环境温度,并能在接收端显示。
数字信号传输时延不超过10s,温度测量误差不超过2℃,语音信号和数字信号能同时传输。
同时,设计并制作一个红外光通信中继转发节点,以改变通信方向90℃,延长通信距离2m,中继转发节点采用5V直流单电源供电,尽量减小转发节点供电电流。
1.2方案的设计与论证1.2.1红外光通信装置总体方案设计整套方案主要由红外发射装置、中继转发节点、红外接收装置三部分组成。
先把传输进红外发射装置的声音经过放大电路进行放大,然后由STC12C5A08S2单片机自身带有的A/D转换功能把模拟信号转换为数字信号对放大之后的语音进行采集,同时把采集到的数字信号存储到STC12C5A08S2单片机中。
然后,经555定时器电路产生38K载波,并利用三极管对单片机中存储的数据和555定时器产生的38K载波进行调制到达中继转发节点,并由1838红外接收头进行解调,接着把解调后的信号编码发送给中继点上的单片机STC11F04E,并由此单片机对其数据进行取反。
再由555定时器电路产生38K载波,利用三极管对经单片机取反后的数据和38K载波进行调制,之后到达接收点。
到达接收点的信号经STC12C5A08S2进行解码,送给 TLC5615CP 芯片构建的D/A转换电路把数字信号转换为模拟信号,最后再将此模拟信号发送给耳机,并由耳机播放。
采用此方案的框图如下:温度、音频1.2.2单片机模块的选择方案一:传统51系列是的单片机,受其结构本身的限制很大,尤其模拟功能部件的增加更显困难,而且运行速度很慢,功耗比较高,抗干扰能力也不是很强。
方案二:STM32系列具有一流的外设、低功耗、最大的集成度、简单的结构和易用的工具,是ARM 公司的高性能Cortex-M3内核。
但我们对此系列的单片机的编程操作不太熟练。
方案三:宏晶芯片STC12C5A08S2是增强型的51系统单片机,具有一个时钟,高速、高可靠、宽电压、增加第二复位功能脚和外部掉电检测电路,采用低功耗设计,最重要的是其内部有AD 外设和45K 的EEPROM,我们可由此进行模数转换和信息存储。
STC11F04E 单片机超强抗干扰,超强抗静电,速度快,输入/输出口多,超低功耗,在系统可编程,无需编程器,无需仿真器,放单片中继转显示音频A/D单片红外单片DA播温度可远程升级。
由于对于中继点低功耗的要求,所以把此单片机用于中继转发节点。
基于我们对各种系列单片机运用的熟练程度和此次作品中所要实现的各项基本功能,我们决定在此方案设计中采用方案三。
1.2.3红外发射接收装置模块的选择方案一:红外模拟信号。
这种方法速度快,能达到实时传输效果。
但是,在传输过程中,噪音比较大,容易受干扰。
而且,传输的距离也比较近。
方案二:红外数字信号。
将要发射出去的模拟信号转换成数字信号,将数字信号送给红外发射电路,经该电路的调制转变成红外光信号在空中传输,到达中继转发节点后,转发到红外接收电路,接收电路收到该红外光信号,经过该电路的解调,将此红外光信号还原成可被单片机或其他处理系统处理的信号,由单片机或其他处理系统内部处理得到原来的数据编码。
比较方案一和方案二,又考虑到我们对模拟部分的知识和数字部分的知识的掌握程度,我们决定选择方案二。
1.2.4语音采集模块方案的选择方案一:采用语音编解码芯片。
这种方法失真度小,信噪比较低,数据量大。
但在数字图像处理中,由于数据量大,算法难度高,因此实时性成为技术难点之一。
而且,在传输过程中所运用的1838红外接收头传输信息速度慢,而语音编码解码芯片数据量过大,与后续装置不协调。
方案二:采用A/D,D/A转换装置。
先把模拟信号转换为数字信号,再经中继转换节点在通信协议的控制下把数字信号转换为模拟信号。
比较两种方案,并基于现实的情况,此模块选择方案二。
2单元硬件电路设计2.1发射部分电路的设计发射部分主要由双运放NE5532组成的放大器、STC12C5A08S2单片机和NE555定时器构建的电路组成。
其电路图如图1:图12.2中转部分电路的设计中转部分主要由1838红外接收头、STC11F04E单片机NE555定时器、三极管等搭建的电路组成,其电路图如图2:图22.3接收部分电路的设计接收部分主要由1838红外接收头、STC12C5A08S2单片机、TLC5615数模转换器、TL431可控精密稳压源等搭建的电路组成。
其电路图如图3:图33 程序设计系统程序主要由发射装置程序和接收装置程序两部分组成。
系统程序流程图如下所示。
3.1发射装置程序流程图NY初采集单片机存储读发NY开读存结YN3.2接收装置程序流程图4 系统测试传输距离测试:传输距离 传输情况 1m 良好 2m 良好 3m 良好 4m良好中继点电流大小:100MA 左右初接单片机NNY Y 读D/A转接收Y YNN开结温度误差:1°C无发射信号时无噪音800HZ信号输出0.3V有信号时8个LED闪烁,无信号时LED不闪烁5 理论分析与计算本系统使用数字信号传输,编码规则自定,具体如下:每串数据有1.5MS高电平,2MS低电平的引导码高电平时间0.5低电平时间0.6MS代表二进制数0高电平时间1.0MS代表二进制数1传输波形如图:波形1波形2波形36 结论本系统功能上和参数上都达到了题目的要求,基本上完成了题目的各项设计。
并按照要求完成了其发挥部分,可以精确的显示温度,也可以利用中继点进行转接,但是声音信号传输延时较大。
优点:本系统采用数字信号传输数据,能够最大限度的减少干扰且传输距离较长,适用于信息量较少、环境干扰较大的情况传输数据。
本系统的不足:由于红外数字信号传输使用38K载波频率,很大程度上限制了数据传输的速度,所以本系统不适合音频等数据量较大的数据传输。
所以本系统还有较大的提升空间,如声音信号使用模拟信号传输、温度信号使用数字信号传输能达到声音信号和温度信号实时传输。
参考文献[1]阎石.数字电子技术基础(第五版)[M].北京:高等教育出版社,2006.[2]童诗白,华成英.模拟电子技术基础(第四版)[M].北京:高等教育出版社,2006.[3]黄智伟.全国大学生电子设计竞赛技能训练(第2版)[M].北京:北京航空航天大学,2011.[4]代万辉,陈松方.全国电子设计大赛培训宝典[M].北京:北京航空航天大学,2012.[5]求是科技.8051系列单片机C程序设计完全手册[M].北京:人民邮电出版社,2006.[6]杨欣,王玉凤,刘湘黔.电子设计从零开始[M].北京:清华大学出版社2005. 附录:源程序//*************************sendmessage**************************//#include "STC12C5A60S2.h"#include "intrins.h"#define uchar unsigned char#define uint unsigned chartypedef unsigned char BYTE;typedef unsigned int WORD;uchar codestr1[]={0x28,0xA6,0x4A,0x0E,0x05,0x00,0x00,0x84};//ROM 1 uchar codestr2[]={0x28,0xA5,0x86,0x40,0x04,0x00,0x00,0x80};//ROM 2 sbit D1=P3^7;sbit DQ=P3^3;/*Define ISP/IAP/EEPROM command*/#define CMD_IDLE 0 //Stand-By#define CMD_READ 1 //Byte-Read#define CMD_PROGRAM 2 //Byte-Program#define CMD_ERASE 3 //Sector-Erase/*Define ISP/IAP/EEPROM operation const for IAP_CONTR*/#define ENABLE_IAP 0x80 //if SYSCLK<30MHzsfr ADC_DATA = 0XBD;sfr ADC_LOW = 0XBE;sbit CS=P2^0;sbit SCLK=P2^1;sbit DIN=P2^2;sbit left = P1^0;double j;uchar flag,t;void Delay(BYTE n);void IapIdle();BYTE IapReadByte(WORD addr);void IapProgramByte(WORD addr, BYTE dat);void IapEraseSector(WORD addr);uchar tvalue;//温度值void Delay999ms() //@30.000MHz{unsigned char i, j, k;_nop_();_nop_();i = 114;j = 226;k = 60;do{do{while (--k);} while (--j);} while (--i);}/******************************ds1820 *********************/ void Delay1us() //@30.000MHz{unsigned char i;i = 5;while (--i);}void Delay10us() //@30.000MHz {unsigned char i;_nop_();_nop_();i = 72;while (--i);}void Delay48us() //@30.000MHz {unsigned char i, j;i = 2;j = 99;do{while (--j);} while (--i);}void Delay700us() //@30.000MHz {unsigned char i, j;i = 21;j = 106;do{while (--j);} while (--i);}void Delay1ms() //@30.000MHz {unsigned char i, j;i = 30;j = 43;do{while (--j);} while (--i);void rst_Ds18b20(){DQ=1;Delay1us();DQ=0;Delay700us();//延迟700usDQ=1;Delay1ms();}void writeDs18b20(uchar date)//写数据{uchar i;DQ=1;Delay1us();for (i=0;i<8;i++){DQ=0;Delay10us();DQ=date&0x01;Delay48us();DQ=1;date>>=1;Delay1us();}}uchar readDs18b20() //读数据{uchar i,date;DQ=1;_nop_();for(i=0;i<8;i++){DQ=0;Delay10us();DQ=1;Delay1us();Delay1us();date>>=1;if(DQ==1)date=date+0x80;Delay48us();}return date;}void MatchromDs18b20(uchar a) //匹配ROM{char j;writeDs18b20(0x55); //发送匹配ROM命令if(a==1){for(j=0;j<8;j++)writeDs18b20(str1[j]); //发送18B20的序列号,先发送低字节}if(a==2){for(j=0;j<8;j++)writeDs18b20(str2[j]); //发送18B20的序列号,先发送低字节}}uint read_temp(uchar z)/*读取温度值并转换*/{uchar a,b;rst_Ds18b20();if(z==1)MatchromDs18b20(1); //匹配ROM 1if(z==2)MatchromDs18b20(2); //匹配ROM 2writeDs18b20(0x44);//*启动温度转换*/// delay(1000);rst_Ds18b20();if(z==1)MatchromDs18b20(1); //匹配ROM 1if(z==2)MatchromDs18b20(2); //匹配ROM 2writeDs18b20(0xbe);//*读取温度*/a=readDs18b20();b=readDs18b20();tvalue=((a>>4)|(b<<4));return(tvalue);}void DAC(uchar w) //转换,将数据写入芯片{int a;CS=0;for(a=0;a<12;a++){SCLK=1;_nop_();_nop_();if((w&0x80)!=0)//判断写入数据从第一位开始,看是否有数据输入DIN=1;//将信号1写入芯片中elseDIN=0;//将0写入芯片中_nop_();_nop_();SCLK=0;//开启下一个写入数据w<<=1;}CS=1; //关闭芯片}void Timer1Init(void) //142微秒@24.000MHz{AUXR &= 0xBF; //定时器时钟12T模式TMOD &= 0x0F; //设置定时器模式TMOD |= 0x10; //设置定时器模式TL1 = 0x7A; //设置定时初值TH1 = 0xFE; //设置定时初值TF1 = 0; //清除TF1标志TR1 = 1; //定时器1开始计时}/*----------------------------initialization function----------------------------*/void init(){EA = 1; //开总中断ET1 = 1; //开定时器1中断PT1 = 1; //定时器1中断设为高优先级P1M0 = 0XFF;P1M1 = 0;P1ASF = 0X01; //设置P1.0作为输入Timer1Init();}/*----------------------------Software delay function----------------------------*/void Delay7us() //@30.000MHz{unsigned char i;i = 50;while (--i);}/*----------------------------Software delay function----------------------------*/void Delay(BYTE n){WORD x;while (n--){x = 0;while (++x);}}/*----------------------------Disable ISP/IAP/EEPROM functionMake MCU in a safe state----------------------------*/void IapIdle(){IAP_CONTR = 0; //Close IAP functionIAP_CMD = 0; //Clear command to standby IAP_TRIG = 0; //Clear trigger register IAP_ADDRH = 0x80; //Data ptr point tonon-EEPROM areaIAP_ADDRL = 0; //Clear IAP address to prevent misuse}/*----------------------------Read one byte from ISP/IAP/EEPROM areaInput: addr (ISP/IAP/EEPROM address)Output:Flash data----------------------------*/BYTE IapReadByte(WORD addr){BYTE dat; //Data bufferIAP_CONTR = ENABLE_IAP; //Open IAP function, and set wait timeIAP_CMD = CMD_READ; //Set ISP/IAP/EEPROM READ commandIAP_ADDRL = addr; //Set ISP/IAP/EEPROM address lowIAP_ADDRH = addr >> 8; //Set ISP/IAP/EEPROM address highIAP_TRIG = 0x5a; //Send trigger command1(0x5a)IAP_TRIG = 0xa5; //Send trigger command2 (0xa5)_nop_(); //MCU will hold here until ISP/IAP/EEPROM operation completedat = IAP_DATA; //Read ISP/IAP/EEPROM data IapIdle(); //Close ISP/IAP/EEPROM functionreturn dat; //Return Flash data}/*----------------------------Program one byte to ISP/IAP/EEPROM areaInput: addr (ISP/IAP/EEPROM address)dat (ISP/IAP/EEPROM data)Output:-----------------------------*/void IapProgramByte(WORD addr, BYTE dat){IAP_CONTR = ENABLE_IAP; //Open IAP function, and set wait timeIAP_CMD = CMD_PROGRAM; //Set ISP/IAP/EEPROM PROGRAM commandIAP_ADDRL = addr; //Set ISP/IAP/EEPROM address lowIAP_ADDRH = addr >> 8; //Set ISP/IAP/EEPROM address highIAP_DATA = dat; //Write ISP/IAP/EEPROM data IAP_TRIG = 0x5a; //Send trigger command1(0x5a)IAP_TRIG = 0xa5; //Send trigger command2(0xa5)_nop_(); //MCU will hold here until ISP/IAP/EEPROM operation completeIapIdle();}/*----------------------------Erase one sector areaInput: addr (ISP/IAP/EEPROM address)Output:-----------------------------*/void IapEraseSector(WORD addr){IAP_CONTR = ENABLE_IAP; //Open IAP function, and set wait timeIAP_CMD = CMD_ERASE; //Set ISP/IAP/EEPROM ERASE commandIAP_ADDRL = addr; //Set ISP/IAP/EEPROM address lowIAP_ADDRH = addr >> 8; //Set ISP/IAP/EEPROM address highIAP_TRIG = 0x5a; //Send trigger command1(0x5a)IAP_TRIG = 0xa5; //Send trigger command2(0xa5)_nop_(); //MCU will hold here until ISP/IAP/EEPROM operation completeIapIdle();}void Delay100us() //@30.000MHz{unsigned char i, j;i = 3;j = 232;do{while (--j);} while (--i);}/*----------------------------擦除eeprom----------------------------*/void Eraseeeprom(){uint i;double a;a=0;for(i = 0; i <90; i++){a = 512+a;IapEraseSector(a); //Erase current sector}}/***********************************************sendmess****** ********************************//************************************************************* *********************************//***************************************发送红外数据**************************/void send(uchar date){uchar i;/*************发送验证信息*************/TR0=0;TH0 = 0xF1;TL0 = 0x5A; //装入初值设置波延时为1.5ms D1 = 1; //发送1.5ms的高电平TR0 = 1; //启动定时器0while(!TF0); //等待TF0 = 0;TH0 = 0xEC;TL0 = 0x78;D1 = 0; //发送2ms的低电平while(!TF0); //等待TF0 = 0;/**************发送数据****************/for(i=0;i<8;i++){TL0 = 0x1E; //设置定时初值 0.5MSTH0 = 0xFB; //设置定时初值TR0=1;D1=1;while(!TF0);TF0=0;if(date&0x01){TL0 = 0x3C; //设置定时初值 1MS 发1TH0 = 0xF6; //设置定时初值}else{TL0 = 0x24; //设置定时初值 0.6MS 发0TH0 = 0xFA; //设置定时初值 TH0 = 0xFD; //0为窄的低电平,持续时间 0.6ms}D1=0;while(!TF0); //等待TF0 = 0;date=date>>1;}TL0 = 0x1E; //设置定时初值 0.5MSTH0 = 0xFB; //设置定时初值TR0=1;D1=1;while(!TF0);TF0=0;D1=0;/************************************结尾**************************/TH0 = 0x0EC; //延时2msTL0 = 0x078;TR0=1;while(!TF0);TF0=0;TR0=0;}void sendtem(uchar date){uchar i;/*************发送验证信息*************/TR0=0;TH0 = 0xF1;TL0 = 0x5A; //装入初值设置波延时为1.5ms D1 = 1; //发送1.5ms的高电平TR0 = 1; //启动定时器0while(!TF0); //等待TF0 = 0;TH0 = 0xE2;TL0 = 0xB4;D1 = 0; //发送3ms的低电平while(!TF0); //等待TF0 = 0;/**************发送数据****************/for(i=0;i<8;i++){TL0 = 0x1E; //设置定时初值 0.5MSTH0 = 0xFB; //设置定时初值TR0=1;D1=1;while(!TF0);TF0=0;if(date&0x01){TL0 = 0x3C; //设置定时初值 1MS 发1TH0 = 0xF6; //设置定时初值}else{TL0 = 0x24; //设置定时初值 0.6MS 发0TH0 = 0xFA; //设置定时初值 TH0 = 0xFD; //0为窄的低电平,持续时间 0.6ms}D1=0;while(!TF0); //等待TF0 = 0;date=date>>1;}TL0 = 0x1E; //设置定时初值 0.5MSTH0 = 0xFB; //设置定时初值TR0=1;D1=1;while(!TF0);TF0=0;D1=0;/************************************结尾**************************/TH0 = 0x0EC; //延时2msTL0 = 0x078;TR0=1;while(!TF0);TF0=0;TR0=0;}/*********************************************main************ ******************************************/void main(){read_temp(2);Delay999ms();/*******************sendinit**********************/ AUXR &= 0x7F; //定时器时钟12T模式TMOD &= 0xF0; //设置定时器模式TMOD |= 0x01; //设置定时器模式TR0=0;/**************************************************/ sendtem(read_temp(2));Eraseeeprom(); //擦除EEPROMflag = 0;j =t=0;init();while (1);}void timer1() interrupt 3{// send(0x55);TL1 = 0x7A; //设置定时初值TH1 = 0xFE; //设置定时初值ADC_CONTR= 0xe8;Delay7us(); //@24.000MHzif(flag == 0){IapProgramByte(j, ADC_DATA); ////写EEPROMj++;if(j == 46079){flag = 1;j = 0;}}ADC_CONTR= 0x80;if(flag == 1){while(j!=46079){send(IapReadByte(j));j++;t++;if((t%500)==0){t=0;sendtem(read_temp(2));}}while(1);// DAC(IapReadByte(j)); //读EEPROM并DAC转化/* j++;if(j == 46079){Eraseeeprom(); //擦除EEPROM*/flag = 0;j = 0;}}------------------------------------------------------------------------------------------------------------------------------------ //*************************receive******************************// #include "STC12C5A60S2.h"#include "intrins.h"#define uchar unsigned char#define uint unsigned chartypedef unsigned char BYTE;typedef unsigned int WORD;uchar code str[]="Temperature";/*Define ISP/IAP/EEPROM command*/#define CMD_IDLE 0 //Stand-By#define CMD_READ 1 //Byte-Read#define CMD_PROGRAM 2 //Byte-Program#define CMD_ERASE 3 //Sector-Erase/*Define ISP/IAP/EEPROM operation const for IAP_CONTR*/#define ENABLE_IAP 0x80 //if SYSCLK<30MHzsbit CS=P2^0;sbit SCLK=P2^1;sbit DIN=P2^2;sbit re=P3^2;sbit test=P0^0;sbit test1=P0^1;sbit lcden=P3^4;sbit lcdrs=P3^5;double LowTime, HighTime;//储存高、低电平的宽度 0-65535uchar mess;uchar tem;double j;uchar flag,ge,shi;void Delay(BYTE n);void IapIdle();BYTE IapReadByte(WORD addr);void IapProgramByte(WORD addr, BYTE dat);void IapEraseSector(WORD addr);/*************************lcd1602程序**************************/ void Delay4ms() //@30.000MHz{unsigned char i, j;i = 117;j = 184;do{while (--j);} while (--i);}void writeCommend_Lcd(uchar com)//写指令{lcdrs=0;P0=com;lcden=1;Delay4ms();lcden=0;Delay4ms();}void writeData_Lcd(uchar date)//写数据{lcdrs=1;P0=date;lcden=1;Delay4ms();lcden=0;Delay4ms();}void init_Lcd()//初始化设置1602{uchar i;lcden=0;writeCommend_Lcd(0x38);writeCommend_Lcd(0x0c);writeCommend_Lcd(0x06);writeCommend_Lcd(0x01);writeCommend_Lcd(0x80);for(i=0;i<11;i++){writeData_Lcd(str[i]);}writeCommend_Lcd(0x80+14);writeData_Lcd(0xdf);writeData_Lcd(0x43);}void display(uchar date){shi=date/10;ge=date%10;writeCommend_Lcd(0x80+12);writeData_Lcd(0x30+shi);writeData_Lcd(0x30+ge);}/***********************************************DAC*************** ********************************//***************************************************************** ********************************/void Delay120us() //@30.000MHz{unsigned char i, j;i = 4;j = 125;do{while (--j);} while (--i);}void DAC(uchar w) //转换,将数据写入芯片{int a;CS=0;for(a=0;a<12;a++){SCLK=1;_nop_();_nop_();if((w&0x80)!=0)//判断写入数据从第一位开始,看是否有数据输入 DIN=1;//将信号1写入芯片中elseDIN=0;//将0写入芯片中_nop_();_nop_();SCLK=0;//开启下一个写入数据w<<=1;}CS=1; //关闭芯片}/**********************************************************EEPROM* ********************************//***************************************************************** ********************************//*----------------------------Disable ISP/IAP/EEPROM functionMake MCU in a safe state----------------------------*/void IapIdle(){IAP_CONTR = 0; //Close IAP functionIAP_CMD = 0; //Clear command to standbyIAP_TRIG = 0; //Clear trigger registerIAP_ADDRH = 0x80; //Data ptr point to non-EEPROM areaIAP_ADDRL = 0; //Clear IAP address to prevent misuse}/*----------------------------Read one byte from ISP/IAP/EEPROM areaInput: addr (ISP/IAP/EEPROM address)Output:Flash data----------------------------*/BYTE IapReadByte(WORD addr){BYTE dat; //Data bufferIAP_CONTR = ENABLE_IAP; //Open IAP function, and set wait timeIAP_CMD = CMD_READ; //Set ISP/IAP/EEPROM READ commandIAP_ADDRL = addr; //Set ISP/IAP/EEPROM address low IAP_ADDRH = addr >> 8; //Set ISP/IAP/EEPROM address high IAP_TRIG = 0x5a; //Send trigger command1 (0x5a) IAP_TRIG = 0xa5; //Send trigger command2 (0xa5) _nop_(); //MCU will hold here untilISP/IAP/EEPROM operation completedat = IAP_DATA; //Read ISP/IAP/EEPROM dataIapIdle(); //Close ISP/IAP/EEPROM functionreturn dat; //Return Flash data}/*----------------------------Program one byte to ISP/IAP/EEPROM areaInput: addr (ISP/IAP/EEPROM address)dat (ISP/IAP/EEPROM data)Output:-----------------------------*/void IapProgramByte(WORD addr, BYTE dat){IAP_CONTR = ENABLE_IAP; //Open IAP function, and set wait timeIAP_CMD = CMD_PROGRAM; //Set ISP/IAP/EEPROM PROGRAM commandIAP_ADDRL = addr; //Set ISP/IAP/EEPROM address low IAP_ADDRH = addr >> 8; //Set ISP/IAP/EEPROM address high IAP_DATA = dat; //Write ISP/IAP/EEPROM dataIAP_TRIG = 0x5a; //Send trigger command1 (0x5a) IAP_TRIG = 0xa5; //Send trigger command2 (0xa5) _nop_(); //MCU will hold here untilISP/IAP/EEPROM operation completeIapIdle();}/*----------------------------Erase one sector areaInput: addr (ISP/IAP/EEPROM address)Output:-----------------------------*/void IapEraseSector(WORD addr){IAP_CONTR = ENABLE_IAP; //Open IAP function, and set wait timeIAP_CMD = CMD_ERASE; //Set ISP/IAP/EEPROM ERASE commandIAP_ADDRL = addr; //Set ISP/IAP/EEPROM address low IAP_ADDRH = addr >> 8; //Set ISP/IAP/EEPROM address high IAP_TRIG = 0x5a; //Send trigger command1 (0x5a) IAP_TRIG = 0xa5; //Send trigger command2 (0xa5)_nop_(); //MCU will hold here until ISP/IAP/EEPROM operation completeIapIdle();}/*----------------------------擦除eeprom----------------------------*/void Eraseeeprom(){uint i;double a;a=0;for(i = 0; i <90; i++){a = 512+a;IapEraseSector(a); //Erase current sector}}/****************************************************************接收*******************************************/void init_ex0(){EA = 1; //开总中断EX0 = 1; //开外部中断0PX0 = 1; //外部中断0设为高优先级IT0 = 1; //设为INT0下降沿触发方式}bit DeCode(void){uchar i,temp;for(i=0;i<8;i++) //每个码有8位数字{temp=temp>>1; //temp中的各数据位右移一位,因为先读出的是低位数据TH0=0; //定时器清0TL0=0; //定时器清0TR0=1; //开启定时器T0while(re==0) ;//如果是低电平就等待低电平计时TR0=0; //关闭定时器T0LowTime=TH0*256+TL0; //保存低电平宽度TH0=0; //定时器清0TL0=0; //定时器清0TR0=1; //开启定时器T0while(re==1); //如果是高电平就等待TR0=0; //关闭定时器T0HighTime=TH0*256+TL0; //保存高电平宽度if((LowTime<800)||(LowTime>1600))return 0; //如果低电平长度不在合理范围,则认为出错,停止解码if((HighTime>1200)&&(HighTime<1850)) //如果高电平时间在600微秒左右,{temp=temp&0x7f; //则该位是0}if((HighTime>2000)&&(HighTime<3000)) //如果高电平时间在1000微秒左右,{temp=temp|0x80; //则该位是1}}mess=temp;return 1;}void Delay999ms() //@30.000MHz{unsigned char i, j, k;_nop_();_nop_();i = 114;j = 226;k = 60;do{do{while (--k);} while (--j);} while (--i);}/***********************************************main************** *******************************/void main(){init_Lcd();mess=0;Eraseeeprom(); //擦除EEPROMflag = 0;j =0;tem = 29;TMOD = 0x01;TR0=0;init_ex0();while (1){// display(tem);// Delay999ms();}}/**********************红外线触发中断处理函数**********************/void ex0() interrupt 0{// display(mess);EX0=0; //关闭外中断0,不再接收二次红外信号的中断,只解码当前红外信号TH0=0; //定时器T0的高8位清0TL0=0; //定时器T0的低8位清0TR0=1; //开启定时器T0while(re==0);//如果是低电平就等待TR0=0;LowTime=TH0*256+TL0; //保存低电平时间TH0=0; //定时器T0的高8位清0TL0=0; //定时器T0的低8位清0TR0=1; //开启定时器T0while(re==1); //如果是高电平就等待// test1=0;TR0=0; //关闭定时器T0HighTime=TH0*256+TL0; //保存引导码的高电平长度// test=0;if((LowTime>3000)&&(LowTime<4500)){//P0=0xaa;if((HighTime>4500&&HighTime<5600)){if(flag == 0){DeCode(); // 执行遥控解码功能P0=mess;IapProgramByte(j, mess); ////写EEPROMj++;if(j == 20000){flag = 1;j = 0;}}if(flag == 1){while(1){while(j!=20000){DAC(IapReadByte(j)); //读EEPROM并DAC 转化Delay120us();j++;}j=0;// P0=0xaa;}Eraseeeprom(); //擦除EEPROMflag = 0;j = 0;}}else if((HighTime>6800&&HighTime<8300)){if(flag==0){DeCode();tem=mess;display(tem);// Delay999ms();}}}EX0=1; //开启外中断EX0}//*************************程序END******************************//。