用PIC1828解码PT2272

2020-02-06 10:17发布

本来对PIC单片机不熟悉,但当时因为PIC有6脚很小封装的,所以就学习用了一下。近期用到315和433的用PT2262编码发送的遥控器,如果用PT2272来解码当然完全没有问题,但因体积原因,只能用单片机身兼数职代替2272解码。在网上收集来了不少资料,找到一个51系列的可用的程序,于是移植到了pic上面。在此对原作者表示感谢。本人对C语言也是才学,对付着写了一下,程序不长,付在下面,供有兴趣的朋友探讨参考。

//pic16f1828_DECODE_2272
/*************             PIC16F1828单片机程序        ******************/
/***************************************************************/
/*****File  Function : pic828软解码PT2272                                  **********/
/*****MCU            : PIC16F1828  内部振荡                          *****/
/*****Compile Date   :  2014/10/09                                                  ******/
/*****Edition Info   :  V0.0                                                              ******/
//**************************************************************/
/***************************************************************/
#include <pic.h>
typedef unsigned char uint8;
typedef unsigned int  uint16;
//---------------------------------------------------------
        uint8 ma1,jmz1,jmz2,jmz3;
//----------------------------------------------------------
void delayms(uint16 count);

void PortInit(void);
//------------------------------------------------------------------------
#define     p2262   LATB6           //11脚  RB6 模拟2262发码,控制315(433)发射信号

#define     p2272   RA2       //17脚  RA2 2272信号进,软解码2272信号进口
//------------------------------------------------------------------------
#define     led     LATB5     //12脚 RB5 红 {MOD} 低电平亮

#define     b_yong1   RB7      //10脚,备用1
#define     b_yong2   RC7      // 9脚,备用2

#define     key       RB7       
//------------------------------------------------------------------------
#define                _asm{"nop"}        NOP()
//------------------------------------------------------------------------
//========================================================================
void PortInit(void) {
        TRISA=0b11001111;    //A口:RA2=p2272(输入)       
        TRISB=0b10011111;    //B口:RB5=led(输出),RB6=PL2262(输出),
        TRISC=0b11011110;    //C口:       
                           
            ANSC0=0;     //禁止RC0口的模拟功能20120729
            ANSC1=0;     //禁止RC1口的模拟功能20120729
            ANSC2=0;     //禁止RC2口的模拟功能20120729
            ANSC3=0;     //禁止RC3口的模拟功能20120729

            ANSC6=0;     //禁止RC6口的模拟功能
            ANSC7=0;     //禁止RC7口的模拟功能

            WPUA =0b11111111;         //使能A口上拉电阻
            WPUB =0b11111111;         //使能B口上拉电阻
            WPUC =0b11111111;         //使能C口上拉电阻

             ANSA0=0;     //禁止RA0口的模拟功能20120719
             ANSA1=0;     //禁止RA1口的模拟功能20120719
        ANSA2=0;     //禁止RA2口的模拟功能
   
        ANSB7=0;     //禁止RB7口的模拟功能20120729           
        ANSELB=0;          //B口配置为数字功能       
        ANSELC=0;          //C口配置为数字功能
     
            //OSCCON=0b01011000;   //1MHZ   
            //OSCCON=0b01100000;   //2MHZ     
      //OSCCON=0b01101000;   //4MHZ 振荡器控制(6-3位=1101 4MHz)     
        OSCCON=0b01110000;   //8MHZ   
      //OSCCON=0b01111000;   //16MHZ
   
      INTCON =0b11010000;    //.7=GIE:全局中断;.6=PEIE:外设中断允许;.5=TMR0IE t0; .4=INTE:INT外部中断允许位;       
                             //.3=电平变化中断(1:允许电平变化,0:不允许);   .2=TMR0IF:t0中断标志位;
                             //.1=INTF:INT外部中断标志位;   .0=IOCIE:电平变化中断标志     
      
     T1CON  = 0b00111000;    //T1时钟源为指令时钟,1:8预分频; .3=1使能专用的T1振荡器,.0=0暂不使能(暂停计时)     
     T1GCON = 0b00000000;    //T1门控功能不要
  
     PIE1   = 0b00000001;    //.0=T1中断允许位     

     OPTION_REG =0b00000111;//111; .7位=0,使能弱上拉     
     led=1;  //led=0 -->亮
}
//==============================================================
static void  interrupt isr(void){     
      uint8 i,tl,th;      
      uint16 l,m;
//--------------------------------------------------------------
        if(INTE&&INTF){      //判断外部中断
        INTF=0;   
           INTE=0;    //INT禁止(关外部中断)
           TMR1ON=1;  //T1开始计时
           i=0;  
//==============================================================  
  while(i<24)
   {           
    while(p2272==0);    //等待高电平到来   
    tl=TMR1L;       //tl=TL1;
    th=TMR1H;       //th=TH1;
    TMR1H=TMR1L=0;  //记录低电平长度并初始化高电平头
    l=th;
    l=((l<<8)+tl);        
    if(i==0){          //处理低电平              
            if(l>2360)                                
          {            //确认是引导头                   
               m=l/31;                                 
          }
          else         //不符合规则(出错)
          {         
            i=0;
          TMR1ON=0;    //T1暂停计时
          TMR1H=TMR1L=0;            
            break;
          }
      }
    else
        {
      if(((l<m-m/4)&&(l>m+m/4))||((l<m*3-m/2)&&(l>m*3+m/2)))//判断窄电平与宽电平的宽度是否合格     
          {
            i=0;
            TMR1ON=0;   //T1暂停计时
            TMR1H=TMR1L=0;                  
              break;
           }        
      }
//==============================================================
    while(p2272==1);  //等待低电平到来   
            
    th=TMR1H;        //th=TH1;
    tl=TMR1L;        //tl=TL1;
    TMR1H=TMR1L=0;   //TH1=TL1=0;
    l=th;
    l=((l<<8)+tl);
    if(((l>(m-m/4))&&(l<(m+m/4))))         //判断窄电平是否合格
         {   
          i++;
        ma1<<=1; //高低位相反问题
       }
    else if((l>(m*2-m/2))&&(l<(m*4+m/2)))  //判断宽电平是否合格       
     {
      i++;
      ma1<<=1; //高低位相反问题
      ma1+=1;  //高低位相反问题
     }
    else        //不符合规则出错
     {
     i=0;
     TMR1ON=0;  //T1暂停计时  
     TMR1H=TMR1L=0;                  
        break;      
     }
//==============================================================     
    if(i==8)  {jmz3=(ma1); }
    if(i==16) {jmz2=(ma1); }
    if(i==24)            //解码成功结束
     { jmz1=ma1;          
              if(jmz1==0xc0)
                {led=0;delayms(39000);led=1;}
                if(jmz1==0x30)
                {led=0;delayms(3000);led=1;}
                if(jmz1==0x0c)
                {led=0;delayms(1000);led=1;}
                if(jmz1==0x03)
                {led=0; }                       
          }
   }   
    TMR1ON=0;  //T1暂停计时     
    TMR1H=TMR1L=0;      
    INTE=1;    //INT允许
}     
//--------------------------------------------------------------                    
   if(TMR1IE&&TMR1IF){    //判TMR1中断
    TMR1IF=0;             //清除TMR1中断标志   
    }            
//--------------------------------------------------------------
   if(TMR0IE&&TMR0IF){    //判TMR0中断   
    TMR0IF=0;             //清除TMR0中断标志   
  }
}
//===============================================================
void main(void) {
        uint16 k,j;       
        uint8 i;       

        PortInit();       
    while(1);     
  }      
//=======================================================================       
void delayms(uint16 count){
uint16 i;
for(i=count;i>0;i--){
NOP();
}}
//========================================================================
//########################################################################
  //数据:(jmz1)        0=00, 1=03, 2=0c, 3=0f, 4=30, 5=33, 6=3c, 7=3f,
  //                      8=c0, 9=c3,10=cc,11=cf,12=f0,13=f3,14=fc,15=ff,
  //                     16=00, 17=03,18=0c, 19=0f, 20=30, 21=33, 22=3c, 23=3f
  //
  //       0   1   2   3   4   5   6   7  
  //       10  10  10  10  10  10  10  10 <--全部悬空     =aaaa
  //       01  01  01  01  01  01  01  01 <--全部接高电平 =5555
  //       00  00  00  00  00  00  00  00 <--全部接低电平 =0000
  //       --------------  --------------
  //         jmz2            jmz3
//########################################################################
友情提示: 此问题已得到解决,问题已经关闭,关闭后问题禁止继续编辑,回答。