//本例实现单片机用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; } } |
|