立即注册 登录
返回首页

uid:262的个人空间

日志

STC15f104模拟315M 2272解码程序 315M解码 _单路遥控开关

已有 4870 次阅读2016-8-15 16:05 | 学习型, 继电器, 程序, 开关


原帖:http://www.51hei.com/bbs/dpj-54638-1.html
// STC15f104模拟315M 2272解码程序
// 工作频率:12M
//说明:1路继电器输出,1LED指示,1微动开关K1。
//      按K1进入编辑模式,LED指示灯亮。
//      在编辑模式下 ,按下遥控器钮,存储有效的遥控码,退出编辑模式。
//      在编辑模式下 ,按K1退出编辑模式。
//      在编辑模式下 ,长按K1 (10S) 删除所有存储的遥控码。
//      在正常模式下 , 按下遥控器钮,及LED与继电器亮灭。 
//优点: 能接收2262的1.2M-4.7M电阻编码,几乎所有的315M遥控器都兼容。
//      由于定时读引脚,抗干扰能力强 ,和硬件解码距离无区别。
//缺点:占用单片机资源比较多。能存储20条编码。

//#include <reg52.h>
#include "stc15f104w.h"
#include "flash.h"  
typedef unsigned int u16;  //16位无符号整型数
typedef unsigned char u8;  //8位无符号整型数

sbit IR_INPUT = P3^3;
sbit KEY1 = P3^1;
sbit JD1 = P3^5;
sbit led1 = P3^2;

u8 T0RL = 0;  //T0重载值的低字节
u8 ms =1;
u8 ircodex[3]; //解码最终值
u8 ircode[6];  //解码中间值 
u8 code Tm_bz[]={ 31 ,156 ,114 ,134 ,2 ,16 ,8 };
//基准:0-1同步码时间范围,  2-3 同步码124a范围,  4-5 宽窄脉冲码4-12a范围,  5 宽窄脉冲码中间值
// 遥控码发射时钟=1a,   1M电阻:1a=31us 5M电阻:1a=156us     
//由于51单片机中断时间过短只能到 60us  用stc15f104的1T模式(同时钟频率下是51单片机6-12倍)————全兼容
bit WanCengBiaoJi = 0; // 读完一组数据的标记
u8 code YaoKongSu_4 = 4 ;      //遥控码个数
u8 code DaiMaTiaoSu_20 = 20 ; //遥控条数
bit Bianji = 0; //进入编辑标记
u8 E2BiaoJi; 
u8 Tm1[50]; //0空位 1-24遥控码脉冲 25同步码 26-50第二次遥控码脉冲

void ConfigTimer0(u8 ms);
void ConfigTimer2(u8 ms);
void xunhuanculi(bit add);
void Bian_ji();
void Led_jia();
void Flash_del();
void LED_jh(bit dat);
void Caozuo_csh();


void main()
{
    EA = 1;      //开总中断
IR_INPUT = 1;  //接收引脚
    ConfigTimer2(5);     //配置T2定时 ms
    ConfigTimer0(124);   //配置T0定时 0-255us   
    WDT_CONTR=0x37;     //喂狗  8.4S
    Caozuo_csh();

    while (1)
    {
         
 if(WanCengBiaoJi == 1)
 {        WanCengBiaoJi = 0;
  xunhuanculi(0);//Tm1[50] 1-24脉冲解码
  xunhuanculi(1);//Tm1[50] 25-50脉冲解码

  if((ircode[0]==ircode[3]) && (ircode[1]==ircode[4]) && (ircode[2]==ircode[5]) && ms!=0) //2次编码比较
  {
  if((ircodex[0]==ircode[0]) && (ircodex[1]==ircode[1]) && (ircodex[2]==ircode[2]))
{    ms=1; }
else   //ircodex[3] 的值保存 0.75S 后清零
  // ms=1; 延续 ircodex[3]的值, ms=0; 启动下一级比较
{
ircodex[0]=ircode[0];
ircodex[1]=ircode[1];
ircodex[2]=ircode[2];  
if(Bianji==1)
        { ms = 1; Led_jia();}
else
{ ms=0;}
}
}
 
                        ET0 = 1; 
 }
 
    }
}
//脉冲解码
void xunhuanculi(bit add)
{
        u8 i, j, x, m, dat;
        u8 byt;
x = add*25+1;
m = add*3;
        for(i=0; i<3; i++)
        {    dat=i*8;
    for(j=0; j<8; j++)
{      if(Tm1[dat+j+x]<=Tm_bz[6])
{  byt <<= 1; byt |= 0x01; }
else 
{  byt <<= 1; }

}
    ircode[i+ m ] = byt;
    }

}
//LED指示 继电器处理
void LED_jh(bit dat)
{   
     led1 = dat;
if(Bianji==0)
{ JD1 = dat;}
}
//初始化 
void Caozuo_csh()
{
Bianji=0; 
LED_jh(0);   
   
P3M1= 0x08; // P3.1准双向 P3.2推挽 P3.3高阻 P3.5推挽  
P3M0= 0x24;  
 
}

//删除Flash内的编码
void Flash_del()
{  if(Bianji==1)
   {  eeprom_erase(0); Caozuo_csh(); }
}
//进入 退出编辑模式
void Bian_ji()
{   u8 i;

if(Bianji==0)
{ Bianji=1;
 
 P3M1= 0x28;  // P3.1准双向 P3.2开漏 P3.3高阻 P3.5开漏
      P3M0= 0x24;  
 LED_jh(1); 
 //读出没有遥控码的空位
 E2BiaoJi=0xff;
      for(i=0; i<DaiMaTiaoSu_20; i++)
      {  
       if(eeprom_read(i*4)==0xff)
     {E2BiaoJi=i; break;}
      }
}
  else
    { Caozuo_csh(); }
 
}
//在编辑模式下,遥控器按一下,写入一条有效的遥控码
void Led_jia()
{       //把有效的遥控码写入Flash
  u8 dat;
   if (E2BiaoJi!= 0xff )
        {      dat= E2BiaoJi*YaoKongSu_4;  
      eeprom_write(dat,0); //标记以写入 
  eeprom_write(dat+1,ircodex[0]);
  eeprom_write(dat+2,ircodex[1]);
  eeprom_write(dat+3,ircodex[2]);

}
  Caozuo_csh();

}   


/* 配置并启动T2,ms-T2定时时间 */
void ConfigTimer2(u8 ms)
{
    unsigned long tmp;  //临时变量
    
    tmp = 12000000 / 12;      //定时器计数频率
    tmp = (tmp * ms) / 1000;  //计算所需的计数值
    tmp = 65536 - tmp;        //计算定时器重载值
    tmp = tmp + 18;           //补偿中断响应延时造成的误差
    T2H = (u8)(tmp>>8);  //定时器重载值拆分为高低字节
    T2L = (u8)tmp;
   
AUXR &= 0xEF;  // 启动T2定时器  方式 :16位重装模式计数器
AUXR |= 0x10;  // 启动T2定时器
    IE2 &= 0xFB;  // 使能T2中断
IE2 |= 0x04;  // 使能T2中断
   
    //ET2 = 1;        //使能T2中断
    //T2R = 1;        //启动T2定时器
}
/* 配置并启动T0,us-T0定时时间 */
void ConfigTimer0(u8 ms)
{
    u8 tmp;  //临时变量

    tmp = 256 -ms ;        //计算定时器重载值
TMOD &= 0xF0;  // 定时器工作方式  方式 :8位重装模式计数器
TMOD |= 0x02;  //配置T0为模式2
T0RL = tmp;
TH0 = tmp;     //加载T0重载值
    ET0 = 1;        //使能T0中断
    TR0 = 1;        //启动T0
PT0 = 1;        //配置T0中断为高优先级
}
/* 中断函数 读出同步码+24位遥控编码 2次 */
void EXINT1_ISR() interrupt 1
{  static bit a1,a2,a3; 
 static u8 Tm_zz=0;
 static u8 Tm_js=0;
      static u8 Tm=0;

 
 //抗干扰用
      a3=a2;
      a2=a1;
 a1=IR_INPUT;
 if(a1==a3)
 {a2=a1;}
//========
/*同步头124a  窄脉冲4a 宽脉冲12a
  ==============================
  定义中断为124a
  Tm=0时 算出1a所用时间us数 
  从定义中断为1a所用时间us数
  则 同步头124个us数 窄脉冲4个us数  宽脉冲12个us数
 */
if(a3)
 {      
switch(Tm_zz)
   {
case 0:      if(Tm==0)
            {  
    if((Tm_js<Tm_bz[0] )|| Tm_js>Tm_bz[1])
{ Tm_zz=0; Tm=0; Tm_js=0; TH0 = T0RL; }
else
  {  Tm++; Tm_zz=2; TH0 = 256- Tm_js; TL0=TH0;}
}
else
{ if((Tm_js<Tm_bz[2] )|| Tm_js>Tm_bz[3] )
{  Tm_zz=0; Tm=0; Tm_js=0; TH0 = T0RL; } 
  else
  { Tm1[Tm]=256-TH0; Tm++; Tm_zz=2;}
}
break;
case 1:   if((Tm_js<Tm_bz[4] )|| Tm_js>Tm_bz[5])
{ Tm_zz=0; Tm=0; Tm_js=0; TH0 = T0RL; }  
else
{ Tm1[Tm]=Tm_js; Tm++; Tm_zz=2;}
break;
case 2:     if( Tm==25)
{Tm_zz=3;}
            if( Tm>=50)
{ ET0 = 0;  WanCengBiaoJi =1; Tm_zz=0; Tm=0; Tm_js=0; TH0 = T0RL; }
break;
default:break;
   }

 }
else
{    
       switch(Tm_zz)
   {
case 0:  Tm_js++; break;
case 1:  Tm_js++; break;
case 2:  Tm_js=1; Tm_zz=1; break;
case 3:  Tm_js=1; Tm_zz=0; break;
   default:break;
   }
 

}
 
}

//遥控码与存储的遥控码比较处理

void chamiao()
{ u8 i,dat;
bit j;
ms++;
if(ms == 1)
 EA=0 ;
 
 for(i=0; i<DaiMaTiaoSu_20; i++)
 {    dat= i*YaoKongSu_4;
       if(eeprom_read(dat)==0)
{ if(eeprom_read(dat+1)==ircodex[0])
    {  if(eeprom_read(dat+2)==ircodex[1])
 {   if(eeprom_read(dat+3)==ircodex[2])
      {    j= !led1;
_nop_();
led1 = j;
JD1 = j; 
  break;
  }
 }
}
}
else
{break;}
      
 }

 EA=1 ;

}
if(ms > 150 )
{//按下0.75S后清除遥控码 作用:遥控器连按误动作
ircodex[0]=0x00;
ircodex[1]=0x00;
ircodex[2]=0x00;
ms = 1;
}

  
}

//按钮扫描 需在定时中断中调用
void anjian()
{ static u16 JiShu=0;
    static bit J=0;
    static u8 keybuf = 0xff;

keybuf = (keybuf <<1) |KEY1;
if(keybuf == 0x00)
{ //在编辑模式下大于10S LED闪烁即可删除Flash存储 
 JiShu++;  
 if(JiShu>=1000)
 {  if(Bianji==1)
 {   JiShu=950;
 J=!J; 
 led1=J;
          }
 else
 {JiShu=1;}
 }
}
else if(keybuf == 0xFF)
{
 if(JiShu>0)
 { if(JiShu<950)//10S删除Flash存储的遥控码
    {Bian_ji();}
    else
    {Flash_del();}//小于10S进入编辑模式
JiShu=0;
 }
 
}

}
/* T0中断服务函数,执行数码管扫描显示 */
void InterruptTimer2() interrupt 12
{
anjian();
    chamiao();
   WDT_CONTR=0x37;     //喂狗  8.4S

}

路过

鸡蛋

鲜花

握手

雷人

全部作者的其他最新日志

评论 (0 个评论)

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

Powered by 单片机教程网

返回顶部