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

📄 rds.c

📁 美国模拟混合器件领导厂商Silabs 芯科实验室 收音机系列 源码
💻 C
📖 第 1 页 / 共 2 页
字号:
//-----------------------------------------------------------------------------
// Includes
//-----------------------------------------------------------------------------
#include <c8051f320.h>        
#include <stddef.h>       
#include "typedefs.h"
#include "example.h"

sbit LED      = P1^5;

//-----------------------------------------------------------------------------
// local defines
//-----------------------------------------------------------------------------
#define RDS_TYPE_0A     ( 0 * 2 + 0)
#define RDS_TYPE_0B     ( 0 * 2 + 1)
#define RDS_TYPE_1A     ( 1 * 2 + 0)
#define RDS_TYPE_1B     ( 1 * 2 + 1)
#define RDS_TYPE_2A     ( 2 * 2 + 0)
#define RDS_TYPE_2B     ( 2 * 2 + 1)
#define RDS_TYPE_3A     ( 3 * 2 + 0)
#define RDS_TYPE_3B     ( 3 * 2 + 1)
#define RDS_TYPE_4A     ( 4 * 2 + 0)
#define RDS_TYPE_4B     ( 4 * 2 + 1)
#define RDS_TYPE_5A     ( 5 * 2 + 0)
#define RDS_TYPE_5B     ( 5 * 2 + 1)
#define RDS_TYPE_6A     ( 6 * 2 + 0)
#define RDS_TYPE_6B     ( 6 * 2 + 1)
#define RDS_TYPE_7A     ( 7 * 2 + 0)
#define RDS_TYPE_7B     ( 7 * 2 + 1)
#define RDS_TYPE_8A     ( 8 * 2 + 0)
#define RDS_TYPE_8B     ( 8 * 2 + 1)
#define RDS_TYPE_9A     ( 9 * 2 + 0)
#define RDS_TYPE_9B     ( 9 * 2 + 1)
#define RDS_TYPE_10A    (10 * 2 + 0)
#define RDS_TYPE_10B    (10 * 2 + 1)
#define RDS_TYPE_11A    (11 * 2 + 0)
#define RDS_TYPE_11B    (11 * 2 + 1)
#define RDS_TYPE_12A    (12 * 2 + 0)
#define RDS_TYPE_12B    (12 * 2 + 1)
#define RDS_TYPE_13A    (13 * 2 + 0)
#define RDS_TYPE_13B    (13 * 2 + 1)
#define RDS_TYPE_14A    (14 * 2 + 0)
#define RDS_TYPE_14B    (14 * 2 + 1)
#define RDS_TYPE_15A    (15 * 2 + 0)
#define RDS_TYPE_15B    (15 * 2 + 1)

#define BLER_SCALE_MAX 200  // Block Errors are reported in .5% increments

//-----------------------------------------------------------------------------
// Globals
//-----------------------------------------------------------------------------

// Determines if the basic or advanced PS/RT RDS display functions are used
// The basic functions are closely tied to the recommendations in the RBDS 
// specification and are faster to update but more error prone. The advanced
// functions attempt to detect errors and only display complete messages
static bit rdsBasic = 0;

// RDS Program Identifier
u16 xdata piDisplay;              // Displayed Program Identifier

// RDS Program Type
u8  xdata ptyDisplay;             // Displayed Program Type

// RDS Radio Text
       u8  xdata rtDisplay[64];   // Displayed Radio Text
static u8  xdata rtTmp0[64];      // Temporary Radio Text (high probability)
static u8  xdata rtTmp1[64];      // Temporary radio text (low probability)
static u8  xdata rtCnt[64];       // Hit count of high probabiltiy radio text
static bit       rtFlag = 0;      // Radio Text A/B flag
static bit       rtFlagValid = 0; // Radio Text A/B flag is valid

// RDS Program Service
       u8  xdata psDisplay[8];    // Displayed Program Service text
static u8  xdata psTmp0[8];       // Temporary PS text (high probability)
static u8  xdata psTmp1[8];       // Temporary PS text (low probability)
static u8  xdata psCnt[8];        // Hit count of high probability PS text

// RDS flags and counters
       u8  xdata RdsDataAvailable = 0;  // Count of unprocessed RDS Groups
static u8  xdata RdsIndicator     = 0;  // If true, RDS was recently detected
static u16 xdata RdsDataLost      = 0;  // Number of Groups lost
static u16 xdata RdsBlocksValid   = 0;  // Number of valid blocks received
static u16 xdata RdsBlocksTotal   = 0;  // Total number of blocks expected

// Debug information storing number of each kind of group received
u16 xdata debug_group_counters[32];

//-----------------------------------------------------------------------------
// Function prototypes
//-----------------------------------------------------------------------------


//-----------------------------------------------------------------------------
//
//
//
//-----------------------------------------------------------------------------
void
initRds(void)
{
    u8 i;

    // Reset RDS variables
	RdsDataAvailable = 0;
	RdsDataLost      = 0;
	RdsIndicator     = 0;
	RdsBlocksValid   = 0;
	RdsBlocksTotal   = 0;

    // Clear Radio Text
	rtFlagValid     = 0;
    for (i=0; i<sizeof(rtDisplay); i++)
	{
        rtDisplay[i] = 0;
		rtTmp0[i]    = 0;
		rtTmp1[i]    = 0;
		rtCnt[i]     = 0;
    }

    // Clear Program Service
	for (i=0;i<sizeof(psDisplay);i++)
	{
		psDisplay[i] = 0;
		psTmp0[i]    = 0;
		psTmp1[i]    = 0;
		psCnt[i]     = 0;
	}

    // Reset Debug Group counters
    for (i=0; i<32; i++)
    {
        debug_group_counters[i] = 0;    
    }
}


//-----------------------------------------------------------------------------
//
//
//
//-----------------------------------------------------------------------------
#define RDS_PI_VALIDATE_LIMIT  4

static void
update_pi(u16 current_pi)
{
    static u8 rds_pi_validate_count = 0;
    static u16 rds_pi_nonvalidated;
    
    // if the pi value is the same for a certain number of times, update
    // a validated pi variable
    if (rds_pi_nonvalidated != current_pi)
	{
        rds_pi_nonvalidated =  current_pi;
        rds_pi_validate_count = 1;
    }
	else
	{
        rds_pi_validate_count++;
    }

    if (rds_pi_validate_count > RDS_PI_VALIDATE_LIMIT)
	{
        piDisplay = rds_pi_nonvalidated;
	}
}


//-----------------------------------------------------------------------------
//
//
//
//-----------------------------------------------------------------------------
#define RDS_PTY_VALIDATE_LIMIT 4

static void
update_pty(u8 current_pty)
{
    static u8 xdata rds_pty_validate_count = 0;
    static u8 xdata rds_pty_nonvalidated;
    
    // if the pty value is the same for a certain number of times, update
    // a validated pty variable
    if (rds_pty_nonvalidated != current_pty)
	{
        rds_pty_nonvalidated =  current_pty;
        rds_pty_validate_count = 1;
    }
	else
	{
        rds_pty_validate_count++;
    }

    if (rds_pty_validate_count > RDS_PTY_VALIDATE_LIMIT)
	{
        ptyDisplay = rds_pty_nonvalidated;
	}
}


//-----------------------------------------------------------------------------
// The basic implementation of the Program Service update displays data
// immediately but does no additional error detection.
//-----------------------------------------------------------------------------
static void
update_ps_basic(u8 current_ps_addr, u8 current_ps_byte)
{
	psDisplay[current_ps_addr] = current_ps_byte;
}

//-----------------------------------------------------------------------------
// This implelentation of the Program Service update attempts to display
// only complete messages for stations who rotate text through the PS field
// in violation of the RBDS standard as well as providing enhanced error
// detection.
//-----------------------------------------------------------------------------
#define PS_VALIDATE_LIMIT 2
static void
update_ps(u8 addr, u8 byte)
{
    u8 i;
	bit textChange = 0; // indicates if the PS text is in transition
	bit psComplete = 1; // indicates that the PS text is ready to be displayed

	if(psTmp0[addr] == byte)
	{
        // The new byte matches the high probability byte
		if(psCnt[addr] < PS_VALIDATE_LIMIT)
		{
			psCnt[addr]++;
		}
		else
		{
            // we have recieved this byte enough to max out our counter
            // and push it into the low probability array as well
			psCnt[addr] = PS_VALIDATE_LIMIT;
			psTmp1[addr] = byte;
		}
	}
	else if(psTmp1[addr] == byte)
	{
        // The new byte is a match with the low probability byte. Swap
        // them, reset the counter and flag the text as in transition.
        // Note that the counter for this character goes higher than
        // the validation limit because it will get knocked down later
		psCnt[addr] = PS_VALIDATE_LIMIT + 1;
		psTmp1[addr] = psTmp0[addr];
		psTmp0[addr] = byte;
		textChange = 1;
	}
	else if(!psCnt[addr+i])
	{
        // The new byte is replacing an empty byte in the high
        // proability array
		psTmp0[addr] = byte;
		psCnt[addr] = 1;
	}
	else
	{
        // The new byte doesn't match anything, put it in the
        // low probablity array.
		psTmp1[addr] = byte;
	}

	if(textChange)
	{
        // When the text is changing, decrement the count for all 
        // characters to prevent displaying part of a message
        // that is in transition.
		for(i=0;i<sizeof(psCnt);i++)
		{
			if(psCnt[i] > 1)
			{
				psCnt[i]--;
			}
		}
	}

    // The PS text is incomplete if any character in the high
    // probability array has been seen fewer times than the
    // validation limit.
	for (i=0;i<sizeof(psTmp0);i++)
	{
		if(psCnt[i] < PS_VALIDATE_LIMIT)
		{
			psComplete = 0;
			break;
		}
	}

    // If the PS text in the high probability array is complete
    // copy it to the display array
	if (psComplete)
	{
		for (i=0;i<sizeof(psDisplay); i++)
		{
			psDisplay[i] = psTmp0[i];
		}
	}
}

//-----------------------------------------------------------------------------
// The basic implementation of the Radio Text update displays data
// immediately but does no additional error detection.
//-----------------------------------------------------------------------------
static void
update_rt_basic(bit abFlag, u8 count, u8 addr, u8* chars)
{
	bit complete = 1;
	u8 i,j;

    // If the A/B flag changes, wipe out the text
	if ((abFlag != rtFlag) && rtFlagValid)
	{
		for (i=0;i<sizeof(rtDisplay);i++)
		{
			rtTmp0[i] = 0;
		}
	}
	rtFlag = abFlag;    // Save the A/B flag
	rtFlagValid = 1;    // Now the A/B flag is valid

	for (i=0; i<count; i++)
	{
        // Store the data in our temporary array
		rtTmp0[addr+i] = chars[i];
		if(chars[i] == 0x0d)
		{
            // The end of message character has been received.
            // Wipe out the rest of the text.
			for (j=addr+i+1;j<sizeof(rtDisplay);j++)
			{
				rtTmp0[j] = 0;
			}
			break;
		}
	}

    // A message is complete if all the characters preceeding 0x0d (or last
	// character in the array) are non-null
	for (i=0;i<sizeof(rtTmp0);i++)
	{
		if(!rtTmp0[i])
		{
			complete = 0;
			break;

⌨️ 快捷键说明

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