单片机论坛

 找回密码
 立即注册

QQ登录

只需一步,快速开始

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

433M无线遥控插座单片机解码程序与PCB文件资料

  [复制链接]
跳转到指定楼层
楼主
433遥控插座。STC15单片机,PCB文件使用PADS打开。程序用keil打开。


单片机源程序如下:

  1. #include <stc15.h>
  2. #include <intrins.h>


  3. #define uchar unsigned char
  4. #define uint  unsigned int
  5.                                

  6. //sbit RF                  =        P0^5;           //信号输入       
  7. //sbit LED                =        P3^4;           //学习指示灯                                                  
  8. //sbit set                 =        P1^4;          //学习按键                                       
  9. //sbit D0                        =        P4^2;          //解码输出
  10. //sbit D1                        =        P3^7;
  11. //sbit D2                        =        P4^1;

  12. sbit RF                  =        P3^0;           //信号输入       
  13. sbit LED                =        P3^2;           //学习指示灯                                                  
  14. sbit set                 =        P3^3;          //学习按键                                       
  15. sbit D0                        =        P3^4;          //解码输出

  16. int KB;
  17. int kk;///定时器初始值
  18. int nn;        ///定时器溢出寄存器       
  19. bit  decode_ok;                 //解码成功
  20. bit rf_ok;               //收到有效数据
  21. bit study;         //学习标志
  22. bit jmnx;  //编码类型 0是2262,1是1527
  23. uchar da1527[2][3];  //解码过程中临时数组
  24. uchar key_d;  //遥控器按键码
  25. uchar short_k;     //窄脉冲宽度


  26. uchar idata key_number[60];                //遥控器编码数组,存放60个遥控器


  27. void delay_1ms(uint x)    //1毫秒延时
  28. {
  29.         uchar b,c;
  30.         for(x;x>0;x--)
  31.                 {
  32.                         for(b=3;b>0;b--)
  33.                                 {
  34.                                         for(c=150;c>0;c--);
  35.                                 }
  36.                 }
  37. }

  38. void delay(uint ms)//
  39. {
  40.   while(ms--)
  41.     {
  42.          ms++;
  43.          ms++;
  44.          ms--;
  45.          ms--;
  46.     }
  47. }




  48. //====================================================
  49. /////////片内EEPROM读写驱动程序///////////////////////////
  50. //====================================================


  51. void IAP_Disable()           //关闭IAP
  52. {
  53.     //关闭IAP 功能, 清相关的特殊功能寄存器,使CPU 处于安全状态,
  54.     //一次连续的IAP 操作完成之后建议关闭IAP 功能,不需要每次都关
  55.     IAP_CONTR = 0;      //关闭IAP 功能
  56.     IAP_CMD   = 0;      //清命令寄存器,使命令寄存器无命令,此句可不用
  57.     IAP_TRIG = 0;      //清命令触发寄存器,使命令触发寄存器无触发,此句可不用
  58.     IAP_ADDRH = 0;
  59.     IAP_ADDRL = 0;
  60. }//



  61. //读一字节,调用前需打开IAP 功能,入口:DPTR = 字节地址,返回:A = 读出字节
  62. uchar read_add(uint addr)         //读EEPROM
  63. {
  64.     IAP_DATA = 0x00;
  65.     IAP_CONTR = 0x84;         //打开IAP 功能, 设置Flash 操作等待时间
  66.     IAP_CMD = 0x01;                 //IAP/ISP/EEPROM 字节读命令

  67.     IAP_ADDRH = addr>>8;    //设置目标单元地址的高8 位地址
  68.     IAP_ADDRL = addr&0xff;    //设置目标单元地址的低8 位地址

  69.     EA = 0;
  70.     IAP_TRIG = 0x5a;   //先送 46h,再送B9h 到ISP/IAP 触发寄存器,每次都需如此
  71.     IAP_TRIG = 0xa5;   //送完 B9h 后,ISP/IAP 命令立即被触发起动
  72.     _nop_();
  73.     EA = 1;
  74.     IAP_Disable(); //关闭IAP 功能, 清相关的特殊功能寄存器,使CPU 处于安全状态,
  75.                     //一次连续的IAP 操作完成之后建议关闭IAP 功能,不需要每次都关
  76.     return (IAP_DATA);
  77. }//------------------------------------------------------------------------------


  78. //字节编程,调用前需打开IAP 功能,入口:DPTR = 字节地址, A= 须编程字节的数据
  79. void write_add(uint addr,uchar ch)         //直接写EEPROM
  80. {
  81.     IAP_CONTR = 0x84;         //打开 IAP 功能, 设置Flash 操作等待时间
  82.     IAP_CMD = 0x02;                 //IAP/ISP/EEPROM 字节编程命令


  83.     IAP_ADDRH = addr>>8;    //设置目标单元地址的高8 位地址
  84.     IAP_ADDRL = addr&0xff;    //设置目标单元地址的低8 位地址

  85.     IAP_DATA = ch;                  //要编程的数据先送进IAP_DATA 寄存器
  86.     EA = 0;
  87.     IAP_TRIG = 0x5a;   //先送 46h,再送B9h 到ISP/IAP 触发寄存器,每次都需如此
  88.     IAP_TRIG = 0xa5;   //送完 B9h 后,ISP/IAP 命令立即被触发起动
  89.     _nop_();
  90.     EA = 1;
  91.     IAP_Disable(); //关闭IAP 功能, 清相关的特殊功能寄存器,使CPU 处于安全状态,
  92.                     //一次连续的IAP 操作完成之后建议关闭IAP 功能,不需要每次都关
  93. }//------------------------------------------------------------------------------
  94. //擦除扇区, 入口:DPTR = 扇区地址


  95. void Sector_Erase(uint addr)         //扇区擦除
  96. {
  97.      IAP_CONTR = 0x84;         //打开IAP 功能, 设置Flash 操作等待时间
  98.     IAP_CMD = 0x03;                 //IAP/ISP/EEPROM 扇区擦除命令

  99.     IAP_ADDRH =addr>>8;    //设置目标单元地址的高8 位地址
  100.     IAP_ADDRL =addr&0xff;    //设置目标单元地址的低8 位地址

  101.     EA = 0;
  102.     IAP_TRIG = 0x5a;   //先送 46h,再送B9h 到ISP/IAP 触发寄存器,每次都需如此
  103.     IAP_TRIG = 0xa5;   //送完 B9h 后,ISP/IAP 命令立即被触发起动
  104.     _nop_();
  105.     EA = 1;
  106. }//------------------------------------------------------------------------------



  107. //============================接收解码部分========================================//

  108. void RF_decode()          
  109. {
  110.           uchar ii=0,j=0,k=0,rep=0;
  111.             uint head_k=0;           //短脉冲宽度
  112.           uchar s;   
  113. //-------------------------------数据接收-----------------------------------------
  114.       short_k=0;
  115.           while(RF && short_k<255)         //检测头信号前一个高脉冲的宽度
  116.                    {
  117.                          delay(1);       
  118.                         short_k++;
  119.                  }
  120.           while(!RF)
  121.                    {
  122.                          delay(1);
  123.                         head_k++;
  124.                  } //检测头脉冲的宽度         
  125.       if(((short_k*24)<head_k) && (head_k<(short_k*38)))   //引导码宽度是窄脉冲的32倍 24/38
  126.          {       
  127.             for(rep=0;rep<2;rep++)         
  128.                {  
  129.                              for(ii=0;ii<3;ii++)//3字节
  130.                              {
  131.                                    for(k=0;k<8;k++)//每个字节8位
  132.                                       {                                     
  133.                                                     j=0;
  134.                                                         while(RF && j<245)
  135.                                                                 {
  136.                                                                         delay(1);
  137.                                                                         j++;
  138.                                                                 }//
  139.                                                if(j>(short_k-short_k/2-short_k/3)&&j<(short_k*2))
  140.                                                                 {
  141.                                                                         da1527[rep][ii]&=~(1<<((7-k)));
  142.                                                                 }                                    
  143.                                                         else if(j>(short_k*2)&&j<(short_k*5))da1527[rep][ii]|=(1<<(7-k));                                                 
  144.                                                 else {return;}          //乱码退出       
  145.                                                j=0;
  146.                                                         while(!RF && j<150){delay(2);j++;}      //跳过低电平                                  
  147.                                                  }
  148.                                  }//for(ii=0;ii<12;ii++)  
  149.                    j=0;while(RF && (j<200)){delay(1);j++;}            //跳个最后一个高脉冲                          
  150.                                head_k=0;while(!RF) {delay(1);head_k++;} //检测下一个前导信号的寬度  
  151.                                if((head_k<(short_k*26)) || (head_k>(short_k*38)))  {return;} //引导码宽度是窄脉冲的32倍  //乱码退出
  152.                            }
  153.             //+++++++++++++++++++++++++2262与1527数据分离处理++++++++++++++++++++++++++++++++++++++++             
  154.                          if((da1527[0][0]==da1527[1][0]) && (da1527[0][1]==da1527[1][1]) && (da1527[0][2]==da1527[1][2]))        //两次接收到的数据相同
  155.                       {          
  156.                      uchar u,i,x;
  157.                                          rf_ok=1;
  158.                                          for(i=0;i<3;i++)  //判定2262与1527
  159.                         {
  160.                            for(u=0;u<4;u++) {if(((da1527[0][i]>>(u*2)) & 3)==2) {i=80;break;}}  //有10则为1527
  161.                                                    if(i==80) break;
  162.                         }
  163.                      if(i==80)  //1527
  164.                         {
  165.                           key_d=da1527[1][2] & 0x0f;         //分出1527的按键值
  166.                           da1527[0][2]=da1527[1][2]>>4; //分出1527的后4位地址
  167.                                                   jmnx=1;         //为0是2262,1是1527
  168.                         }
  169.                        else      //2262
  170.                          {
  171.                           key_d=0;
  172.                           for(i=0;i<4;i++){if(((da1527[0][2]>>(i*2))&3)==3) key_d|=1<<i;}   //计算出2262的按键数据                                 
  173.                           da1527[0][2]=00; //2262无后4位地址,全为0
  174.                                                   jmnx=0;         //为0是2262,1是1527
  175.                          }
  176.                                                   
  177.                                           if (!study)                //非学习状态
  178.                                                   {
  179.                                                         rf_ok=0;
  180.                                                         for(x=0;x<60;x++)
  181.                                                                    {
  182.                                                                         if((da1527[0][0]==key_number[x*3+1])&&(da1527[0][1]==key_number[x*3+2])
  183.                                                                                                                                         &&(da1527[0][2]==key_number[x*3+3]))//判断是否已学习过的编码
  184.                                                                                 {
  185.                                                         //  D0=key_d&0x08;                //取得按键码
  186.                                                                                 //        D0=key_d&0x04;
  187.                                                                                 //        D0=key_d&0x02;
  188.                                                                                 //        D0=key_d&0x01;
  189.                                                                                         if(key_d==0x04)
  190.                                                                                         {
  191.                                                                                         D0=0;
  192.                                                                                         LED=0;
  193.                                                                                                 } else if(key_d==0x08)

  194.                              {
  195.                                                                                                       D0=1;
  196.                                                                                                                          LED=1;
  197.                                                                                                                  }
  198.                                                                                                                                                                                
  199.                                                                                         decode_ok=1;
  200.                                                                                         //VT=0;                                                               
  201.                                                                                         s=100;
  202.                                                                                         break;
  203.                                                                                 }
  204.                                                                                                                
  205.                                                                 }       
  206.                                                
  207.                                                
  208.                                                 }
  209.                            
  210.                  }
  211.              
  212.          }
  213.         if(decode_ok)   //解码有效信号,类似2272 PT脚
  214.                   {
  215.                         s--;
  216.                         if(!s)
  217.                                 {
  218.                                         decode_ok=0;
  219.                                         //VT=1;
  220.                                 }                                  
  221.                   }         
  222.                                   
  223.                   
  224. }

  225. void key_buffer()                  //把遥控器码从 EEPROM 复制到DATA
  226. {
  227.         uchar n;

  228.         for(n=0;n<60;n++)
  229.                 {
  230.                    key_number[n]=read_add(0x0000+n);                       
  231.                 }
  232. }

  233. void KEY_study()        //遥控器学习
  234. {       
  235.         uchar num_rf;
  236.         uint d_num;
  237.         if(study)
  238.                 {
  239.                            rf_ok=0;
  240.                         d_num=0;
  241.        
  242.                         while(!rf_ok)
  243.                                 {
  244.                                         RF_decode();
  245.                                         d_num++;
  246.                                         if(d_num>50000) break;                                                                       
  247.                                 }
  248.                         d_num=0;
  249.                         if(rf_ok==1)
  250.                                 {

  251.                                         num_rf=key_number[0];                   //取已学习的遥控器数量
  252.                                         if(num_rf>60){num_rf=0;}        //如果遥控器数量超过10个,覆盖最先学习的
  253.                                         key_number[num_rf*3+1]=da1527[0][0];
  254.                                         key_number[num_rf*3+2]=da1527[0][1];
  255.                                         key_number[num_rf*3+3]=da1527[0][2];
  256.                                         key_number[0]=num_rf+1;

  257.                                         Sector_Erase(0x0000);
  258.                                         for(num_rf=0;num_rf<60;num_rf++)
  259.                                                 {
  260.                                                         write_add(0x0000+num_rf,key_number[num_rf]);
  261.                                                        
  262.                                                 }
  263.                                         rf_ok=0;
  264.                                         LED=1;                   //学习成功       
  265.          EA=0;     //允许总中断
  266.         TR0=0;    //启动定时器0                                               
  267.                                   }       
  268.                                 else
  269.                                         {
  270.                                                 rf_ok=0;

  271.                                                 for(num_rf=0;num_rf<8;num_rf++)                   //操作超时
  272.                                                         {
  273.                                                                 LED=!LED;
  274.                                                                 delay_1ms(100);                                                       
  275.                                                         }
  276.                                                  LED=0;
  277.                                        
  278.                                         }
  279.                         d_num=0;
  280.                         study=0;                 
  281.                 }
  282. }

  283. void system_res()  //系统清零          
  284. {
  285.        
  286.           Sector_Erase(0x0000);       
  287.         write_add(0x0000,0x00);
  288.         Sector_Erase(0x0200);       
  289.         write_add(0x0200,0x00);
  290.         Sector_Erase(0x0400);               
  291.         key_buffer();

  292.         delay_1ms(2000);
  293.     IAP_CONTR=0x20;       

  294. }

  295. void set_scan()          //判断学习键状态
  296. {
  297.   uchar h=0;

  298.                
  299.                        
  300.                        
  301.                                 while(!set)
  302.                                 {
  303.                        
  304.                 if(h>5 && h< 60)
  305.                         {
  306.                                 study=0;
  307.                         LED=!LED;
  308.                                 D0=!D0;
  309.                                 h=0;
  310.        
  311.                                 while(!set)
  312.                                         {
  313.                                           delay_1ms(300);
  314.                                           h++;
  315.                                                 if(h >60 && h<100)
  316.                                                        
  317.                                         {
  318.                                         kk=20;
  319.                                                        
  320.                            EA=1;     //允许总中断
  321.         TR0=1;    //启动定时器0
  322.                                                 if(set==1)
  323.                                                 {
  324.                                                         study=1;
  325.                                                 }
  326.                                         }
  327.                        
  328.                         //        KEY_study();
  329.                                
  330.                                        
  331.                                                 if(h > 150)
  332.                                                 {
  333.                                        
  334.                                                 kk=90;
  335.                                                         delay_1ms(20000);
  336.                                                 study=0;
  337.                                                         h=0;
  338.                                                         system_res();
  339.                                                         LED=0;
  340.                                                         D0=0;
  341.                                                 //        delay_1ms(2000);
  342.                                                         while(!set);
  343.                                                 }
  344.                                        
  345.                                         }
  346.                                 }
  347.                        
  348.                        
  349.                        
  350.                
  351.        
  352.                  delay_1ms(100);
  353.                   h++;
  354.          }               
  355.        
  356.   if(study)
  357.                 {
  358.                         KEY_study();
  359.                 }         
  360. }

  361. void system_start()   //上电初始化
  362. {       
  363.         TMOD &= 0xF0;   //定时器0运行在模式0 ,13位计数器
  364.                 // GATE0=0; C/T0#=0; M1=0; M0=0;
  365. TH0 = 0x00;     //设置初值0x00,所以计数值为8192,若是时钟频率为12MHz
  366. TL0 = 0x00;     //则8192μs中断一次
  367. ET0=1;    //允许定时器0中断

  368.         AUXR=0x95;

  369.         P3M0=0x14;


  370. ……………………

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

所有资料51hei提供下载:
遥控插座.rar (117.85 KB, 下载次数: 95)
遥控插座程序.rar (46.34 KB, 下载次数: 102)



评分

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

查看全部评分

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

使用道具 举报

沙发
fzfrd 发表于 2018-8-18 00:26 | 只看该作者
不错,学习了
回复

使用道具 举报

板凳
XBS025 发表于 2018-8-18 11:06 | 只看该作者
谢谢,很好的程序,找了好久
回复

使用道具 举报

地板
jgjgjgjg 发表于 2018-8-18 19:37 | 只看该作者
谢谢,资料不错,下来学习看看!
回复

使用道具 举报

5#
chjx0131 发表于 2018-8-19 00:23 | 只看该作者
  我做一个试试看!
回复

使用道具 举报

6#
chjx0131 发表于 2018-8-19 01:06 | 只看该作者
没有原理图,PCB资料也没有BOM 单,怎么办?
回复

使用道具 举报

7#
 楼主| gupingdn 发表于 2018-8-19 19:20 | 只看该作者
chjx0131 发表于 2018-8-19 01:06
没有原理图,PCB资料也没有BOM 单,怎么办?

不好意思。漏掉了。这两天在外面出差。回去给大家补上。
回复

使用道具 举报

8#
yong761228 发表于 2018-10-4 13:03 | 只看该作者
楼主老师,您好,您这个用2262遥控器控制需要A键开,有办法改成C键开吗?谢谢
回复

使用道具 举报

9#
leichyi 发表于 2018-10-5 08:27 | 只看该作者
标记下
回复

使用道具 举报

10#
yong761228 发表于 2018-10-17 12:44 | 只看该作者
各位师傅,楼主师傅上的是互锁功能,如何改成自锁功能,就是下面这段互锁功能 就是ABCD互相切换的,如何改成自锁,按遥控器A,A对应继电器吸合,松开遥控器按钮A,再次按一下遥控按钮A,A对应继电器断开,谢谢。          
                                          if (!study)                //非学习状态
                                                  {
                                                        rf_ok=0;
                                                        for(x=0;x<60;x++)
                                                                   {
                                                                        if((da1527[0][0]==key_number[x*3+1])&&(da1527[0][1]==key_number[x*3+2])
                                                                                                                                        &&(da1527[0][2]==key_number[x*3+3]))//判断是否已学习过的编码
                                                                                {
                                                                    D3=key_d&0x08;                //取得按键码
                                                                                    D2=key_d&0x04;
                                                                                        D1=key_d&0x02;
                                                                                        D0=key_d&0x01;
                                                                                        decode_ok=1;
                                                                                        //VT=0;                                                               
                                                                                        s=100;
                                                                                        break;
                                                                                }
                                                                                                               
                                                                }       
                                               
                                               
                                                }
                           
                 }
             
         }
        if(decode_ok)   //解码有效信号,类似2272 PT脚
                  {
                        s--;
                        if(!s)
                                {
                                        decode_ok=0;
                                        //VT=1;
                                }                                  
                  }         
                                  
                  
}
回复

使用道具 举报

11#
yong761228 发表于 2018-10-17 12:44 | 只看该作者

非常感谢!这个我懂了。
回复

使用道具 举报

12#
yong761228 发表于 2018-10-18 07:25 | 只看该作者
各位师傅,楼主师傅的互锁功能,我改成自锁程序有问题,遥控器ABCD 按每个按钮都出现对应的按键码Key-d(相当于波形,短时间里有许多相同的波形),D3 D2 D1 D0 是四个继电器,按住或者按一下遥控器按钮A,D3一直吸合,松开遥控器按钮A,再次按遥控器按钮A,D3断开;同理其它BCD也一样。我现在这样写程序出现按住遥控器按钮A, D3继电器不停的吸合 断开。看看哪位师傅帮我修改一下程序,谢谢。

if(key_d == 0x08){D3=~D3;} //当按键码是0x08的时候,D3继电器取反,问题出现在短时间里有许多个0x08 出现,就出现了不停的吸合 断开。
if(key_d == 0x04){D2=~D2;}
if(key_d == 0x02){D1=~D1;}
if(key_d == 0x01){D0=~D0;}       

回复

使用道具 举报

13#
lqsgg 发表于 2018-10-19 21:37 | 只看该作者
谢谢分享!学习学习!
回复

使用道具 举报

14#
冰冰洁洁 发表于 2018-11-7 09:16 来自手机 | 只看该作者
yong761228 发表于 2018-10-18 07:25
各位师傅,楼主师傅的互锁功能,我改成自锁程序有问题,遥控器ABCD 按每个按钮都出现对应的按键码Key-d(相 ...

加一句等待不等于0x80时再取反.
回复

使用道具 举报

15#
licpro 发表于 2018-11-9 18:27 | 只看该作者
谢谢!学习
回复

使用道具 举报

16#
职教电子 发表于 2018-11-13 11:01 | 只看该作者
本帖最后由 职教电子 于 2018-11-14 15:50 编辑

STC15W104有没有IAP功能,这个程序能不能用在STC15W104中?(已经知道了,不能。)
回复

使用道具 举报

17#
核芯 发表于 2018-11-13 12:35 | 只看该作者

谢谢!学习
回复

使用道具 举报

18#
职教电子 发表于 2018-11-17 21:50 | 只看该作者
ASC文件用PADS 9.5怎么打不开?
回复

使用道具 举报

19#
yong761228 发表于 2018-11-26 19:39 | 只看该作者
给位师傅,您好好,这个我改成非锁功能,我想支持复合按钮,就是按住遥控器按钮A,A继电器吸合,不松开手,再按遥控器按钮B,这时AB对应的都吸合,松开哪个按钮,对应的继电器断开,改如何修改程序,非常感谢。{
                                                                                   if(key_d == 0x08){D3=0;}
                                                                                   if(key_d == 0x04){D2=0;}
                                                                                   if(key_d == 0x02){D1=0;}
                                                                                   if(key_d == 0x01){D0=0;}                                                                                       
                                                                                        decode_ok=1;
                                                                                        VT=0;                                                               
                                                                                        s=30;
                                                                                        break;
                                                                                }
                                                                                                               
                                                                }       
                                               
                                               
                                                }
                           
                 }
             
         }
        if(decode_ok)   //解码有效信号,类似2272 PT脚
                  {
                        s--;
                        if(!s)
                                {
                                        decode_ok=0;
                                        D0=1;D1=1;D2=1;D3=1;
                                        VT=1;
                                }                                  
                  }         
回复

使用道具 举报

20#
职教电子 发表于 2018-11-29 09:22 | 只看该作者
注意:如果长按学习按键,不是仅仅清除记忆,而是自毁了。
回复

使用道具 举报

21#
职教电子 发表于 2018-11-30 15:25 | 只看该作者
写入IRC15W207S中不能用,改频率也不行。
回复

使用道具 举报

22#
职教电子 发表于 2018-12-1 22:12 | 只看该作者
终于改好了,用IRC15W207S最多可以控制三路。
回复

使用道具 举报

23#
WFX777888 发表于 2018-12-3 06:02 | 只看该作者
谢谢,资料不错,下来学习看看!
回复

使用道具 举报

24#
Rain2003 发表于 2018-12-10 21:15 | 只看该作者
thanks for your sharing.
回复

使用道具 举报

25#
czj7221 发表于 2019-1-11 10:29 | 只看该作者
下载下来慢慢学,谢谢楼主分享
回复

使用道具 举报

26#
WFX777888 发表于 2019-1-12 06:28 | 只看该作者
谢谢分享资料
回复

使用道具 举报

27#
didadi 发表于 2019-1-12 20:31 | 只看该作者
谢谢楼主分享
回复

使用道具 举报

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

本版积分规则

QQ|手机版|小黑屋|单片机论坛 |51黑电子论坛单片机. 联系QQ:125739409;技术交流QQ群582644647

Powered by 单片机教程网

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