pic单片机软件解码PT2240

发布者:Serendipity66最新更新时间:2016-11-17 来源: eefocus关键字:pic单片机  软件解码  PT2240 手机看文章 扫描二维码
随时随地手机看文章

1:单片机软件解码PT2240
2:选用PIC16F877A作为软件解码芯片
3:单片机时钟频率选用外部4MHZ晶振
4:选用外部中断脚作为编码信号脚输入脚
5:可解PT2240芯片(8脚的学习型编码芯片 编码地址位:2的20次方 重复几率100万分之一)
6:功能有:遥控器学习(DEMO上的S9作为学习按纽) 清除记忆(长按DEMO上的S9即可清除遥控器地址的记忆)
7:学习遥控器数量可以设定(可根据EEPROM的大小 随便设定)
8:输出功能(有三路是 单击遥控器双稳,可以通过PORTC上的LED可以看到结果.还有一路是 双击遥控器双稳)
9:可选用315MHZ/433MHZ的饿超再生/超外差接收模块

/******************************************************************************/
/****************************** 遥控器接收程序 ********************************/
/******************************************************************************/
#include <PIC.h>
#include <PIC1687x.h>
#define remote_geshu 10
/******************************************************************************/
union BIT_16
{
 int TIMER1_REG;
 unsigned char REG[2];
}
union BIT_32
{
 unsigned long data_temp_long;
 unsigned char data_temp_byte[4];
}
/******************************************************************************/
static union BIT_16 TIMER1_TEMP;//16位定时器1
static union BIT_32 data_temp;
/******************************************************************************/
static volatile unsigned char rec_status @ 97;
static unsigned char data_cout;//接收的遥控器码位数
static unsigned char data;//接收的4位数据
static unsigned int h_pulse;//高电平宽度
static unsigned int l_pulse;//低电平宽度
static unsigned char remote_cout;//遥控器数量
static unsigned char remote_numb;//遥控器编号
/******************************************************************************/
static unsigned char TIMER15S1;//清除学习码按键长按时间
static unsigned char TIMER15S2;//学习等待时间
static unsigned char TIMER15S3;//遥控器数据缓冲时间
static unsigned char TIMER15S4;//LED显示时间
static unsigned char TIMER15S5;//
static unsigned char TIMER15S6;//
static unsigned char TIMER15S7;//
static unsigned char TIMER15S8;//
/******************************************************************************/
static bit head @ ((unsigned)(&rec_status)*8+(0));//同步头标志位
static bit learn @((unsigned)(&rec_status)*8+(1));//学习标志位
static bit recieved @((unsigned)(&rec_status)*8+(2));//接收完成标志位
static bit remote_button_status @((unsigned)(&rec_status)*8+(3));//遥控器按键标志位
static bit first_click_status @((unsigned)(&rec_status)*8+(4));//遥控器按键单击标志位


/******************************************************************************/
/********************************** 数据接收 **********************************/
/******************************************************************************/
unsigned char data_read(void)
{
 if(h_pulse>l_pulse)
  {
   if((l_pulse>200)&&(l_pulse<1000))
    {
     if(h_pulse<(l_pulse<<2))return 1;//数据为1
    }
   return 2;//无效的数据
  }
 else if(h_pulse   {
   if((h_pulse>200)&&(h_pulse<1000))
    {
     if(l_pulse<(h_pulse<<2))return 0;//数据为0
    }
   return 2;//无效的数据
  }
}
/******************************************************************************/
void clr_head(void)//清除寄存器
{
 data_cout=0;
 head=0;  
}
/******************************************************************************/
#pragma interrupt_level 1
void check_data(void)//检测数据是否正确
{
 if(head)
  {
   switch(data_read())
    {
     case 0:(data_temp.data_temp_long)<<=1;;data_cout++;break;
     case 1:(data_temp.data_temp_long)<<=1;(data_temp.data_temp_long)++;;data_cout++;break;
     default:clr_head();break;
    }
   if(data_cout>23)
    {
     INTE=0;
     recieved=1;
     clr_head();//

    }
  }
}
/******************************************************************************/
#pragma interrupt_level 1
void check_head(void)
{
 if((!head)&&(!recieved))//
  {
   if((h_pulse>300)&&(h_pulse<1000))
    {
     if((l_pulse>h_pulse*27)&&(l_pulse       {
       head=1;
      }
    }

  }
}
/******************************************************************************/
#pragma interrupt_level 1
void interrupt level_h_l(void)
{
/* if(RAIF)//如果是电平中断
  {
   PORTA=PORTA;
   RAIF=0;//
   TIMER1_TEMP.REG[0]=TMR1L;
   TIMER1_TEMP.REG[1]=TMR1H;
   TMR1H=0;
   TMR1L=0;
   if(RA4)//如果是低电平中断
    {
     l_pulse=TIMER1_TEMP.TIMER1_REG;
     check_data();
     check_head();
    }
   else//如果是高电平中断
    {
     h_pulse=TIMER1_TEMP.TIMER1_REG;
    }


  }*/
 if(INTF)
  {
   INTF=0;
   TIMER1_TEMP.REG[0]=TMR1L;
   TIMER1_TEMP.REG[1]=TMR1H;
   TMR1H=0;
   TMR1L=0;
   if(INTEDG)//低电平宽度
    {
     INTEDG=0;
     l_pulse=TIMER1_TEMP.TIMER1_REG;
     check_data();
     check_head();
    }
   else
    {
     INTEDG=1;
     h_pulse=TIMER1_TEMP.TIMER1_REG;
    }
  }
 if(T0IF)//
  {
   T0IF=0;
   TIMER15S1++;
   TIMER15S2++;
   TIMER15S3++;
   TIMER15S4++;
   TIMER15S5++;
   TIMER15S6++;
   TIMER15S7++;
   TIMER15S8++;
  }
}
/******************************************************************************/
/********************************* 遥控器学习 *********************************/
/******************************************************************************/
void clr_learn_reg(void)
{
 unsigned char n;
 di();
 for(n=1;n==remote_cout*4;n++)
  {
   eeprom_write(n,0);
  }
 eeprom_write(70,0);
 eeprom_write(71,0);
 ei();
}
/******************************************************************************/
unsigned char compare_data(unsigned char eep_addr)
{
 unsigned char n;
 union BIT_32 addr_data;
    for(n=0;n<4;n++)
  {
   addr_data.data_temp_byte[n]=eeprom_read(eep_addr+n);
        }
     if((data_temp.data_temp_long&0x00fffff0)==(addr_data.data_temp_long&0x00fffff0))
    {
      return 1;//地址匹配返回1
    }
     return 0;//地址不匹配返回0
}
/******************************************************************************/
unsigned char compare_all_data(void)
{
 unsigned char n;
    for(n=0;n   {
   if(compare_data(n*4+1))//如果有相同的遥控器
    {
     return 1;
             }
        }
     return 0;//没有一个地址是相同的
}
/******************************************************************************/
//读遥控器的数量
void read_remote_cout(void)
 {
   remote_cout=eeprom_read(71);//读出已经学习的遥控器总数量
   if(remote_cout>20)remote_cout=0; //如果EEPROM是空的则为0
 }
/******************************************************************************/
void check_learn_pro(void)
{
 unsigned char n;
 if(learn)
  {
   learn=0;
   remote_numb=eeprom_read(70);//读出现在可以覆盖掉哪个遥控器的编号
         read_remote_cout();////读遥控器的数量
   if(remote_numb>(remote_geshu-1))remote_numb=0;//如果遥控器的编号已经是最大的了 则从小开始
            if((remote_cout==0)||!compare_all_data())//如果还没有遥控器学习或没有相同地址的遥控器学习
    {
     di();
                    for(n=0;n<4;n++)
      {
       eeprom_write(remote_numb*4+n+1,data_temp.data_temp_byte[n]);
                        }
              remote_numb++;
              if(remote_cout               eeprom_write(71,remote_cout);//保存已经学习好的遥控器总数量
              eeprom_write(70,remote_numb);//保存已学习的遥控起编号
              ei();
             }
  }
}
/******************************************************************************/
void check_out_pro(void)
{
 read_remote_cout();//读遥控器的数量
 if(compare_all_data())
  {
   data=data_temp.data_temp_byte[0]&0x0f;//
   TIMER15S3=0;
   TIMER15S4=0;
   RC4=1;
  }
}
/******************************************************************************/
void decode_init(void)//接收初始化
{
 OPTION=0x87;
 RBPU=0;
 TMR0=0;
 T0IE=1;//使能定时器0中断
 INTE=1;
 TMR1ON=1;//
 PORTC=0x00;//
 TRISC=0x00;//
 ei();//开放全局中断
}
/******************************************************************************/
void check_remote_recieved(void)//检测有无新的数据
{
 if(!RB1)//
  {
   if(TIMER15S1>30)//是否长按了3秒
    {
     learn=0;//
     clr_learn_reg();
     RC4=0;
    }
   else
    {
     learn=1;//
     TIMER15S2=0;
     TIMER15S4=0;
     RC4=1;
    }
  }
 else
  {
   TIMER15S1=0;
   if(TIMER15S2>60)
    {
     learn=0;//
    }
  }

 if(TIMER15S3>2)//数据保持时间
  {
   data=0;
   TIMER15S3=0;
  }
 if(TIMER15S4>3)//LED显示时间
  {
   RC4=0;
  }
 if(recieved)
  {
   TIMER15S3=0;
   recieved=0;
   TIMER15S4=0;
   RC4=1;
   check_learn_pro();
   check_out_pro();  

  }
 INTE=1;
}
/******************************************************************************/
/********************************* 控制部分程序 *******************************/
/******************************************************************************/
void control_init(void)
{

 ;
}
/******************************************************************************/
/*********************************声音部分程序*********************************/
/******************************************************************************/
/******************************************************************************/
unsigned char delay(unsigned int nus)
{
 for(;nus>0;nus--)
  {
   if(recieved==1) return 0;
   asm("nop");
  }
}
/******************************************************************************/
unsigned char soud_one_fre(unsigned int cout,unsigned int delay_time)//发音程序
{
 if(recieved==1) return 0;
 INTE=0;
       for (;cout>0;cout--)
  {
   RC6=!RC6;
   delay(delay_time);
  }
 RC6=0;
 INTE=1;
}
/******************************************************************************/
/*********************************急促的声音***********************************/
/******************************************************************************/
unsigned char soud_one_fre0(unsigned int time,unsigned int delay_time)
{
 for (;time>0;time--)
  {
   if(recieved==1) return 0;
   soud_one_fre(1000,10);
   delay(delay_time);
  }
}
/******************************************************************************/
/*********************************救护的声音***********************************/
/******************************************************************************/
unsigned char soud_tow_fre0(unsigned int time)//
{
 for (;time>0;time--)
  {
   if(recieved==1) return 0;
   soud_one_fre(900,10);
   soud_one_fre(800,30);
  }
}
/******************************************************************************/
/************************************低-高音***********************************/
/******************************************************************************/
unsigned char soud_many_fre0(unsigned int time,unsigned int cout)
{
 for (;time>0;time--)
  {
   unsigned int delay_time;
   for(delay_time=50;delay_time>10;delay_time--)
    {
     if(recieved==1) return 0;
     soud_one_fre(cout,delay_time);
    }
  }
}
/******************************************************************************/
/************************************低-高音1**********************************/
/******************************************************************************/
unsigned char soud_many_fre2(unsigned int time,unsigned int cout)
{
 for (;time>0;time--)
  {
   unsigned int delay_time;
   for(delay_time=30;delay_time>20;delay_time--)
    {
     if(recieved==1) return 0;
     soud_one_fre(cout,delay_time);
    }
  }
}


/******************************************************************************/
/***********************************高—低音************************************/
/******************************************************************************/
unsigned char soud_many_fre1(unsigned int time,unsigned int cout)
{
 for (;time>0;time--)
  {
   unsigned int delay_time;
   for(delay_time=10;delay_time<50;delay_time++)
    {
     if(recieved==1) return 0;
     soud_one_fre(cout,delay_time);
    }
  }
}
/******************************************************************************/
/***********************************高—低音1***********************************/
/******************************************************************************/
unsigned char soud_many_fre3(unsigned int time,unsigned int cout)
{
 for (;time>0;time--)
  {
   unsigned int delay_time;
   for(delay_time=20;delay_time<30;delay_time++)
    {
     if(recieved==1) return 0;
     soud_one_fre(cout,delay_time);
    }
  }
}
/******************************************************************************/
/**********************************汽车报警声**********************************/
/******************************************************************************/
unsigned char soud_low_high_low(unsigned int cout)
{
 for (;cout>0;cout--)
  {
   if(recieved==1) return 0;
   soud_many_fre0(1,10);
   soud_many_fre2(1,10);
  }
}
/******************************************************************************/
unsigned char remote_check(void)//遥控器按键检测
{
 if(data)//
  {
      if(remote_button_status)
       {
           return 0;
             }
      else
       {
        remote_button_status=1;
        return data;//遥控器数据有效
       }
    }
 else
    {
   remote_button_status=0;
   return 0;
    }
}
/******************************************************************************/
void check_remote_command(void)
{
 if(TIMER15S5>10)
  {
   first_click_status=0;//
  }

 switch (remote_check())
  {
   case 0x01:
    {
     RC0=!RC0;
    // soud_one_fre0(1,6000);
     soud_tow_fre0(5);
     delay(10000);
     soud_many_fre0(5,40);
     delay(10000);
     soud_many_fre2(10,100);
     delay(10000);
     soud_many_fre1(5,40);
     delay(10000);
     soud_many_fre3(10,150);
     delay(10000);
     soud_low_high_low(5);
     delay(10000);
     soud_one_fre0(2,10000);
     break;
    }
   case 0x02:RC1=!RC1;break;
   case 0x04:RC2=!RC2;break;
   case 0x08:
    {
     if(first_click_status==1)
      {
       RC3=!RC3;
       first_click_status=0;//
       break;
      }
     else
      {
       first_click_status=1;
       TIMER15S5=0;
       break;
      }
    }
   default:break;
  }
}


/******************************************************************************/
void control_pro(void)
{

 check_remote_command();
}


关键字:pic单片机  软件解码  PT2240 引用地址:pic单片机软件解码PT2240

上一篇:PIC单片机滚动码解码C程序
下一篇:PT2262解码程序( pic12F629 )

推荐阅读最新更新时间:2024-03-16 15:20

PIC单片机状态寄存器中的C(进位/借位位标志)
查阅PIC单片机芯片手册,关于进位/借位位的说明为:   C:进位/借位位。    1 = 结果的最高位发生了进位    0 = 结果的最高位未发生进位    同时有一条标注:借位的极性是相反的。 通过以上说明,可以将C的分析分为两种情况:   1、加法:    最高位发生了进位:C = 1;    最高位未发生进位:C = 0;   2、减法:    最高位发生了借位:C = 0;    最高位未发生借位:C = 1; 为了加深理解,在MPLAB中写入一段代码,通过观测STATUS寄存器的值来测试以上分析: 1 ;测试SUBWF、ADDWF指令与状态寄存器C标志位的关系 2 3 LIST P=16F684 4
[单片机]
<font color='red'>PIC单片机</font>状态寄存器中的C(进位/借位位标志)
基于GSM和PIC单片机的无人清洁护理机的设计
0 引言 随着我国老龄化进程的加剧,当今社会中存在着一种因失去生活自理能力而“长期卧床的弱势群体”,特别是那些几乎无意识的弱势群体,他们需要被人长期照顾,特别是他们的大小便的清洁处理。然而由于该弱势群体数量大、护理人员紧缺和护理费用高等问题,导致这些弱势群体的家庭护理矛盾日益凸显。目前市场上的长期卧床病人大小便清洁护理机在“智能护理”方面己比较完善,已经具有大小便自动识别与回收、温水清洗与自动烘干等功能,达到了“人性化”护理的要求,但在使用过程中仍然需要专门的“陪护人员”,对于绝大多数现代家庭而言,无论从人力还是财力,这都将是一个沉重的负担,同时也限制了大小便清洁护理机在家庭中的推广使用,因此,社会迫切需要一种在现有护理功能的基
[单片机]
基于GSM和<font color='red'>PIC单片机</font>的无人清洁护理机的设计
PIC单片机的各种汇编语言指令的用法解析
工作以来一直使用ST的单片机,其他的单片机虽大致了解但从未认真看过,近几日恰好无事,决定熟悉一下PIC的单片机,于是想将自己从网上或这书本上的东西转下来,予以同一样的初学者共同参考。 PIC的指令系统 PIC 8位单片机共有三个级别,有相对应的指令集。基本级PIC系列芯片共有指令33条,每条指令是12位字长;中级PIC系列芯片共有指令35条,每条指令是14位字长;高级PIC系列芯片共有指令58条,每条指令是16位字长。其指令向下兼容。 一、PIC汇编语言指令格式 PIC系列微控制器汇编语言指令与MCS-51系列单片机汇编语言一样,每条汇编语言指令由4个部分组成,其书写格式如下: 标号 操作码助记符 操作数1,操作数2;注释
[单片机]
<font color='red'>PIC单片机</font>的各种汇编语言指令的用法解析
PIC单片机实现双字节无符号数的除法
编写子程序Div_16,实现双字节无符号数除法。自行定义变量,其中: ACCALO ;存放被除数低 8 位 ACCAHI ;存放被除数高 8 位 ACCBLO ;存放除数 8 位 ACCCLO ;存放余数 8 位 ACCCHI ;存放商 8 位 采用移位法,设被除数为ACCA、除数为ACCBLO、商为ACCCHI(初值为0)、余数为ACCCLO(初值为0)。ACCA由高位至低位依次左移进入ACCCLO单元,每次移位进入后比较ACCCLO单元和ACCBLO的值,如果ACCCLO≥ACCBLO,则将这一位的商单元的值置1,然后从ACCCLO中减去ACCBLO,否则不做操作。直到ACCA全部进入ACCCLO单元为止。此时AC
[单片机]
MPLAB X安装,PIC单片机开发环境的搭建记录
  第一次使用PIC单片机,记录一下使用的过程,所谓工欲善其事必先利其器,首先需要安装PIC的开发环境,这里我选的是MPLABX-v5.25.   首先到官网下载MPLAB X,其他渠道也行,官网: https://www.microchip.com/mplab/mplab-x-ide ,其次还要下载XC 16,这是编译必须的,官网 https://www.microchip.com/mplab/compilers/compiler-maintenance-and-support/mplab-xc-hpa 选择你使用芯片对应的版本,我用的是16位芯片,所以我下载了XC 16。   安装MPLAB X:   其实安装很简单,
[单片机]
MPLAB X安装,<font color='red'>PIC单片机</font>开发环境的搭建记录
基于PIC单片机的IAI无线模块测试板
  近年来,由于数据通信需求的推动,加上半导体、计算机等相关电子技术领域的快速发展,短距离无线与移动通信技术也经历了一个快速发展的阶段。短距离无线通信通常指的是l00m到200m以内的通信。   它被广泛应用于无线数据采集、无线水表、煤气表、电力表抄表、工业遥控、遥测、工业数据采集、楼宇自动化、安防、机房设备无线监控、家庭自动化数据网络组网等领域。   美国SILICon Laboratories公司作为专业的无线芯片开发和生产商,它的IAI系列无线芯片具有集成度高,外围元件少,功耗低,性能稳定可靠,芯片内部集成了FSK无线收发必需的全部功能模块,包括多边带PLL合成器、PA、LNA、混频器、基带滤波器、中频放大器、信号强度指
[单片机]
基于<font color='red'>PIC单片机</font>的IAI无线模块测试板
PIC单片机编程格式和风格
首先我们来看一段程序: ittle ‘Input.asm’ ;标题 这是一个简单的输入实验 include COUNT EQU 20H ;定义20H寄存器名为COUNT ORG 0 ;程序区将从0000H开始装载 GOTO START ORG 4 ;中断入口 GOTO INTEN ;中断发生时跳转到INTEN ORG 10 ;START将从第10行开始 START …… MAIN …… GOTO MAIN INTSEVER …… RETFIE ;中断返回 END ;程序结束伪指令,不能少! 事实上汇编程序并没有固定的格式,但是它的各部分是有一定的位置安排的,习惯上依次为: ①程序标题:用Tittle伪指令定义,可缺省; ②程序
[单片机]
PIC单片机实现的脉冲编码传感器
引 言   随着社会的发展,出租车成为人们生活中非常方便且较普遍的交通工具,但出租车计价器却相对较为落后。在过去,出租车采用机械式计价器,用齿轮比的方式来计算出租车所跑的里程数,并由里程数来换算车费。但是机械齿轮体积较大,计算不是很准确,而且容易磨损。后来又采用了传感器方式,利用传感器接收车的跑动信息,从而计算里程数和车费。但此方法通常使干扰信号也能产生计数脉冲,所以也不完善。笔者引用单片机技术,使用编码和解码信息传递方式来完成计价器计数脉冲的形成。单片机可以很精确的检测到传感器信号,这样计价就会非常准确。完成此装置所需器件简单,成本非常低,技术上也容易实现。 1 系统原理   系统框图如图1所示,本文主要介绍虚线框内模块的设计
[单片机]
用<font color='red'>PIC单片机</font>实现的脉冲编码传感器
小广播
添点儿料...
无论热点新闻、行业分析、技术干货……
设计资源 培训 开发板 精华推荐

最新单片机文章
何立民专栏 单片机及嵌入式宝典

北京航空航天大学教授,20余年来致力于单片机与嵌入式系统推广工作。

换一换 更多 相关热搜器件
电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2024 EEWORLD.com.cn, Inc. All rights reserved