?? rds_link.c
字號:
// Gloables ------------------ //
WORD PICode; //
BYTE GroupType; //
BYTE PTY; //
BOOL bTP; // TP
BOOL bMS; // M/S
BOOL bTA; // TA
BOOL bRdsrec;
BOOL bRDSOk = 0; // set when group 0 ready
BOOL bTextOk = 0; // set when group 2 ok, Text ready, need 16 groups
WORD aRDS_Text[16]; // radio text, 32 bytes maxium
WORD aPS[4]; // Service name, 8 chars
// Locals ------------------- //
static WORD aRDS_Block[4]; // Groupe = 4 blocks
static WORD rdsdata[2]; // byte 1, byte 2
// 0 0 0 0 0 0 c9 c8 c7 c6 c5 c4 c3 c2 c1 c0
static WORD crc;
static BYTE pscnt;
static BYTE textcnt;
//BYTE bytecnt;
//-------------------------------------------------------------------------
// RDS Callback
//-------------------------------------------------------------------------
void RDS_BLOCK_Auto_Update(void){
BYTE chr_addr;
static BOOL bTextAB = 0;
PICode = aRDS_Block[0];
GroupType = (aRDS_Block[1] >> 11) & 0x1f;
PTY = (aRDS_Block[1] >> 5) & 0x1f;
switch (GroupType){
case 0: // Group 0A
case 1: // Group 0B
bTP = aRDS_Block[1] & 0x0400; // bit 10
bTA = aRDS_Block[1] & 0x0010; // bit 4
bMS = aRDS_Block[1] & 0x0008; // bit 3
chr_addr = aRDS_Block[1] & 0x03;
if (chr_addr == 0) pscnt = 0; else pscnt ++;
if (chr_addr == pscnt) aPS[chr_addr] = aRDS_Block[3]; else bRDSOk = 0;
if (pscnt == 3) bRDSOk = 1;
break;
case 4: // Group 2A
// if TextAB changed, should update
if (bTextAB != (aRDS_Block[1] & 0x10)){ // Text AB : bit 5 in block 1
bTextAB = (aRDS_Block[1] & 0x10);
textcnt = 0;
}
chr_addr = aRDS_Block[1] & 0x0f;
if (chr_addr == 0) textcnt = 0; else textcnt ++;
if (chr_addr == textcnt) {
aRDS_Text[chr_addr*2] = aRDS_Block[2]; aRDS_Text[chr_addr*2 + 1] = aRDS_Block[3];
// if "0x0d" found, the text finish.
if (((aRDS_Text[chr_addr*2] & 0x00ff) == 0x000d) || ((aRDS_Text[chr_addr*2] & 0xff00) == 0x0d00) || ((aRDS_Text[chr_addr*2+1] & 0x00ff) == 0x000d) || ((aRDS_Text[chr_addr*2+1] & 0xff00) == 0x0d00)){
bTextOk = 1; textcnt = 0;
}
}
else {
bTextOk = 0;
}
if (textcnt >= 16) {bTextOk = 1; textcnt = 0;}
break;
case 5: // Group 2B
// if TextAB changed, should update
if (bTextAB != (aRDS_Block[1] & 0x10)){ // Text AB : bit 5 in block 1
bTextAB = (aRDS_Block[1] & 0x10);
textcnt = 0;
}
chr_addr = aRDS_Block[1] & 0x0f;
if (chr_addr == 0) textcnt = 0; else textcnt ++;
if (chr_addr == textcnt) {
aRDS_Text[chr_addr] = aRDS_Block[2];
// if "0x0d" found, the text finish.
if (((aRDS_Text[chr_addr] & 0x00ff) == 0x000d) || ((aRDS_Text[chr_addr+1] & 0xff00) == 0x0d00)){
bTextOk = 1;textcnt = 0;
}
}
else {
bTextOk = 0;
}
if (textcnt >= 16) {bTextOk = 1; textcnt = 0;}
break;
default:
break;
}
}
// --------------------------------------------------------------
// RDS_CRCCheck
// --------------------------------------------------------------
void RDS_CRCCheck(void){
bit bCFlag;
BYTE TempH, TempL;
TempH = rdsdata[0] / 0x100;
TempL = rdsdata[0] % 256;
//C9
ACC = TempH & 0x7c;
bCFlag = P;
ACC = TempL & 0x3e;
bCFlag ^= P;
if(bCFlag)crc = 0x200;
//C8
ACC = TempH & 0x3e;
bCFlag = P;
ACC = TempL & 0x1f;
bCFlag ^= P;
if(bCFlag) crc |= 0x100;
//C7
ACC = TempH & 0x63;
bCFlag = P;
ACC = TempL & 0x31;
bCFlag ^= P;
if(bCFlag) crc |= 0x80;
//C6
ACC = TempH&0xcd;
bCFlag = P;
ACC = TempL & 0xa6;
bCFlag ^= P;
if(bCFlag)crc |= 0x40;
//C5
ACC = TempH & 0xe6;
bCFlag = P;
ACC = TempL & 0xd3;
bCFlag ^= P;
if(bCFlag)crc |= 0x20;
//C4
ACC = TempH & 0x8f;
bCFlag = P;
ACC = TempL & 0x57;
bCFlag ^= P;
if(bCFlag) crc |= 0x10;
//C3
ACC = TempH & 0x3b;
bCFlag = P;
ACC = TempL & 0x95;
bCFlag ^= P;
if(bCFlag)crc |= 0x08;
//C2
ACC = TempH & 0xe1;
bCFlag = P;
ACC = TempL & 0xf4;
bCFlag ^= P;
if(bCFlag)crc |= 0x04;
//C1
ACC = TempH & 0xf0;
bCFlag = P;
ACC = TempL & 0xfa;
bCFlag ^= P;
if(bCFlag) crc |= 0x02;
//C0
ACC = TempH & 0xf8;
bCFlag = P;
ACC = TempL & 0x7d;
bCFlag ^= P;
if(bCFlag) crc |= 0x01;
}
// -------------------------------------------------- //
#define OFFSET_A 0x00fc // 0x00fc
#define OFFSET_B 0x0198 // 0x0198
#define OFFSET_C 0x0168 // 0x0168
#define OFFSET_C2 0x0350 // 0x0350
#define OFFSET_D 0x01b4 // 0x01b4
// --------------------------------------------------------------
// Interrupt Handle Routines
// --------------------------------------------------------------
// ISREX0:EXTERNAL INTERRUPT 0 SERVICE ROUTINE
static void ISREX1() interrupt 2{
static BYTE seq = 0;
static BOOL bSynch = 0;
static BYTE bitcnt;
bRdsrec = 1;
rdsdata[0] <<= 1; if (rdsdata[1] & 0x0200) rdsdata[0] |= 0x0001;
rdsdata[1] <<= 1;
if (PIN_RDS_DATA) rdsdata[1] |= 0x0001; else rdsdata[1] &= 0x03fe;
//void Rds_process (void){
rdsdata[1] &= 0x03ff;
bitcnt ++;
if (!bSynch){
crc = 0;
RDS_CRCCheck(); // Input = rdsdata[0], output = crc;
crc ^= rdsdata[1];
if (crc == OFFSET_A){
seq = 1; bSynch = 1; bitcnt = 0; aRDS_Block[0] = rdsdata[0];
}
}
else if (bitcnt == 26){
bitcnt = 0;
crc = 0;
RDS_CRCCheck(); // Input = rdsdata[0], output = crc;
crc ^= rdsdata[1];
// -------------------------- Syn Checking ----------------------- //
if ((crc == OFFSET_A) && (seq == 0)){
seq = 1; aRDS_Block[0] = rdsdata[0];
}
else if ((crc == OFFSET_B) && (seq == 1)){
seq = 2; aRDS_Block[1] = rdsdata[0];
}
else if ((crc == OFFSET_C) && (seq == 2)){
seq = 3; aRDS_Block[2] = rdsdata[0];
}
else if ((crc == OFFSET_C2) && (seq == 2)){
seq = 3; aRDS_Block[2] = rdsdata[0];
}
else if ((crc == OFFSET_D) && (seq == 3)){
seq = 0; aRDS_Block[3] = rdsdata[0];
RDS_BLOCK_Auto_Update();
}
else { // Lost sychronization
bSynch = 0; bRDSOk = 0; bTextOk = 0;
}
}
}
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -