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