xiefengwise 发表于 2007-5-20 12:03:58

了解收音头RDS的朋友进来看看(附有源程序)

void RDS_BLOCK_Auto_Update(void)

{                       

        uchar chr_addr;       

        //bit sign;

        //uchar k;                                       

        static bit bTextAB = 0;

        //static uint utc_offset;

        //static uint mjd;

        if(PICode != aRDS_Block)       

        {

                PICode = aRDS_Block;       

                //RDS_clear();//写清除函数               

        }                               

        GroupType = (aRDS_Block >> 11) & 0x1f;       

        PTY = (aRDS_Block >> 5) & 0x1f;//mode

        PTY_disp_F=1;               

        switch (GroupType)

        {                                               

                case 0:        // Group 0A                                       

                case 1: // Group 0B                                       

                        bTP = aRDS_Block & 0x0400;                // bit 10 TP//traffic programe

                        bTA = aRDS_Block & 0x0010;                // bit 4 TA//traffic 公告TP。TA都为1有交通信息

                        bMS = aRDS_Block & 0x0008;                // bit 3 ms        music speech 0为speech,1为music        

                        chr_addr = aRDS_Block & 0x03;

                        if (chr_addr == 0) pscnt = 0;

                        else         pscnt ++;

                        if (chr_addr == pscnt)

                        {

                                chr_addr*=2;

                                aPS = aRDS_Block>>8; //四组字符信号,电台名

                                aPS = aRDS_Block&0xff;                               

                        }

                        else         bRDSOk = 0;

                        if (pscnt == 3)

                        {

                                bRDSOk = 1;

                                PS_disp_F=1;

                        }

                        break;

                case 4:        // Group 2AText character number

                        // if TextAB changed, should update

                        if (bTextAB != (aRDS_Block & 0x10))        // Text AB : bit 5 in block 1 版本一变马上清0

                        {

                                bTextAB = (aRDS_Block & 0x10);

                                textcnt = 0;

                        }

                        chr_addr = aRDS_Block & 0x0f;

                        if (chr_addr == 0)

                                textcnt = 0;

                        else         textcnt ++;

                        if (chr_addr == textcnt)

                        {

                                chr_addr*=4;

                                aRDS_Text = aRDS_Block>>8;

                                aRDS_Text = aRDS_Block&0xff;

                                aRDS_Text = aRDS_Block>>8;

                                aRDS_Text = aRDS_Block&0xff;                               

                                // if "0x0d" found, the text finish.

                                if (aRDS_Text==0x0d)

                                {

                                        if(chr_addr!=0)text_length=chr_addr-1;

                                        bTextOk = 1; textcnt = 0;

                                        if(!TEXT_disp_F)TEXT_disp_F=1;

                                }

                                else if(aRDS_Text==0x0d)

                                {

                                        text_length=chr_addr;

                                        bTextOk = 1; textcnt = 0;

                                        if(!TEXT_disp_F)TEXT_disp_F=1;

                                }

                                else if(aRDS_Text==0x0d)

                                {

                                        text_length=chr_addr+1;

                                        bTextOk = 1; textcnt = 0;

                                        if(!TEXT_disp_F)TEXT_disp_F=1;

                                }

                                else if(aRDS_Text==0x0d)

                                {

                                        text_length=chr_addr+2;

                                        bTextOk = 1; textcnt = 0;

                                        if(!TEXT_disp_F)TEXT_disp_F=1;

                                }

                          }

                        else

                        {

                                bTextOk = 0;

                        }

                        if (textcnt >= 16) {bTextOk = 1; textcnt = 0;}

                        break;       

                case 5: // Group 2B                                       

                        chr_addr = aRDS_Block & 0x0f;

                        if (chr_addr == 0) textcnt = 0;

                        else         textcnt ++;

                        if (chr_addr == textcnt)

                        {

                                chr_addr*=2;

                                aRDS_Text = aRDS_Block>>8;

                                aRDS_Text = aRDS_Block&0xff;

                                // if "0x0d" found, the text finish.

                                if (aRDS_Text==0x0d)

                                {

                                        if(chr_addr!=0)text_length=chr_addr-1;

                                        bTextOk = 1; textcnt = 0;

                                        if(!TEXT_disp_F)TEXT_disp_F=1;

                                }

                                else if(aRDS_Text==0x0d)

                                {

                                        text_length=chr_addr;

                                        bTextOk = 1; textcnt = 0;

                                        if(!TEXT_disp_F)TEXT_disp_F=1;

                                }

                          }

                        else

                        {

                                bTextOk = 0;

                        }

                        if (textcnt >= 16) {bTextOk = 1; textcnt = 0;}

                        break;       

                /*case 8://group 4A                               

                        break;*/

                default:break;                                               

        }       

}

// --------------------------------------------------------------

// RDS_CRCCheck

// --------------------------------------------------------------

void RDS_CRCCheck(void)

{

        bit bCFlag;

        uchar TempH, TempL;

        TempH = rdsdata / 0x100;

        TempL = rdsdata % 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

void INT11() interrupt 2 using 2

{

static uchar seq = 0;

static bit bSynch = 0;

static uchar bitcnt;

        //PIN_TEST = 1;       

        rdsdata <<= 1;

        if (rdsdata & 0x0200) rdsdata |= 0x0001;//存信息16位

        rdsdata <<= 1;

        if (RDS_DATA) rdsdata|= 0x0001; //存12较验

        rdsdata &= 0x03ff;

        bitcnt ++;

        if (!bSynch)//先找到头码

        {

                crc = 0;

                RDS_CRCCheck();                // Input = rdsdata, output = crc;

                crc ^= rdsdata;

                if (crc == OFFSET_A)

                {

                        seq = 1; bSynch = 1; bitcnt = 0; aRDS_Block = rdsdata;

                }

        }

        else if (bitcnt == 26)

        {

                bitcnt = 0;

                crc = 0;

                RDS_CRCCheck();                // Input = rdsdata, output = crc;

                crc ^= rdsdata;

                // -------------------------- Syn Checking ----------------------- //

                if ((crc == OFFSET_A) && (seq == 0))

                {

                        seq = 1; aRDS_Block = rdsdata;

                }

                else if ((crc == OFFSET_B) && (seq == 1))

                {

                        seq = 2; aRDS_Block = rdsdata;

                }

                else if ((crc == OFFSET_C) && (seq == 2))

                {

                        seq = 3; aRDS_Block = rdsdata;

                }

                else if ((crc == OFFSET_C2) && (seq == 2))

                {

                        seq = 3; aRDS_Block = rdsdata;

                }

                else if ((crc == OFFSET_D) && (seq == 3))

                {

                        seq = 0; aRDS_Block = rdsdata;

                        RDS_BLOCK_Auto_Update();

                }

                else // Lost sychronization

                {       

                        bSynch = 0; bRDSOk = 0; bTextOk = 0;

                }

        }                               

        //PIN_TEST = 0;

}

这个程序虽不完整,但也差不多了,可以用来调试了,我也是在网上下载的,原理我也知道了,写得挺清楚的,可是我就是调不成功,不知道是硬件问题还是怎么回事,我在收音厂用RDS信号发生器调试,频率也对应了,那些信号都是没有规律的变来变去,进了OFFSETA下面26位的校验字变来变去,没有一次一等于OFFSETB,极郁闷,哪个好心人帮我提点提点,非常感谢!!我在深圳天安数码城工作,近的话,一定当面感谢。

Grant 发表于 2007-5-20 17:14:17

你用的RDS芯片是哪家,不说清楚就是知道也回答不了你。

xiefengwise 发表于 2007-5-21 21:28:17

回复Grant :

    我不知道芯片规格,没有打开收音盒。我是按照欧洲标准来写的,就是接收RDS数据啊,RDS的CLK接下降引中断啊。不同的芯片会有不同的写法吗?我看标准上就是只有两种算法啊,两种矩阵信息,我用的是第一种,很多网上碟机的程序用第二种,那种计算共大些,我怕我的51处理不了。能留个电话或QQ吗?有空帮我一下。谢谢!!

moov 发表于 2007-12-7 20:25:09

你这个程序是从哪个网站上down下来的?

armok 发表于 2007-12-7 20:43:15

lzerof 发表于 2008-9-3 16:49:15

楼主调试通了没有?在那儿下载欧洲的RDS标准?

lzerof 发表于 2008-9-3 17:03:43

armok 阿莫
RDS,国内还没有电台有这个信号.你装了也收不到信息...除非你开车到深圳,珠海,靠香港的地方才可以收到...

halloween 发表于 2008-9-3 17:07:54

楼主是哪个收音机厂的?国产机也要有rds了吗?s2000已经出了,排除在外。难倒是安键DTS-09?或者是de1108吧????

Edesigner 发表于 2009-5-25 22:04:36

没有资料只有一份代码有屁用

reynold520 发表于 2010-12-21 20:17:05

51 的单片机的话要看你处理的速度,至少26ms 内要处理完一组数据,否则会出现同步有问题的情况,就类似于你这这个情况!

drydiy 发表于 2013-12-12 18:39:40

帮你,我也在搞。。。
页: [1]
查看完整版本: 了解收音头RDS的朋友进来看看(附有源程序)