找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 7915|回复: 9
打印 上一主题 下一主题
收起左侧

ESP8266智能家居自学习红外遥控设计 单片机源代码+PCB电路图

  [复制链接]
跳转到指定楼层
楼主
Altium Designer画的ESP8266自学习红外遥控原理图和PCB图如下:(51hei附件中可下载工程文件)


ESP8266单片机源程序如下:
  1. #include "stc12c2052ad.h"
  2. #include "wifi_IR.h"

  3. #include <intrins.h>

  4. //#define ENABLE_IAP  0x83            //if SYSCLK<20MHz

  5. #define FOSC 11059200UL//12M晶振

  6. #define CMD_IDLE    0               //Stand-By
  7. #define CMD_READ    1               //Byte-Read
  8. #define CMD_PROGRAM 2               //Byte-Program
  9. #define CMD_ERASE   3               //Sector-Erase



  10. uint addr;//EPPROM地址
  11. //uchar cou;
  12. bit study_send_switch,LED_state;

  13. void SaveLevelTimeLength(uint addr);//存储电平时长
  14. void IrSend();//红外发射                                         
  15. void Read_Key();
  16. void IrStudy();
  17. void IapIdle();
  18. void byte_write(uint addr, uchar dat);
  19. void SectorErase(uint sector_addr);
  20. uchar byte_read(uint addr);


  21. void TIMER0_RELOAD(uint addr)//装入定时器
  22. {
  23. TR0=0;
  24. TF0=0;
  25. TH0=byte_read(addr);//从指定的地址读出电平的长度
  26. TL0=byte_read(addr+1);//从指定的地址读出电平的长度
  27. TR0=1;//启动定时器

  28. }
  29. //---------------------------------------------------

  30. void IrSend()//红外发射
  31. {
  32.         uchar level_cnt;        //电平个数

  33.         level_cnt=byte_read(addr);//读出电平个数
  34.         addr++;//地址后移一位
  35.         while (1)
  36.         {
  37.                 F38_4KHZ_ON();//因为红外码大部分都是起始一段高电平,所以此处一开始就打开。
  38.                 TIMER0_RELOAD(addr);//时长装入定时器,开始计时
  39.                 addr+=2;// 地址移到没有取过的地方,TIMER0_RELOAD函数取了两个地址的数据
  40.                 while (!TF0);//等待定时器0溢出
  41.                
  42.                 if(level_cnt--==0)break;//判断是否取完
  43.                 F38_4KHZ_OFF(); IR_SEND = 1;//停止发射
  44.                 TIMER0_RELOAD(addr);//时长装入定时器,开始计时
  45.                 addr+=2;//地址移到没有取过的地方,TIMER0_RELOAD函数取了两个地址的数据
  46.                 while (!TF0);//等待定时器0溢出
  47.                 if(level_cnt--==0)break;//电平数是否完毕
  48.         }
  49.         F38_4KHZ_OFF(); IR_SEND = 1;//停止发射
  50. }
  51. //---------------------------------------------------

  52. void SaveLevelTimeLength(uint addr)//存电平时长
  53. {
  54.         TR0=0;
  55.         byte_write(addr, ~TH0);
  56.         byte_write(addr+1, ~TL0);  //电平时长存入eeprom中
  57.         TH0=0;//定时器初值归0
  58.         TL0=0x65;//查手册知道,编程一个字节需要55us,编程两个字节,所以此处需要110us。
  59.         TR0=1;//开始计数
  60. }

  61. void IrStudy()
  62. {
  63.         uint level_cnt;
  64.         uint addrtmp;

  65.         TF0 = 0;
  66.         SectorErase(addr);
  67.         addrtmp=addr;//记录第一个地址,存储电平个数
  68.         addr++;
  69.         TR0=0;//停止计数
  70.         while (IR_REV);//等待红外接收管脚为低电平        
  71.         //编码与解码是一对逆过程,不仅在原理上是一对逆过程,在码的发收过程也是互反的,即以前发射端原始信号是高电平,那接收头输出的就是低电平
  72.         TH0=0;
  73.         TL0=0;
  74.         TR0=1;//开启定时器
  75.         
  76.         
  77.         while (1)
  78.                 {
  79.                   while (!IR_REV)        //等待高电平,等待超时;超过70MS退出
  80.                   {
  81.                         if (TF0)
  82.                         {
  83.                          goto StudyFinish;
  84.                         }                  
  85.                   
  86.                   }                        
  87.                         
  88.                 SaveLevelTimeLength(addr); //高电平到来,存低电平时长到eeprom}
  89.         level_cnt++;
  90.                 addr += 2;
  91.                         
  92.                 while (IR_REV)        //等待低电平,等待超时;超过70MS退出                        
  93.                  {
  94.                   if (TF0)
  95.                   {
  96.                     goto StudyFinish;
  97.                   }                        
  98.                 }
  99.             SaveLevelTimeLength(addr);//低电平到来存高电平电平时长
  100.                 level_cnt++;//存储的电平个数加11
  101.                 addr+=2;//地址后移两位
  102.                 }
  103.                 StudyFinish:
  104.                 TF0=0;
  105.                 TR0=0;
  106.                 byte_write(addrtmp,level_cnt);
  107.                 level_cnt = 0;

  108. }




  109. void Delay100ms()                //@11.0592MHz
  110. {
  111.         unsigned char i, j, k;

  112.         _nop_();
  113.         _nop_();
  114.         i = 5;
  115.         j = 52;
  116.         k = 195;
  117.         do
  118.         {
  119.                 do
  120.                 {
  121.                         while (--k);
  122.                 } while (--j);
  123.         } while (--i);
  124. }


  125. void IapIdle()
  126. {
  127.     IAP_CONTR = 0;                  //Close IAP function
  128.     IAP_CMD = 0;                    //Clear command to standby
  129.     IAP_TRIG = 0;                   //Clear trigger register
  130.     IAP_ADDRH = 0x80;               //Data ptr point to non-EEPROM area
  131.     IAP_ADDRL = 0;                  //Clear IAP address to prevent misuse
  132. }


  133. /************************************************************************
  134. 函数名称:字节写
  135. 全局变量:无
  136. 参数说明:addr:写入地址, dat:写入数据
  137. ************************************************************************/
  138. void byte_write(uint addr,uchar dat)
  139. {
  140.         IAP_CONTR = ENABLE_IAP;         //Open IAP function, and set wait time
  141.     IAP_CMD = CMD_PROGRAM;          //Set ISP/IAP/EEPROM PROGRAM command
  142.     IAP_ADDRL = addr;               //Set ISP/IAP/EEPROM address low
  143.     IAP_ADDRH = addr >> 8;          //Set ISP/IAP/EEPROM address high
  144.     IAP_DATA = dat;                 //Write ISP/IAP/EEPROM data
  145.     IAP_TRIG = 0x46;                //Send trigger command1 (0x46)
  146.     IAP_TRIG = 0xb9;                //Send trigger command2 (0xb9)
  147.     _nop_();
  148.     _nop_();   
  149.         _nop_();   
  150.         _nop_();
  151.     IapIdle();   


  152. }


  153. /************************************************************************
  154. 函数名称:扇区擦除
  155. 全局变量:无
  156. 参数说明:sector_addr:扇区地址
  157. ************************************************************************/
  158. void SectorErase(uint addr)
  159. {
  160.         IAP_CONTR = ENABLE_IAP;         //Open IAP function, and set wait time
  161.     IAP_CMD = CMD_ERASE;            //Set ISP/IAP/EEPROM ERASE command
  162.     IAP_ADDRL = addr;               //Set ISP/IAP/EEPROM address low
  163.     IAP_ADDRH = addr >> 8;          //Set ISP/IAP/EEPROM address high
  164.     IAP_TRIG = 0x46;                //Send trigger command1 (0x46)
  165.     IAP_TRIG = 0xb9;                //Send trigger command2 (0xb9)
  166.     _nop_();
  167.     _nop_();   
  168.         _nop_();   
  169.         _nop_();
  170.         IapIdle();

  171. }

  172. /************************************************************************
  173. 函数名称:字节读函数
  174. 全局变量:无
  175. 参数说明:addr:所要读取的地址
  176. 返回说明:读取到的数据
  177. ************************************************************************/
  178. uchar byte_read(uint addr)
  179. {
  180.     uchar dat;                       //Data buffer

  181.     IAP_CONTR = ENABLE_IAP;         //Open IAP function, and set wait time
  182.     IAP_CMD = CMD_READ;             //Set ISP/IAP/EEPROM READ command
  183.     IAP_ADDRL = addr;               //Set ISP/IAP/EEPROM address low
  184.     IAP_ADDRH = addr >> 8;          //Set ISP/IAP/EEPROM address high
  185.     IAP_TRIG = 0x46;                //Send trigger command1 (0x46)
  186.     IAP_TRIG = 0xb9;                //Send trigger command2 (0xb9)
  187.     _nop_();
  188.     _nop_();   
  189.         _nop_();   
  190.         _nop_();



  191.     dat = IAP_DATA;                 //Read ISP/IAP/EEPROM data

  192.         IapIdle();

  193.     return dat;                     //Return Flash data
  194. }



  195. /*****************************
  196. 主程序
  197. ******************************/

  198. void main()        
  199. {
  200.         uchar i;
  201. /***********************************按复位键下载***********************************************************/        
  202.         if((PCON&0x10)==0) //如果POF位=0   不是上电复位
  203.         {     PCON=PCON|0x10;  //将POF位置1  此处置1是为了下一条语句复位的时候不进入此函数   
  204.               ISP_CONTR=0x60;  //软复位,从ISP监控区启动   复位完成 ISP_CONTR 寄存器的值是多少???
  205.         }  
  206.         else  
  207.         {     
  208.           PCON=PCON&0xef;  //将POF位清零
  209.         }
  210. /***********************************按复位键下载***********************************************************/
  211.         
  212.         wifi_power = 0;
  213.         IR_REV = 1;
  214.         
  215.         P1M0  = 0;
  216.         
  217.         P1M1  = 0x02; //定义P1.1为推挽输出
  218.         
  219.         P3M0  = 0;
  220.         
  221.         P3M1  = 0xA0; //定义P3.5 P3.7为推挽输出
  222.         
  223.         SW_WIFI_DL = 1;
  224.         
  225.         TIMER0_INIT();
  226.         serial_init();
  227.         DEBUG_LED = 1;
  228.         
  229.         while(1)
  230.         {
  231.                  PCON = 0X01;
  232.                     _nop_();
  233.                     _nop_();   
  234.                         _nop_();   
  235.                         _nop_();
  236.                
  237.                   r_string();
  238.                   if(r_comp == 1)
  239.                   {
  240.                         r_comp = 0;
  241.                
  242.                         if(tp[0] == 0)
  243.                                         {
  244.                                                 study_send_switch = 1;         //学习状态
  245.                                         }
  246.                         
  247.                          else if(tp[0] == 0x15)
  248.                                         {
  249.                                                 study_send_switch = 0;         //发射状态
  250.                                         }
  251.                         else if(tp[0] == 0x16)
  252.                                         {
  253.                                                 HS0038_power = 1;
  254.                                                 wifi_power = 1;
  255.                                                 IR_SEND = 1;
  256.                
  257.                                                 PCON=2;
  258.                                                 _nop_();
  259.                                                 _nop_();
  260.                                                 _nop_();
  261.                                                 _nop_();                        
  262.                
  263.                                         }
  264.                                 else
  265.                                            {
  266.                                                  EA = 0;
  267.                
  268.                                                  switch(tp[0])
  269.                                                   {
  270.                                                 
  271.                 //                                   case 0x00: study_send_switch = !study_send_switch;break;
  272.                                                    case 0x01: addr = 0;        break;
  273.                                                    case 0x02: addr = 0x200;        break;
  274.                                                    case 0x03: addr = 0x400;        break;
  275.                                                    case 0x04: addr = 0x600;        break;
  276.                                                    case 0x05: addr = 0x800;        break;
  277.                                                    case 0x06: addr = 0xa00;        break;
  278.                                                    case 0x07: addr = 0xc00;        break;
  279.                                                    case 0x08: addr = 0xe00;        break;
  280.                                                    case 0x09: addr = 0x1000;break;
  281.                                                    case 0x0a: addr = 0x1200;break;
  282.                                                    case 0x0b: addr = 0x1400;break;
  283.                                                    case 0x0c: addr = 0x1600;break;
  284.                                                    case 0x0d: addr = 0x1800;break;
  285.                                                    case 0x0e: addr = 0x1a00;break;
  286.                                                    case 0x0f: addr = 0x1c00;break;
  287.                                                    case 0x10: addr = 0x1e00;break;
  288.                                                    case 0x11: addr = 0x2000;break;
  289.                                                    case 0x12: addr = 0x2200;break;
  290.                                                    case 0x13: addr = 0x2400;break;
  291.                                                    case 0x14: addr = 0x2600;break;
  292.                
  293.                
  294.                                                      default: addr = 0x8000;break;                                
  295.                                                 
  296.                                                 }
  297.                
  298.                                                 if(study_send_switch)
  299.                                                                  {
  300.                                                                         HS0038_power = 0;
  301.                
  302.                                                                         for(i = 0;i < 5;i++)
  303.                                                                         {
  304. ……………………

  305. …………限于本文篇幅 余下代码请从51黑下载附件…………
复制代码

所有资料51hei提供下载:
wifi红外学习遥控源代码V1.0.zip (13.48 KB, 下载次数: 203)
wifi红外遥控PCB工程V1.0.zip (437.44 KB, 下载次数: 197)


评分

参与人数 1黑币 +50 收起 理由
admin + 50 共享资料的黑币奖励!

查看全部评分

分享到:  QQ好友和群QQ好友和群 QQ空间QQ空间 腾讯微博腾讯微博 腾讯朋友腾讯朋友
收藏收藏20 分享淘帖 顶1 踩
回复

使用道具 举报

沙发
ID:67537 发表于 2019-4-20 22:12 | 只看该作者
请教下,这个HS0038接收头电源端为什么要接一个8550三极管由单片机来控制电源端,有什么其他作用吗,还有个问题,为什么还要额外增加一个单片机,这个8266本身就有红外功能的,另外这个电路如何修改成对射的红外线报警器
回复

使用道具 举报

板凳
ID:251820 发表于 2019-4-26 10:12 | 只看该作者
自学习行的
回复

使用道具 举报

地板
ID:189467 发表于 2019-4-26 13:44 | 只看该作者
2016年的丝印,学习学习
回复

使用道具 举报

5#
ID:609432 发表于 2019-12-27 16:26 | 只看该作者
谢谢分享 学习
回复

使用道具 举报

6#
ID:666656 发表于 2019-12-28 20:17 | 只看该作者
谢谢分享,最近正好在接触!
回复

使用道具 举报

7#
ID:517951 发表于 2020-11-15 16:25 | 只看该作者
不错,值得学习。51hei有你更精彩!!
回复

使用道具 举报

8#
ID:100247 发表于 2021-4-5 09:17 | 只看该作者
你好,设计的很周全,文中没有说明ESP8266模块起到什么作用,应该只是串口通讯吧,没参与红外的学习和发送动作吧?
回复

使用道具 举报

9#
ID:758532 发表于 2021-9-18 21:26 | 只看该作者

不错,值得学习。51hei有你更精彩!!
回复

使用道具 举报

10#
ID:860003 发表于 2023-2-23 15:18 | 只看该作者
不错,刚要找这个来学习。控制家里的电热水器!!
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

手机版|小黑屋|51黑电子论坛 |51黑电子论坛6群 QQ 管理员QQ:125739409;技术交流QQ群281945664

Powered by 单片机教程网

快速回复 返回顶部 返回列表