分享

单片机发送寻呼机pocsag码

 浏今岁月 2017-02-17
//本例实现单片机用pocsag码向数字机发送pocsag数字28167的全部编码
//包括引导码、同步码、闲置码、地址码、信息码。、
//本例用stc12C5a60s2用32M晶振成功呼响了motorola大顾问传呼机
//本例仅供传呼机爱好者地pocsag进行了解和试验,切勿用于商业用途
#include 'STC12C5A60S2.H'                  

//#include 'string.h'
//#include 'intrins.h'
//#include'stdio.h'

#define uchar unsigned char
#define uint unsigned int           

#define TIMER0_ENABLE  TR0=1;
#define TIMER0_DISABLE TR0=0;

#define TX  P2_0   //数据输出端
#define PTT P2_2   //PTT控制端
#define HIGH   1
#define LOW    0

unsigned long xdata addr;        //地址         
uchar  Tx_Num;//地址码发射次序

bit TM0_FLAG=0;

void UartInit(void)                //9600bps@32.000MHz
{
        PCON &= 0x7F;                //波特率不倍速
        SCON = 0x50;                //8位数据,可变波特率
        AUXR |= 0x40;                //定时器1时钟为Fosc,即1T
        AUXR &= 0xFE;                //串口1选择定时器1为波特率发生器
        TMOD &= 0x0F;                //清除定时器1模式位
        TMOD |= 0x20;                //设定定时器1为8位自动重装方式
        TL1 = 0x98;                //设定定时初值
        TH1 = 0x98;                //设定定时器重装值
        ET1 = 0;                //禁止定时器1中断
        TR1 = 1;                //启动定时器1
   //        TI = 1;
}         

void Delay200ms()                //@32MHz
{
        unsigned char i, j, k;

        i = 25;
        j = 82;
        k = 145;
        do
        {
                do
                {
                        while (--k);
                } while (--j);
        } while (--i);
}        

unsigned long  calc_bch_and_parity( unsigned long cw_e ) //BCH校验和奇偶校验函数
{
   uchar i;
   uchar  parity = 0; //奇偶校验计数   
   unsigned long local_cw; //临时存放数         
   local_cw=cw_e;//保存cw_e参数值
   for(i=1;i<=21; i++,cw_e<<=1)           
       if (cw_e & 0x80000000) cw_e ^= 0xED200000;  
   cw_e=cw_e&0xFFC00000;//保留前10位,BCH校验值共11位,只保留前10位有效数据         
   local_cw |= (cw_e >> 21); //BCH校验数移至第22位到31位,BCH共10位,并和原始数据相加
   cw_e=local_cw;         
   for(i=0; i<31; i++, cw_e<<=1) if(cw_e&0x80000000) parity++;        
   if(parity%2) local_cw+=1;//从1至31位判断为奇数则后面加1补充为偶数
   return local_cw;         
}  

unsigned long  calc_addr( unsigned long add,uchar fun ) //地址转换,第1参数为地址,第2参数为功能
{
  unsigned long adr;
  unsigned long tem;   
  Tx_Num=(uchar)(add&0x00000007);//获取地址发射的帧位次,111位第7帧,后3位地址数据隐藏不发送,接收按帧位还原
  adr=0x00;
  adr=add&0xFFFFFFF8;        //去掉地址码后3位
  adr=adr<<10;  //地址左移10位
  tem=0x00;
  tem=fun;  //功能位
  tem=tem<<11;//功能位左移11位,功能位为00 01 10 11四种状态,代表4个地址码
  adr=adr|tem; //地址码和功能位合成地址码;
  return adr;
}


void IntTimer0() interrupt 1 //设定中断时间为0.8333毫秒,1/1200=0.8333,1200比特速率
{
     TL0 = 0x53;                //设置定时初值
         TH0 = 0xF7;                //设置定时初值         
     TM0_FLAG=1;
}
         

void WaitTF0( void )
{
   while(!TM0_FLAG);
   TM0_FLAG=0;      //清标志位
}

void Send_start(unsigned long s)
{
   uchar i,n;
   unsigned long tem;  
   for(i=0;i<20;i++) //发送576个前导10101010101010
        {      
      tem=s;
          for (n=0;n<32;n++)
       {
                 if(tem&0x80000000)TX= HIGH ;else TX=LOW;
                 WaitTF0();//等待延时结束 0.833ms                           
                    tem<<=1;
           }      
        }   
}

void Send_nill()//发送闲置位
{
  uchar n;
  unsigned long s=0x7A89C197;
  for(n=0;n<32;n++)
   {
          if(s&0x80000000)TX= HIGH ;else TX=LOW;
          WaitTF0();//等待延时结束 0.833ms                           
          s<<=1;
   }
}

void Send_Num(unsigned long s)         //发送数据
{
   uchar n;
   for (n=0;n<32;n++)
    {  
          if(s&0x80000000)TX= HIGH ;else TX=LOW;
          WaitTF0();//等待延时结束 0.833ms                           
          s<<=1;
    }   
}         

void Print_code(unsigned long p)  //串口打印,用于测试BCH值
{
  uchar i;
  unsigned long t;
  t=p;
  for(i=0;i<32;i++,t<<=1)
   {
         if(t&0x80000000)
          {
            SBUF=0x31;
                while(TI==0);
                TI=0;
          }
         else
          {
                SBUF=0x30;
                while(TI==0);
                TI=0;
          }         
   }
  SBUF=0x0D;
                while(TI==0);
                TI=0;

  SBUF=0x0A;
                while(TI==0);
                TI=0;
  
   t=p;
   t<<=21;
   for(i=0;i<10;i++,t<<=1)
    {
          if(t&0x80000000)
           {
        SBUF=0x31;
                while(TI==0);
                TI=0;
          }
         else
          {
                SBUF=0x30;
                while(TI==0);
                TI=0;
          }         
        }
   SBUF=0x0D;
                while(TI==0);
                TI=0;

   SBUF=0x0A;
                while(TI==0);
                TI=0;  
}

         

main()
{
    uchar i,n;
        unsigned long tem;
        unsigned long star;  
        unsigned long sync;         //同步码
        unsigned long mess;  //信息码        
        

        UartInit();  //串口初始化

        TMOD|=0x01;  //定时器0为模式1 (16位定时器)                                    
        TL0 = 0x53;                //设置定时初值
        TH0 = 0xF7;                //设置定时初值
    ET0=1; //定时器0充许中断
        TR0=0;        
        EA=1;  //开总中断
        TX = 0;
        
    P2M0 = 0x01;//设P2_0为推挽输出模式
        P2M1 = 0x00;

    PTT= 0;        
        star = 0xAAAAAAAA; //前导码
        sync = 0x7CD215D8; //同步码        
   
        tem=calc_addr(1234567,1);//前面是地址码,后面是BB机内00 01 10 11  代表0,1,2,3种不同的声音        
    addr=calc_bch_and_parity(tem);//取得BCH校验后的地址码序列
        mess=calc_bch_and_parity( 0xA0C37000);//信息码28167数字码,取0010(2)的反顺序0100输入
        Print_code(mess);  //从串口打印32位信息码和BCH校验码


   while(1)
    {           
           PTT = 0;
           Delay200ms();        
           TL0 = 0x53;                //设置定时初值
           TH0 = 0xF7;                //设置定时初值                 
           TIMER0_ENABLE; //启动定时器
           Send_start(star); //引导码
       Send_Num(sync);        //同步码

       for(i=0;i<8;i++)  //发送一个批次,共8帧数据
            {
              if(Tx_Num==i)        //计算地址码插入的帧位,本例为第7帧
               {
                      Send_Num(addr);          //地址码
                      Send_Num(mess);          //信息码
               }
              else
               {
              Send_nill();        //闲置码
                      Send_nill();        //闲置码                     
                   }
            }                        
           Send_Num(0xFFFFFFFF);
           TX=LOW;
           TIMER0_DISABLE;
           Delay200ms();
           Delay200ms();
           Delay200ms();
           Delay200ms();
           Delay200ms();
           PTT = 1;  
     }
}

    本站是提供个人知识管理的网络存储空间,所有内容均由用户发布,不代表本站观点。请注意甄别内容中的联系方式、诱导购买等信息,谨防诈骗。如发现有害或侵权内容,请点击一键举报。
    转藏 分享 献花(0

    0条评论

    发表

    请遵守用户 评论公约

    类似文章 更多