⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 rds.c

📁 RDS技術是利用調頻多工技術
💻 C
字号:
//-------------------------------------------------------------------------
// RDS Decoding
// COPYRIGHT (C) 2003, Enbia Technology Inc.
// Target: 8031
// AUTHOR: STEVEN LUO
//
// Revision History:
// 2003/2/16 - Original Version
//-------------------------------------------------------------------------
#include <reg51.h>
#include <types.h>
#include <intrins.h>
#include <bin.h>

//#define DEBUG

// Gloables ------------------ //
WORD PICode;        //
BYTE GroupType;        //
BYTE PTY;          //
BOOL bTP;          // TP
BOOL bMS;          // M/S
BOOL bTA;          // TA

BOOL bRDSOk = 0;      // set when group 0 ready
BOOL bTextOk = 0;      // set when group 2 ok, Text ready, need 16 groups

extern WORD aRDS_Text[32];  // radio text 
extern 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 WRD crc;
static BYTE pscnt;
static BYTE textcnt;
BYTE bytecnt;

#ifdef DEBUG
  sbit PIN_RDS_DATA = P3^1;  // using 89c51
  sbit PIN_TEST = P3^7;    
#else
  sbit PIN_RDS_DATA = P3^7;  // using 89c2051
  sbit PIN_TEST = P1^7;O    
#endif

//-------------------------------------------------------------------------
// 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] = aRDS_Block[2]; aRDS_Text[chr_addr + 1] = aRDS_Block[3]; 
        // if "0x0d" found, the text finish.
        if (((aRDS_Text[chr_addr] & 0x00ff) == 0x000d) || ((aRDS_Text[chr_addr] & 0xff00) == 0x0d00) || ((aRDS_Text[chr_addr+1] & 0x00ff) == 0x000d) ||  ((aRDS_Text[chr_addr+1] & 0xff00) == 0x0d00)){
          bTextOk = 1; bytecnt=textcnt*2;textcnt = 0; 
        }
       }
      else { 
        bTextOk = 0;
      }
      if (textcnt >= 16) {bTextOk = 1; bytecnt=textcnt*2;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] & 0xff00) == 0x0d00)){
          bTextOk = 1; bytecnt=textcnt;textcnt = 0; 
        }
       }
      else { 
        bTextOk = 0;
      }
      if (textcnt >= 16) {bTextOk = 1;bytecnt=textcnt; 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 ISREX0() interrupt 0{
static BYTE seq = 0;
static BOOL bSynch = 0;
static BYTE bitcnt;

  PIN_TEST = 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;
  
  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;
    }
  }          

  PIN_TEST = 0;
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -