Altium Designer画的ESP8266自学习红外遥控原理图和PCB图如下:(51hei附件中可下载工程文件)
ESP8266单片机源程序如下:
- #include "stc12c2052ad.h"
- #include "wifi_IR.h"
- #include <intrins.h>
- //#define ENABLE_IAP 0x83 //if SYSCLK<20MHz
- #define FOSC 11059200UL//12M晶振
- #define CMD_IDLE 0 //Stand-By
- #define CMD_READ 1 //Byte-Read
- #define CMD_PROGRAM 2 //Byte-Program
- #define CMD_ERASE 3 //Sector-Erase
- uint addr;//EPPROM地址
- //uchar cou;
- bit study_send_switch,LED_state;
- void SaveLevelTimeLength(uint addr);//存储电平时长
- void IrSend();//红外发射
- void Read_Key();
- void IrStudy();
- void IapIdle();
- void byte_write(uint addr, uchar dat);
- void SectorErase(uint sector_addr);
- uchar byte_read(uint addr);
- void TIMER0_RELOAD(uint addr)//装入定时器
- {
- TR0=0;
- TF0=0;
- TH0=byte_read(addr);//从指定的地址读出电平的长度
- TL0=byte_read(addr+1);//从指定的地址读出电平的长度
- TR0=1;//启动定时器
- }
- //---------------------------------------------------
- void IrSend()//红外发射
- {
- uchar level_cnt; //电平个数
- level_cnt=byte_read(addr);//读出电平个数
- addr++;//地址后移一位
- while (1)
- {
- F38_4KHZ_ON();//因为红外码大部分都是起始一段高电平,所以此处一开始就打开。
- TIMER0_RELOAD(addr);//时长装入定时器,开始计时
- addr+=2;// 地址移到没有取过的地方,TIMER0_RELOAD函数取了两个地址的数据
- while (!TF0);//等待定时器0溢出
-
- if(level_cnt--==0)break;//判断是否取完
- F38_4KHZ_OFF(); IR_SEND = 1;//停止发射
- TIMER0_RELOAD(addr);//时长装入定时器,开始计时
- addr+=2;//地址移到没有取过的地方,TIMER0_RELOAD函数取了两个地址的数据
- while (!TF0);//等待定时器0溢出
- if(level_cnt--==0)break;//电平数是否完毕
- }
- F38_4KHZ_OFF(); IR_SEND = 1;//停止发射
- }
- //---------------------------------------------------
- void SaveLevelTimeLength(uint addr)//存电平时长
- {
- TR0=0;
- byte_write(addr, ~TH0);
- byte_write(addr+1, ~TL0); //电平时长存入eeprom中
- TH0=0;//定时器初值归0
- TL0=0x65;//查手册知道,编程一个字节需要55us,编程两个字节,所以此处需要110us。
- TR0=1;//开始计数
- }
- void IrStudy()
- {
- uint level_cnt;
- uint addrtmp;
- TF0 = 0;
- SectorErase(addr);
- addrtmp=addr;//记录第一个地址,存储电平个数
- addr++;
- TR0=0;//停止计数
- while (IR_REV);//等待红外接收管脚为低电平
- //编码与解码是一对逆过程,不仅在原理上是一对逆过程,在码的发收过程也是互反的,即以前发射端原始信号是高电平,那接收头输出的就是低电平
- TH0=0;
- TL0=0;
- TR0=1;//开启定时器
-
-
- while (1)
- {
- while (!IR_REV) //等待高电平,等待超时;超过70MS退出
- {
- if (TF0)
- {
- goto StudyFinish;
- }
-
- }
-
- SaveLevelTimeLength(addr); //高电平到来,存低电平时长到eeprom}
- level_cnt++;
- addr += 2;
-
- while (IR_REV) //等待低电平,等待超时;超过70MS退出
- {
- if (TF0)
- {
- goto StudyFinish;
- }
- }
- SaveLevelTimeLength(addr);//低电平到来存高电平电平时长
- level_cnt++;//存储的电平个数加11
- addr+=2;//地址后移两位
- }
- StudyFinish:
- TF0=0;
- TR0=0;
- byte_write(addrtmp,level_cnt);
- level_cnt = 0;
- }
- void Delay100ms() //@11.0592MHz
- {
- unsigned char i, j, k;
- _nop_();
- _nop_();
- i = 5;
- j = 52;
- k = 195;
- do
- {
- do
- {
- while (--k);
- } while (--j);
- } while (--i);
- }
- void IapIdle()
- {
- IAP_CONTR = 0; //Close IAP function
- IAP_CMD = 0; //Clear command to standby
- IAP_TRIG = 0; //Clear trigger register
- IAP_ADDRH = 0x80; //Data ptr point to non-EEPROM area
- IAP_ADDRL = 0; //Clear IAP address to prevent misuse
- }
- /************************************************************************
- 函数名称:字节写
- 全局变量:无
- 参数说明:addr:写入地址, dat:写入数据
- ************************************************************************/
- void byte_write(uint addr,uchar dat)
- {
- IAP_CONTR = ENABLE_IAP; //Open IAP function, and set wait time
- IAP_CMD = CMD_PROGRAM; //Set ISP/IAP/EEPROM PROGRAM command
- IAP_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 data
- IAP_TRIG = 0x46; //Send trigger command1 (0x46)
- IAP_TRIG = 0xb9; //Send trigger command2 (0xb9)
- _nop_();
- _nop_();
- _nop_();
- _nop_();
- IapIdle();
- }
- /************************************************************************
- 函数名称:扇区擦除
- 全局变量:无
- 参数说明:sector_addr:扇区地址
- ************************************************************************/
- void SectorErase(uint addr)
- {
- IAP_CONTR = ENABLE_IAP; //Open IAP function, and set wait time
- IAP_CMD = CMD_ERASE; //Set ISP/IAP/EEPROM ERASE command
- IAP_ADDRL = addr; //Set ISP/IAP/EEPROM address low
- IAP_ADDRH = addr >> 8; //Set ISP/IAP/EEPROM address high
- IAP_TRIG = 0x46; //Send trigger command1 (0x46)
- IAP_TRIG = 0xb9; //Send trigger command2 (0xb9)
- _nop_();
- _nop_();
- _nop_();
- _nop_();
- IapIdle();
- }
- /************************************************************************
- 函数名称:字节读函数
- 全局变量:无
- 参数说明:addr:所要读取的地址
- 返回说明:读取到的数据
- ************************************************************************/
- uchar byte_read(uint addr)
- {
- uchar dat; //Data buffer
- IAP_CONTR = ENABLE_IAP; //Open IAP function, and set wait time
- IAP_CMD = CMD_READ; //Set ISP/IAP/EEPROM READ command
- IAP_ADDRL = addr; //Set ISP/IAP/EEPROM address low
- IAP_ADDRH = addr >> 8; //Set ISP/IAP/EEPROM address high
- IAP_TRIG = 0x46; //Send trigger command1 (0x46)
- IAP_TRIG = 0xb9; //Send trigger command2 (0xb9)
- _nop_();
- _nop_();
- _nop_();
- _nop_();
- dat = IAP_DATA; //Read ISP/IAP/EEPROM data
-
- IapIdle();
- return dat; //Return Flash data
- }
- /*****************************
- 主程序
- ******************************/
- void main()
- {
- uchar i;
- /***********************************按复位键下载***********************************************************/
- if((PCON&0x10)==0) //如果POF位=0 不是上电复位
- { PCON=PCON|0x10; //将POF位置1 此处置1是为了下一条语句复位的时候不进入此函数
- ISP_CONTR=0x60; //软复位,从ISP监控区启动 复位完成 ISP_CONTR 寄存器的值是多少???
- }
- else
- {
- PCON=PCON&0xef; //将POF位清零
- }
- /***********************************按复位键下载***********************************************************/
-
- wifi_power = 0;
- IR_REV = 1;
-
- P1M0 = 0;
-
- P1M1 = 0x02; //定义P1.1为推挽输出
-
- P3M0 = 0;
-
- P3M1 = 0xA0; //定义P3.5 P3.7为推挽输出
-
- SW_WIFI_DL = 1;
-
- TIMER0_INIT();
- serial_init();
- DEBUG_LED = 1;
-
- while(1)
- {
- PCON = 0X01;
- _nop_();
- _nop_();
- _nop_();
- _nop_();
-
- r_string();
- if(r_comp == 1)
- {
- r_comp = 0;
-
- if(tp[0] == 0)
- {
- study_send_switch = 1; //学习状态
- }
-
- else if(tp[0] == 0x15)
- {
- study_send_switch = 0; //发射状态
- }
- else if(tp[0] == 0x16)
- {
- HS0038_power = 1;
- wifi_power = 1;
- IR_SEND = 1;
-
- PCON=2;
- _nop_();
- _nop_();
- _nop_();
- _nop_();
-
- }
- else
- {
- EA = 0;
-
- switch(tp[0])
- {
-
- // case 0x00: study_send_switch = !study_send_switch;break;
- case 0x01: addr = 0; break;
- case 0x02: addr = 0x200; break;
- case 0x03: addr = 0x400; break;
- case 0x04: addr = 0x600; break;
- case 0x05: addr = 0x800; break;
- case 0x06: addr = 0xa00; break;
- case 0x07: addr = 0xc00; break;
- case 0x08: addr = 0xe00; break;
- case 0x09: addr = 0x1000;break;
- case 0x0a: addr = 0x1200;break;
- case 0x0b: addr = 0x1400;break;
- case 0x0c: addr = 0x1600;break;
- case 0x0d: addr = 0x1800;break;
- case 0x0e: addr = 0x1a00;break;
- case 0x0f: addr = 0x1c00;break;
- case 0x10: addr = 0x1e00;break;
- case 0x11: addr = 0x2000;break;
- case 0x12: addr = 0x2200;break;
- case 0x13: addr = 0x2400;break;
- case 0x14: addr = 0x2600;break;
-
-
- default: addr = 0x8000;break;
-
- }
-
- if(study_send_switch)
- {
- HS0038_power = 0;
-
- for(i = 0;i < 5;i++)
- {
- ……………………
- …………限于本文篇幅 余下代码请从51黑下载附件…………
复制代码
所有资料51hei提供下载:
wifi红外学习遥控源代码V1.0.zip
(13.48 KB, 下载次数: 207)
wifi红外遥控PCB工程V1.0.zip
(437.44 KB, 下载次数: 201)
|