CALL机POSAG码解码电路与软件 电原理图 POSAG.BIN
CALL机信号编码格式使用由Philips公司开发的POSAG码。关于POSAG解码方案,总体来说分为软件解码及硬件解码两种。软件解码不需要额外的硬件,原则上,使用ATMEL
89LV51的外部中断及定时器即可。然而,事实却并非如此,因为,电磁波经空中传播,会受到严重的干扰,使用CPU解码误码率很高,基本上没有实用价值,甚至连同步信号也无法检出。因此,所有的CALL机均使用硬件解码,无一例外。
S-70L41B为EPSON公司开发的具有完整功能的POSAG解码芯片,POSAG信号经内置的滤波器滤波后,送入解码电路解码。S-70L41B具有串行接口,很方便与各种单片机连接。S-70L41B可同时设定6个不同的接收地址,支持512/1200/2400三种速率,并具有BCH校验电路,可纠正2位错误。在AT89LV51与S-70L41B的接口电路中。J1为标准的字符型LCD接口。J2输入由RF接收板输出的POSAG信号。常见的RF接收板大体分为两种:固定频率和PLL锁相环频率合成。从使用角度来讲,固定频率的RF接受板较为方便,无须对PLL电路进行初始化。RF接收板的控制信号由电源、POSAG信号输出端及节电控制信号组成(如果是PLL接收板还有PLL控制信号)。一般来说将节电控制信号接到高电平即可使接收板正常工作。进一步的资料请参考其电路图极其说明。
完整的CALL机POSAG解码软件如下,使用Franklin C-51 V5.02编译。( POSAG.BIN )
#include "stdio.h"
#include "reg51.h"
#define DO P10
#define INT P32
#define BUSY P11
#define DI P12
#define CLK P13
#define CS P33
#define SGIN 0x02
#define DR0 0x04
#define DR1 0x00
#define CSEL 0x40
#define CDIS 0x00
void delay(void);
void RUN(void);
void ReadMsg(void);
void WriteReg(unsigned char,unsigned char);
unsigned char Msg[20],buffer[20],remained;
unsigned long int ID = 1513050;
main()
{
unsigned int dly;
unsigned char ch,cn;
SCON = 0x50;
TMOD |= 0x20;
TH1 = 0xfd;
TR1 = 1;
TI = 1;
puts("POSAG decode Program V1.0.");
WriteReg(0x1a,CDIS + CSEL + DR1 + DR0 + SGIN);
for(dly=0;dly<500;dly++);
remained = (unsigned char) (ID % 8);
ID = ID / 8;
ch = (unsigned char)(ID&0xff);
WriteReg(0x00,ch);
for(dly=0;dly<500;dly++);
ch = (unsigned char) ((ID>>8) & 0xff);
WriteReg(0x01,ch);
for(dly=0;dly<500;dly++);
ch = (unsigned char) ((ID>>16) & 0xff);
WriteReg(0x02,ch);
for(dly=0;dly<500;dly++);
ch = (unsigned char)(remained<<3);
WriteReg(0x18,ch);
for(dly=0;dly<500;dly++);
RUN();
while(1) {
while(P32);
for(cn=0;cn<20;cn++) Msg[cn] = 0;
putch('#');
ReadMsg();
}
}
void delay(void) {
unsigned int cn;
for(cn=0;cn<5;cn++);
}
void WriteReg(unsigned char i,unsigned char j) {
unsigned char cn,ch;
while(!BUSY);
CS = 0;
ch = 0x20 + i;
for(cn=0;cn<8;cn++) {
if(ch&0x01) DI = 1; else DI = 0;
CLK = 0; delay(); CLK = 1; delay();
ch = ch >> 1;
}
ch = j;
for(cn=0;cn<8;cn++) {
if(ch&0x01) DI = 1; else DI = 0;
CLK = 0; delay(); CLK = 1; delay();
ch = ch >> 1;
}
CS = 1;
}
void RUN(void) {
unsigned char cn;
while(!BUSY);
CS = 0;
for(cn=0;cn<8;cn++) {
DI = 1;
CLK = 0; delay(); CLK = 1; delay();
}
CS = 1;
}
void ReadMsg(void) {
unsigned char cn,ch,s0,s1,sn,d;
while(!BUSY);
CS = 0;
ch = 0x80; s1 = 0; // Read s0
for(cn=0;cn<8;cn++) {
if(ch&0x01) DI = 1; else DI = 0;
CLK = 0; delay(); CLK = 1; delay();
s1 = s1 >> 1;if(DO) s1 |= 0x80; ch = ch >> 1;
}
while(!BUSY);
ch = 0x00; s0 = 0; // Dummy
for(cn=0;cn<8;cn++) {
if(ch&0x01) DI = 1; else DI = 0;
CLK = 0; delay(); CLK = 1; delay();
s0 = s0 >> 1; if(DO) s0 |= 0x80; ch = ch >> 1;
}
if(s0 & 0x06) goto end;
while(!BUSY);
ch = 0xb0; // Read DREG
for(cn=0;cn<8;cn++) {
if(ch&0x01) DI = 1; else DI = 0;
CLK = 0; delay(); CLK = 1; delay();
ch = ch >> 1;
}
sn = 0;
while(1) {
while(!BUSY);
ch = 0x80; d = 0; // Read s0
for(cn=0;cn<8;cn++) {
if(ch&0x01) DI = 1; else DI = 0;
CLK = 0; delay(); CLK = 1; delay();
d = d >> 1; if(DO) d |= 0x80;
ch = ch >> 1;
}
Msg[sn] = d & 0x0f;
while(!BUSY);
ch = 0xb0; s0 = 0; // Read DREG
for(cn=0;cn<8;cn++) {
if(ch&0x01) DI = 1; else DI = 0;
CLK = 0; delay(); CLK = 1; delay();
s0 = s0 >> 1; if(DO) s0 |= 0x80;
ch = ch >> 1;
}
sn++; if(s0 & 0x04) break;
}
end:
CS = 1;
for(cn=0;cn<sn;cn++) { if(Msg[cn]<10) putchar('0'+Msg[cn]); }
puts("\r");
}
|