|
当时接这个项目是Z80CPU系统的单板机编写汇编语言构建一个小型传呼机BB机(微型或小型)系统收费为5千元港币,但当其时自己对POCSAG传呼机编码系统完全不熟悉,之前都没有接触过,要立即去查找很多有关这方面的一切资料,初步认识了,为了减轻(软件)编写汇编难度,应用了两片逻辑芯片(一片74HC4060本身再直接连接上1只32.768KHz晶振(除频电路有Q4~Q14级输出)选择了(Q4÷16/Q5÷32 )二级(÷16/÷32)除频输出,(2选一)之后要(兵分两路)一路连接到PIO其中1条输入端(这样Z80CPU微处理器)就清楚知道每一个的脉沖上升沿和下降沿的来临,另一路送入到(一片D型触发器74HC74)脉冲输入端(CLK)÷2 在Q的输出端(如果不是上升沿,是要选择(下降沿)可改连接/Q就可以,不用变更任何汇编编程)连接到FSK移频键控发射机串行数据输入端(得到精准512波特率,绝对没有误差),74HC74(D)输入端连接到PIO其中1条串行数据输出端,解决了传呼机系统(512bp波特率)的累计(长时间累积叠加误差)这一大难题,Z80单板机系统(CPU、PIO(8255)、EPROM、RAM、有六只七划管LED显示、4x5键盘输入(〈0~9A~F〉16个数字键盘输入,4个功能键盘输入)),再加上一个移频键控FSK发射机(Bit1 发射150MHz / Bit0 发射145MHz)就可构成一个传呼机(BB机发射系统),POCSAG一个系统可容纳200萬部传呼机,传呼机相等同是一部收音机,只和收音机不同的是收到信息之后有两部份,一部分就是本身机的号码(地址码)〈例如(1234567)〉,另一部分就是信息(例如(简易编码345) 代表立刻回家食饭),这200萬部传呼机都同一时间接收到大气电波一样的信息,但只有其中唯一部机身号码是(1234567)(地址码)这部机才会BB响同时将(345)这组号码显示出来,这样就很清楚知道家人通知立即回家食饭,因当其时是没有手提电话的,已经很先进的年代了,所以不能同现今通信简便年代(相提并论)!
……………………………………………………………………………………………
基于寻呼网络的POCSAG码是什么有什么特点具体编码解码机制如何
POCSAG码 ——POCSAG码由英国邮政总局研究成功的。1980年首次在英国的单音无线寻呼系统中得到应用。
POCSAG码具有编码效率高、纠错能力强、地址容量大等优点…等。
POCSAG码
POCSAG码由英国邮政总局研究成功的。1980年首次在英国的单音无线寻呼系统中得到应用。
POCSAG码具有编码效率高、纠错能力强、地址容量大等优点,因此在无线寻呼系统中得到广泛应用。1982年国际无线电通信咨询委员会(CCIR)将其定为“一号无线寻呼码”,又称“国际一号码”。我国亦将其做为公众无线寻呼的标准码。
POCSAG码的码字类型为BCH(31,21)加1bit偶校验码,汉明距r=6,码字结构为576bit前置码后接若干字群,每一字群总长度为 544bit,由32bit同步码开头,后接8帧信息。该码的单位码字可检出11bit突发错误或5bit随机错误,也可纠正5bit突发错误或2bit 随机错误。
POCSAG码通常可容纳200万个用户。如经过地址扩展,用户可达到800万个。在寻呼系统传输中通常采用 512bit/s和 1200bit/s两种码速率。
无线寻呼通信是什么意思求答案
POCSAG编码制式是1984年由飞利浦公司发明的,被国际电信联盟批准为国际一号码。此后POCSAG 编码在全世界被广泛应用,但它的传输率仅为512bit/s和1200bit/s,因此效率比较低,按速率 120 0bit/s计,一个频点用户容量大约为3万-4万,要增加用户只能靠增加频点,建设新台来实现,当然从初期阶段来看,它是能够满足要求的,但随着寻呼业的迅速发展,用户急剧增加,采用 POCSAG 编码制式的系统就显得不够应用了,因为频率资源是有限的。 FLEX高速编码体制就是为了满足寻呼通信的发展需求,由摩托罗拉公司在1993年提出来的,后经不断充实完善,现已成为集高速、移动、双向和语言等先进功能于一体的无线寻呼标准体系,国际电联已批准把FLEX技术作为无线寻呼代码格式的建议标准,FLEX规程也被信息产业部采纳为全国的高速寻呼网标准,国家无委也已将279-28MHz频段作为FLEX全国高速寻呼专用频段,共有16个频点。 FLEX编码与POCSAG编码比较有如下优点: (1)系统高效、寻呼机省电。 FLEX编码采用同步传输方式,而POCSAG是异步,因此FLEX编码体制的寻呼系统发射机能以准确的时间作基准,并按预订的时间开启发送,FLEX编码体制的寻呼机只是在刚刚开机和离开系统很长时间才需要连续开机搜索系统时间信息,使该机时钟与系统时钟同步。此外FLEX编码体制中的地址码集中在地址区中的,当寻呼机在地址区中搜索不到本机的地址码时,就立即处于休眠的省电状态,可见FLEX编码体制的寻呼机是通过减少开启频率,提高每次开启时的搜索效率来大幅度地提高省电效率的。FLEX寻呼机的电池寿命较POCSAG寻呼机延长多至5倍。 (2)地址码资源丰富,系统用户客量大。 由于FLEX编码体制废弃了像POCSAG编码体制那样的前置码,数据信息是以1路、2路、4路 1600b it/s的数据复接形成的,所以它有1600、3200、6400bit/s的速率可供选择,这就大大扩展了信息容量,它比POCSAG码的容量要大5倍,可容纳10亿个地址码,单频点用户数达30万。 (3)抗多径裹落性能比POCSAG编码体制好。 FLEX编码体制除了采用2bit的前向纠错外,还采用了交织编码、奇偶校验、信息编号以及信息结束等多种技术,因此10ms抗多径衰落的能力比POCSAG编码体制要高12倍。 2双向寻呼技术 双向寻呼是在高速寻呼应用的基础上建立并发展起来的,双向寻呼技术的不断成熟,为寻呼通信开拓了更广阔的生存空间,利用双向寻呼提供个人移动信息业务,存在着更广阔的应用前景,寻呼通信在个人移动信息业务中的应用很可能使其成为全新的产业。 双向寻呼的“双向”不能单纯地理解为两个方向都可以通信,这种双向通信不是完整意义上的双工通信,不同于语音的对等双向通信,它是建立在高速单向寻呼的基础上开拓的一种新的增值服务编码,只是在单向高速编码的基础上正向发射信道上加入了控制命令,同时增设了反间接信道。这样,当寻呼接收机收到呼叫信息后就自动向系统发回一个“应答”信号,以确定寻呼机已接收到信息。因此,双向寻呼系统的寻呼机发出的信息是一种非常简单的应答信号,是不对称的“双向”,但它的确通过这种简单的信号实现了寻呼机与系统之间的双向联系,使用户与系统、用户与用户之间进行短消息交换。 双向寻呼系统中的寻呼机能通过短消息向系统发出位置参数,使系统及时了解它目前的位置,因此在某一时段内只要控制和开启被寻呼机所在的区域内的一个或少量发射机仍能重复使用此频率发送其它消息。由此可见双向寻呼系统大大提高了频率和发射机的利用率,这一点是单向寻呼不可及的。单向寻呼必须是本地区的发射机同播,因此双向寻呼才是真正的“寻”呼。在双向寻呼系统中,用户无须办理漫游手续就可以在整个网内漫游,扩大了系统网络覆盖面积。 双向寻呼系统的优点是显而易见的,但是建立一个双向寻呼系统的投资也是相当可观的。首先必须建立基站和键路,并且还要有一个比较完善的网管系统,此外除了用原有的单向发射的一整套系统外,还要许多类似蜂窝系统的基站,它们构成小区制式,相互之间还要有链路支持,费用可想而知。 3网络寻呼技术 网络寻呼可以说是lnternet和寻呼通信发展的必然产物,实际上它是Internet和寻呼通信增值服务的结合。它是利用现有的寻呼系统,连接入Internet中,其基本原理是将寻呼的控制器与WEB 相连,当用户访问寻呼WEB站点时,可将寻呼号码和信息输入,信息将自动进入寻呼系统控制器,然后呼到正确的地址,网络寻呼具有如下功能: (1)全球呼。 Internet是世界范围的网络,因此在世界任何一个城市均可以通过Internet进入寻呼台的 WEB站点发送信息,这在某种意义上可以说实现全球呼。Internet寻呼有着高效、大信息量、保密性好、方便准确的优点,同时一些跨国公司可以从国外通过Internet将信息发送到传呼机上,信息传递成本低、速度快。 (2)E-mail寻呼。 寻呼台可在寻呼系统开发一个E-mail服务器,每个传呼号码唯一对应的一个E-mail账号,这样就可以通过E-mail的方式将信息发送到寻呼机上,寻呼机实际变成了一个无线E-mail接收机了,其方便之处就不言而喻了。 (3)个人信息订阅寻呼服务。 通过Internet的信息系统,寻呼机可以订阅自己所选择的信息,并定时发送到自己的寻呼机上去,如航班、股票、地产、气象等信息,用户可以自主选择,作为个人信息发送。 双向寻呼和网络寻呼的发展为日趋平稳的寻呼通信市场带来了新的发展机遇,当然技术的发展方各不一定完全符合一项通信产业的市场发展规律,决定寻呼通信业务发展还有诸多因素,尤其是在我国民族通信产业正在飞速发展阶段,国家对电信产业调整以及加入WTO,开放电信市场将会给我国的民族通信产业带来深远的影响和前所未有的机遇与挑战,对寻呼经营企业而言,发展规模经营,组建大型寻呼企业,是行之有效且迫在眉睫的必由之路,开放的、竞争的、有序的电信市场,有利于双向寻呼、网络寻呼的迅速应用。
中国最后的bp机 运营商 是那一年停的
2007年3 月信息产业部发表公示称,中国联通申请停止经营北京等三十省自治区、直辖市的198/199、126/127、128/129无线传呼服务。标志着传呼机在大陆地区的运营正式结束。
传呼机和无线传呼网络于1980年代出现,经过十多年的发展,于1990年代末期达到了顶峰。在手机普及之前,人们普遍以拥有传呼机为荣。1998年,全国传呼机用户突破 6546万,名列世界第一。其后逐渐式微。
拓展资料:
无线寻呼系统中的被叫用户接收机。由超外差接收机、解码器、控制和显示等部分组成。
它从基站发射的寻呼信号和干扰中选择出所需接收的有用信号,恢复成原来寻呼本机的基带信号,并产生音响(或振动)和显示数字(或字母、汉字)消息。
以下连结(如何获得bp机的地址码和工作频率)
https://359303267.github.io/Get-BP-Code/
无线接收器电路>寻呼机发码电路ML99V4
2010年11月24日发布//无线接收器电路
电路ML99V4发出的寻呼机代码不仅可以生成POCSAG自编程代码,而且还随RF电路一起提供。它不能依靠任何其他电路或程序来直接编译和分发自由的POCSAG码格式的寻呼机地址码,信息码,传输速率变量,相位变量,功能位变量,而且还设置启动延迟,发送启控制代码来设置灵敏度功能。因此,这是该电路的第二个发展,可用于防盗报警系统,BP可以直接使用普通的报警单元作为便携式接收器,从而使BP机器成为一台机器。通常是无线警报系统,要求用户携带通过遥控器接收或发送的一个或另一个。ML99V4寻呼机代码电路也可以作为廉价维护仪器直接发送到寻呼机。本文介绍了它的原理,编程和应用。ML99V4代码发出寻呼机的电路原理图如图1所示。核心组件是高性能微控制器AT89C2051。拨码位微控制器从输入的四位地址码,信息码,传输速率,功能参数等设置位的开关自动计算,生成POCSAG码。ML99V4代码发出寻呼机的原理图电路如图1所示。核心组件是高性能微控制器AT89C2051。拨码位微控制器从输入的四位地址码,信息码,传输速率,功能参数等设置位的开关自动计算,生成POCSAG码。ML99V4代码发出寻呼机的电路原理图如图1所示。核心组件是高性能微控制器AT89C2051。拨码位微控制器从输入的四位地址码,信息码,传输速率,功能参数等设置位的开关自动计算,生成POCSAG码。ML99V4代码发出寻呼机的原理图电路如图1所示。核心组件是高性能微控制器AT89C2051。拨码位微控制器从输入的四位地址码,信息码,传输速率,功能参数等设置位的开关自动计算,生成POCSAG码。ML99V4代码发出寻呼机的电路原理图如图1所示。核心组件是高性能微控制器AT89C2051。拨码位微控制器从输入的四位地址码,信息码,传输速率,功能参数等设置位的开关自动计算,生成POCSAG码。ML99V4代码发出寻呼机的原理图电路如图1所示。核心组件是高性能微控制器AT89C2051。拨码位微控制器从输入的四位地址码,信息码,传输速率,功能参数等设置位的开关自动计算,生成POCSAG码。信息码,传输速率,位设置等功能参数自动计算,生成POCSAG码。ML99V4代码发出寻呼机的原理图电路如图1所示。核心组件是高性能微控制器AT89C2051。拨码位微控制器从输入的四位地址码,信息码,传输速率,功能参数等设置位的开关自动计算,生成POCSAG码。信息码,传输速率,位设置等功能参数自动计算,生成POCSAG码。ML99V4代码发出寻呼机的原理图电路如图1所示。核心组件是高性能微控制器AT89C2051。拨码位微控制器从输入的四位地址码,信息码,传输速率,功能参数等设置位的开关自动计算,生成POCSAG码。
寻呼机发码电路ML99V4。
射频单元电路由振荡器和射频缓冲放大器电路组成。晶体振荡器的频率稳定电路,因此具有很高的频率稳定性。BP机使用的晶体为二次谐波晶体,在137〜170MHz频段内,只需更换晶体即可改变频率,这时可以略微调整调谐电容器。
程式设计
KV触摸开关和四个DIP开关发出的寻呼机ML99V4电路编程代码。编程时,按住KV,再次敲击KD引导,这时蜂鸣器会响起很长的声音,然后可以按表1所示订购,表2所示为编程代码。除信息代码和地址代码外,每个码都可通过单击KV输入确认,听到两声短促的哔哔声。信息代码和地址代码是每个输入的短哔声,已完成最后一个,按住KV1秒或更长时间,将听到一声长鸣,完成输入代码将听到三声短哔声
寻呼机发码电路ML99V4。 1个
当机器没有损坏启动代码或程序时,它将听到持续的“哔哔”声。如果代码不正确,则对输入进行编码,则每个输入都会听到低调的“哔”声。最后是探头灵敏度设置,拨出四个位置开关的数字越高,探头的灵敏度越低。可以在上面的代码中完成此设置,以在设置后随时使用。设置好电源开关后再次确认。
应用实例
传呼机将以ML99V4的BP机器代码直接发送到电路代码,并假设BP机器频率与无线电频率相同的电路点,其编程步骤如下:(1)保持KV,然后打开切换KD的电源进入状态后,您会听到很久的声音;(2)设置开机无延迟,将四个DIP开关设置为0000,单击KV识别;(3)将相位设置为正常相位,即将四个拨码开关设置为0001位,经KV确认后;(4)设置功能位C,将四个DIP开关设置为确认0011; (5)信息集,如果要发布此数字信息185,868,则应跟随四个DIP开关设置0001,1000,0101,1000,0110,1000; (6)设定速率,如果BP机为512bit,则应在0000后留出四位置开关,才能识别;(7)如果BP机器地址码为0000568,则应在其后设置四个DIP开关0000,0000,0000,0000,0101,0110,1000,最后设置探头的最高灵敏度,即易爆,四个呼叫开关为0000,然后关闭电源即可再次使用。由于案例是直接发送给BP机器代码的,因此该点可以直接连接到探头A开关上,然后再作为一个触摸开关用作发码,因此每次单击触摸开关时,BP机器将在发射过程中接收到三个连续的信息电路会有三倍的音调
该电路也可以与对讲机配合使用,当然最好是射频合成,这种设置频率更方便。当与无线电结合使用时,只需断开C,D,E点,在图2中的C点,发射无线电控制的振荡器接收输入,B点可用于切换控制无线电发射器。
……………………………………………………………………………………………
以下有其他人编写51单片机POCSAG编码程式的链结
https://359303267.github.io/POCSAG/
小小小日天的博客
瞧!这里有个不知道叫什么好的小玩意!
logo
开源!使用单片机发送POCSAG编码呼响BP机
需要注意的是,现在BP机工作频段已经被国家收回,所以自己使用手台、车台等大功率无线发射器在这个频段发射无线电波是违法的,所以需要进行发射信号的衰减,无线发射功率控制在0.1W之内是没有问题的。
单片机使用STC公司的IAP15W4K58S4,时钟频率为27MHz,使用串口1来发送数据,串口波特率为115200。支持1200和512比特速率的POCSAG编码,支持正负相位,可以发送数字信息和汉字信息(不支持混输)
对讲机我用的是宝峰UV-5R。单片机的P36接对讲机的压控振荡器输入端,P35接对讲机的PTT控制端,还要和对讲机共地(至于这三个接线端具体接在哪一个位置,网上一搜就有了)。对讲机的发射频率需要调到BP机的工作频率一样。
BP机我用摩托罗拉精英王和大顾问实验成功,如果不响可以试试切换一下相位。如果显示乱码就换一个响声/功能位。
如果就是不响,要知道哪有这么容易响?地址码、BP机工作频率、对讲机频率调到和BP机工作频率一致、对讲机不能有频偏。如果就是不响,要考虑BP机是否被改过频率,很多BP机在使用的时候都是改过频率的,或者就是对讲机有频偏,可以使用SDR(软件无线电)测试对讲机的频率。
关于如何准确获得BP机的工作频率和地址码,跳转这里:
如何获得BP机的地址码和工作频率?
开源!单片机源码和上位机源码都开源!讨厌那种一个单片机加个Si4463模块就卖你几百块的商家,虽然我知道写程序画板子也不容易,但是价格是成本的十倍着实太坑。
单片机源码:
#include <stc15.h>
#include <intrins.h>
#define TX P36 //数据输出端
#define PTT P35 //PTT控制端
#define HIGH 1 //高电平
#define LOW 0 //低电平
#define NILL_DATA 0x7A89C197 //闲置码
#define SYNC_DATA 0x7CD215D8 //同步码
#define DATA_START 12 //串口中数据开始位置
#define TEXT_OR_NUM 11 //串口中文字或数字标志位置
#define SPEED 10 //串口中速率标志位置
#define UARTBUFF_SIZE 400 //串口接收缓冲区
#define TXBUFF_SIZE 200 //TX发送缓冲区
#define LOWSPEED_TIMER_L 0xE7 //512bit/s时定时器初值,需要微调
#define LOWSPEED_TIMER_H 0x31
#define HIGHTSPEED_TIMER_L 0x1A //1200bit/s时定时器初值,需要微调
#define HIGHTSPEED_TIMER_H 0xA8
unsigned long TxBuff[TXBUFF_SIZE] = {0};//TX发送缓冲区
unsigned char Tx_Num;//地址码发射次序
unsigned char beep;//功能位,1,2,3,4
unsigned char UartBuff[UARTBUFF_SIZE] = "#P12345674HT0001$";//串口缓冲区
unsigned int UartCount = 13;//串口接收计数
unsigned char UartTmp;
bit TM0_FLAG=0;//定时器0标志
bit NewData = 0;//串口是否有新数据收到标志
void UartInit(void);//函数声明
void Delay200ms();
unsigned long calc_bch_and_parity(unsigned long cw_e);
unsigned long calc_addr(unsigned long add,unsigned char fun);
void Timer0Init();
void WaitTF0(void);
void Send_Num(unsigned long s);
void GetAddrNumber();
void calc_NumberData();
void SendTxBuff();
void Empty_Buff();
void calc_TextData();
void UartInit(void) //115200bps@27.000MHz
{
SCON = 0x50; //8位数据,可变波特率
AUXR |= 0x40; //定时器1时钟为Fosc,即1T
AUXR &= 0xFE; //串口1选择定时器1为波特率发生器
TMOD &= 0x0F; //设定定时器1为16位自动重装方式
TL1 = 0xC5; //设定定时初值
TH1 = 0xFF; //设定定时初值
ET1 = 0; //禁止定时器1中断
TR1 = 1; //启动定时器1
ES = 1; //开启接收中断
EA = 1; //开总中断
}
void Timer0Init()
{
AUXR |= 0x80; //定时器时钟1T模式
TMOD &= 0xF0; //设置定时器模式
if(UartBuff[SPEED] == 'L')//为L表示512bit/s速率,下同
{
TL0 = LOWSPEED_TIMER_L; //设置定时初值
TH0 = LOWSPEED_TIMER_H;
}
if(UartBuff[SPEED] == 'H')
{
TL0 = HIGHTSPEED_TIMER_L; //设置定时初值
TH0 = HIGHTSPEED_TIMER_H;
}
ET0=1; //定时器0充许中断
TR0=0;
EA=1; //开总中断
}
void UartSendString(unsigned char* ch, unsigned char n) //串口发送字符串函数
{
unsigned char i;
for(i = 0; i < n; i++)
{
SBUF = *ch++;
while(TI == 0);
TI = 0;
}
}
void Delay200ms() //@27.000MHz
{
unsigned char i, j, k;
_nop_();
_nop_();
i = 21;
j = 133;
k = 210;
do
{
do
{
while (--k);
} while (--j);
} while (--i);
}
unsigned long calc_bch_and_parity(unsigned long cw_e) //BCH校验和奇偶校验函数
{
unsigned char i;
unsigned char 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,unsigned char fun) //地址转换,第1参数为地址,第2参数为功能
{
unsigned long adr;
unsigned long tem;
Tx_Num=(unsigned char)(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 WaitTF0(void)
{
while(!TM0_FLAG);//等待定时器溢出
TM0_FLAG=0;//清标志位
}
void Send_Num(unsigned long s)//发送数据
{
unsigned char n;
for (n=0;n<32;n++)
{
if(s&0x80000000)
{
if(UartBuff[1] == 'N')//判断正负相位,下同
TX = LOW;
else
TX= HIGH;
}
else
{
if(UartBuff[1] == 'N')
TX = HIGH;
else
TX=LOW;
}
WaitTF0();//等待延时结束 0.833ms
s<<=1;
}
}
void Empty_Buff()//清空缓冲区
{
unsigned int i;
for(i = TEXT_OR_NUM; i < UARTBUFF_SIZE; i++)
{
UartBuff = 0x00000000;
}
for(i = TEXT_OR_NUM; i < TXBUFF_SIZE; i++)
{
TxBuff = 0x00000000;
}
}
void GetAddrNumber()
{
unsigned char i;
unsigned long tem;
unsigned long addr_tmp;
addr_tmp = (UartBuff[2] - '0')*1000000;//提取地址码
addr_tmp += (UartBuff[3] - '0')*100000;
addr_tmp += (UartBuff[4] - '0')*10000;
addr_tmp += (UartBuff[5] - '0')*1000;
addr_tmp += (UartBuff[6] - '0')*100;
addr_tmp += (UartBuff[7] - '0')*10;
addr_tmp += (UartBuff[8] - '0');
beep = UartBuff[9] - '0';//提取功能位
tem=calc_addr(addr_tmp,beep);//前面是地址码,后面是BB机内00 01 10 11 代表0,1,2,3种不同的声音
for(i = 0; i < 8; i++)
{
if(i == Tx_Num)//地址码放入对应的帧中
TxBuff[i*2] = calc_bch_and_parity(tem);//取得BCH校验后的地址码序列
else
{
TxBuff[i*2] = NILL_DATA;//其他帧填充闲置码
TxBuff[i*2+1] = NILL_DATA;
}
}
}
void calc_NumberData() //计算数值数据(数字机)
{
unsigned long Num_Negate[UARTBUFF_SIZE] = {0};
unsigned int i, j, k, n;
unsigned char byte_tmp[10], byte_tmp_negate[10];
float TxCount = 0.0;
for(i = DATA_START; i < UARTBUFF_SIZE; i++) //表意字符替换
{
if(UartBuff == 'A')
UartBuff = 0x0A;
if(UartBuff == 'B')
UartBuff = 0x0B;
if(UartBuff == 'C')
UartBuff = 0x0C;
if(UartBuff == 'D')
UartBuff = 0x0D;
if(UartBuff == 'E')
UartBuff = 0x0E;
if(UartBuff == 'F')
UartBuff = 0x0F;
}
n = DATA_START;
for(i = DATA_START; i < UARTBUFF_SIZE; i++) //数字的ASIIC码只用到第四位,所以将所有数字的低四位合并,高四位丢弃
{
if(i % 2 == 0)
UartBuff[n] = UartBuff << 4;
else
{
UartBuff[n] |= UartBuff & 0x0f;
n++;
}
}
k = Tx_Num * 2 + 1; //定位到地址码后数据所在的位置
for(i = DATA_START; i < UARTBUFF_SIZE; i += 5) //按四位取出并放在高四位准备倒序
{
byte_tmp[0] = (UartBuff & 0xf0);
byte_tmp[1] = (UartBuff & 0x0f) << 4;
byte_tmp[2] = (UartBuff[i + 1] & 0xf0);
byte_tmp[3] = (UartBuff[i + 1] & 0x0f) << 4;
byte_tmp[4] = (UartBuff[i + 2] & 0xf0);
byte_tmp[5] = (UartBuff[i + 2] & 0x0f) << 4;
byte_tmp[6] = (UartBuff[i + 3] & 0xf0);
byte_tmp[7] = (UartBuff[i + 3] & 0x0f) << 4;
byte_tmp[8] = (UartBuff[i + 4] & 0xf0);
byte_tmp[9] = (UartBuff[i + 4] & 0x0f) << 4;
for(j = 0; j < 10; j++) //倒序
{
for(n = 0; n < 8; n++)
{
byte_tmp_negate[j] <<= 1;
byte_tmp_negate[j] |= (byte_tmp[j] >> n) & 0x01;
}
}
Num_Negate[k] = 0x80000000; //重新组合
Num_Negate[k] |= (unsigned long)byte_tmp_negate[0] << 27;
Num_Negate[k] |= (unsigned long)byte_tmp_negate[1] << 23;
Num_Negate[k] |= (unsigned long)byte_tmp_negate[2] << 19;
Num_Negate[k] |= (unsigned long)byte_tmp_negate[3] << 15;
Num_Negate[k] |= (unsigned long)byte_tmp_negate[4] << 11;
Num_Negate[k + 1] = 0x80000000;
Num_Negate[k + 1] |= (unsigned long)byte_tmp_negate[5] << 27;
Num_Negate[k + 1] |= (unsigned long)byte_tmp_negate[6] << 23;
Num_Negate[k + 1] |= (unsigned long)byte_tmp_negate[7] << 19;
Num_Negate[k + 1] |= (unsigned long)byte_tmp_negate[8] << 15;
Num_Negate[k + 1] |= (unsigned long)byte_tmp_negate[9] << 11;
k = k + 2;
}
//UartCount = 25;
n = Tx_Num * 2 + 1; //将数据合并到Tx发送缓冲区并计算校验码
TxCount = 0.0;
for(i = Tx_Num * 2 + 1; i < UARTBUFF_SIZE; i++)
{
if(TxCount >= (UartCount - DATA_START - 1))
break;
if(i % 16 == 0) //每8帧(16个码字)插入一个同步码
TxBuff[n++] = SYNC_DATA;
TxBuff[n++] = calc_bch_and_parity( Num_Negate);
TxCount += 5; //串口接收5个数字相当于POCSAG码中一个码字
if(n >= TXBUFF_SIZE || i >= UARTBUFF_SIZE) //超出缓冲区退出
break;
}
}
void calc_TextData() //计算汉字数据
{
unsigned long Text_Negate[UARTBUFF_SIZE] = {0};
unsigned int n, i, k, byte_tmp;
float TxCount = 0.0;
for(k = DATA_START; k < UARTBUFF_SIZE; k++) //字节按位倒序
{
byte_tmp = UartBuff[k];
UartBuff[k] = 0;
for(n = 0; n < 8; n++) //倒序
{
UartBuff[k] <<= 1;
UartBuff[k] |= (byte_tmp >> n) & 0x01;
}
UartBuff[k] &= 0xFE; //倒序后丢弃最低位
}
k = Tx_Num * 2 + 1;
for(n = DATA_START; n < UARTBUFF_SIZE; n += 20) //移位,20个字节一循环
{
Text_Negate[k] = 0x80000000;
Text_Negate[k] |= (unsigned long)UartBuff[n] << 23;
Text_Negate[k] |= (unsigned long)UartBuff[n + 1] << 16;
Text_Negate[k] |= (unsigned long)UartBuff[n + 2] << 9;
Text_Negate[k] &= 0xfffff800;
Text_Negate[k + 1] = 0x80000000;
Text_Negate[k + 1] |= (unsigned long)UartBuff[n + 2] << 29;
Text_Negate[k + 1] &= 0xC0000000;
Text_Negate[k + 1] |= (unsigned long)UartBuff[n + 3] << 22;
Text_Negate[k + 1] |= (unsigned long)UartBuff[n + 4] << 15;
Text_Negate[k + 1] |= (unsigned long)UartBuff[n + 5] << 8;
Text_Negate[k + 1] &= 0xfffff800;
Text_Negate[k + 2] = 0x80000000;
Text_Negate[k + 2] |= (unsigned long)UartBuff[n + 5] << 28;
Text_Negate[k + 2] &= 0xE0000000;
Text_Negate[k + 2] |= (unsigned long)UartBuff[n + 6] << 21;
Text_Negate[k + 2] |= (unsigned long)UartBuff[n + 7] << 14;
Text_Negate[k + 2] |= (unsigned long)UartBuff[n + 8] << 7;
Text_Negate[k + 2] &= 0xfffff800;
Text_Negate[k + 3] = 0x80000000;
Text_Negate[k + 3] |= (unsigned long)UartBuff[n + 8] << 27;
Text_Negate[k + 3] &= 0xF0000000;
Text_Negate[k + 3] |= (unsigned long)UartBuff[n + 9] << 20;
Text_Negate[k + 3] |= (unsigned long)UartBuff[n + 10] << 13;
Text_Negate[k + 3] |= (unsigned long)UartBuff[n + 11] << 6;
Text_Negate[k + 3] &= 0xfffff800;
Text_Negate[k + 4] = 0x80000000;
Text_Negate[k + 4] |= (unsigned long)UartBuff[n + 11] << 26;
Text_Negate[k + 4] &= 0xF8000000;
Text_Negate[k + 4] |= (unsigned long)UartBuff[n + 12] << 19;
Text_Negate[k + 4] |= (unsigned long)UartBuff[n + 13] << 12;
Text_Negate[k + 4] |= (unsigned long)UartBuff[n + 14] << 5;
Text_Negate[k + 4] &= 0xfffff800;
Text_Negate[k + 5] = 0x80000000;
Text_Negate[k + 5] |= (unsigned long)UartBuff[n + 14] << 25;
Text_Negate[k + 5] &= 0xFC000000;
Text_Negate[k + 5] |= (unsigned long)UartBuff[n + 15] << 18;
Text_Negate[k + 5] |= (unsigned long)UartBuff[n + 16] << 11;
Text_Negate[k + 5] |= (unsigned long)UartBuff[n + 17] << 4;
Text_Negate[k + 5] &= 0xfffff800;
Text_Negate[k + 6] = 0x80000000;
Text_Negate[k + 6] |= (unsigned long)UartBuff[n + 17] << 24;
Text_Negate[k + 6] &= 0xFE000000;
Text_Negate[k + 6] |= (unsigned long)UartBuff[n + 18] << 17;
Text_Negate[k + 6] |= (unsigned long)UartBuff[n + 19] << 10;
Text_Negate[k + 6] &= 0xfffff800;
k += 7;
}
n = Tx_Num * 2 + 1;
TxCount = 0.0;
for(i = Tx_Num * 2 + 1; i < UARTBUFF_SIZE; i++) //将数据合并到Tx发送缓冲区并计算校验码
{
if(TxCount >= (UartCount - DATA_START - 1))
break;
if(i % 16 == 0) //每8帧(16个码字)插入一个同步码
TxBuff[n++] = SYNC_DATA;
TxBuff[n++] = calc_bch_and_parity( Text_Negate);
TxCount += 2.8571428571; //串口接收2.8571428571个字节相当于POCSAG码中一个码字
if(n >= TXBUFF_SIZE || i >= UARTBUFF_SIZE)
break;
}
}
void SendTxBuff()
{
unsigned int i;
PTT = 0; //触发PTT
Delay200ms(); //PTT延时,根据对讲机不同进行调整
if(UartBuff[SPEED] == 'L')
{
TL0 = LOWSPEED_TIMER_L; //设置定时初值
TH0 = LOWSPEED_TIMER_H;
}
if(UartBuff[SPEED] == 'H')
{
TL0 = HIGHTSPEED_TIMER_L; //设置定时初值
TH0 = HIGHTSPEED_TIMER_H;
}
TR0 = 1; //启动定时器
for(i = 0; i < 18; i++)//至少发送576个前导码,只能多,不能少
{
Send_Num(0xAAAAAAAA);
}
Send_Num(SYNC_DATA);//发送同步码
for(i = 0; i < TXBUFF_SIZE; i++)//将TX发送缓冲区中的数据发出
{
if(TxBuff == 0x00000000 || TxBuff == 0xffffffff)//如果缓冲区中数据为全0或全1则表示发送完毕
break;
Send_Num(TxBuff);
}
TX=LOW;
TR0 = 0;
Delay200ms(); //发送完毕PTT延时,根据对讲机不同进行调整
Delay200ms();
Delay200ms();
PTT = 1;
UartSendString("OK\r\n",4); //串口输出调试信息
UartSendString("UartCount=",10);
SBUF = UartCount / 100 + '0';
while(TI == 0);
TI = 0;
SBUF = (UartCount / 10) % 10 + '0';
while(TI == 0);
TI = 0;
SBUF = UartCount % 10 + '0';
while(TI == 0);
TI = 0;
UartSendString("\r\n",2);
}
void main()
{
UartInit();//串口初始化
Timer0Init();//定时器0初始化
TX = 0; //初始化IO引脚
PTT= 1;
while(1)
{
//NewData = 1;
if(NewData == 1 && (UartBuff[TEXT_OR_NUM] == 'N' || UartBuff[TEXT_OR_NUM] == 'T'))
{
GetAddrNumber();//获取地址码及功能位
if(UartBuff[TEXT_OR_NUM] == 'N')
calc_NumberData();//计算数字数据
if(UartBuff[TEXT_OR_NUM] == 'T')
calc_TextData();//计算文字数据
SendTxBuff();//发送数据
Empty_Buff();//清空TX发送缓冲区和串口接收缓冲区
NewData = 0;
}
}
}
void UART_RxData() interrupt 4 //串口接收中断函数
{
if(RI == 1)
{
RI = 0;
UartTmp = SBUF;
if(UartTmp == '#') //串口开头
UartCount = 0;
if(UartTmp == '$') //串口结尾
{
UartTmp = 0x00;
NewData = 1;
}
UartBuff[UartCount] = UartTmp;
UartCount++; //串口计数
if(UartCount >= UARTBUFF_SIZE) //超出缓冲区归零
UartCount = 0;
}
}
void IntTimer0() interrupt 1 //定时器0中断函数
{
if(UartBuff[SPEED] == 'L')
{
TL0 = LOWSPEED_TIMER_L; //设置定时初值
TH0 = LOWSPEED_TIMER_H;
}
if(UartBuff[SPEED] == 'H')
{
TL0 = HIGHTSPEED_TIMER_L; //设置定时初值
TH0 = HIGHTSPEED_TIMER_H;
}
TM0_FLAG=1;
}
|
本帖子中包含更多资源
您需要 登录 才可以下载或查看,没有帐号?注册
x
阿莫论坛20周年了!感谢大家的支持与爱护!!
如果天空是黑暗的,那就摸黑生存;
如果发出声音是危险的,那就保持沉默;
如果自觉无力发光,那就蜷伏于牆角。
但是,不要习惯了黑暗就为黑暗辩护;
也不要为自己的苟且而得意;
不要嘲讽那些比自己更勇敢的人。
我们可以卑微如尘土,但不可扭曲如蛆虫。
|