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

📄 si470x.c

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

//-----------------------------------------------------------------------------
// Defines
//-----------------------------------------------------------------------------

//-----------------------------------------------------------------------------
// Global variables
//-----------------------------------------------------------------------------
sbit RSTB     = P1^3;
sbit SENB     = P1^2;
sbit SCLK     = P1^1;
sbit SDIO     = P0^7;


//-----------------------------------------------------------------------------
// Function prototypes
//-----------------------------------------------------------------------------
static u16 chanToFreq (u16 channel);
static u16 freqToChan (u16 frequency);

//-----------------------------------------------------------------------------
// Take the Si470x out of powerdown mode, initializes a set
// of shadow registers, and sets some default register values.
//-----------------------------------------------------------------------------
void si470x_initialize (void)
{
	u8 i;
	
	// zero shadow registers to start
	for (i=0; i<16; i++)
		si470x_shadow[i] = 0;
	
	si470x_shadow[2] = 0x0001;	// set enable bit
	si470x_reg_write(2, 2);
  
	// set default parameters
   si470x_shadow[ 4] = 0xd004;   // Enable interrupt generation, enable rds, set de-emphasis
	                           	// set gpio muxes.  gpio2 generates an interrupt
 	si470x_shadow[ 5] &= 0x00ff;	// set seek threshold
 	si470x_shadow[ 5] |= 0x1400;
	si470x_reg_write(4, 5);
   wait_ms(85);  // wait for si470x to powerup

   si470x_reg_read(10, 9);  // initialize shadow registers

}

//-----------------------------------------------------------------------------
//
//-----------------------------------------------------------------------------
void si470x_powerup (void)
{
    si470x_reg_write(2, 2);  // restore register 2 to power up again
    wait_ms(85);  // wait for si470x to powerup
    si470x_tune(0);     // retune to last station 
    
}   

//-----------------------------------------------------------------------------
// Set the volume and mute/unmute status
//
// Inputs:
//		volume:	a 4-bit volume value
//      dmute:  0 = output muted
//              1 = output enabled (mute disabled)
//
//-----------------------------------------------------------------------------
void si470x_set_volume (u8 volume, u8 dmute)
{
	if (dmute)
		si470x_shadow[2] |= 0x4000;
	else
		si470x_shadow[2] &= ~0x4000;

	si470x_shadow[5] &= ~0x000F;
	si470x_shadow[5] |= volume & 0x000F;
	
	si470x_reg_write(2, 5);
}

//-----------------------------------------------------------------------------
// Forces mono mode or enables stereo mode
//
// Inputs:
//		mono: 0 = stereo mode enabled
//		      1 = mono mode forced
//-----------------------------------------------------------------------------
void si470x_set_mono(u8 mono)
{
	if (mono)
		si470x_shadow[2] |= 0x2000;
	else
		si470x_shadow[2] &= ~0x2000;
	
	si470x_reg_write(2, 2);
}	

//-----------------------------------------------------------------------------
// Tunes to a station number using the current band and spacing settings.
//
// Inputs:
//  frequency:  frequency in 10kHz steps
//
//-----------------------------------------------------------------------------
void si470x_tune (u16 frequency)
{
	// write channel number to register 0x03 and set tune bit
    // if frequency is zero, routine will retune to last station (used for powerup)
    if (frequency)
        si470x_shadow[ 3] = freqToChan(frequency) | 0x8000;
    else
        si470x_shadow[ 3] |= freqToChan(frequency) | 0x8000;
        
	si470x_reg_write(3, 3);

	// wait for stc bit to be set
	do {
		si470x_reg_read(10, 10);
	} while ((si470x_shadow[10] & 0x4000) == 0); 		  

	// write address 0x03 to clear tune bit
	si470x_shadow[ 3] &= ~0x8000;
	si470x_reg_write(3, 3);

	// wait for stc bit to be cleared
	do {
		si470x_reg_read(10, 10);
	} while ((si470x_shadow[10] & 0x4000) != 0); 		  
	
	// read adresses 0x0a - 0x0b to read status (optional)
    // Address 0x0a just read, so just read 0x0b here
    si470x_reg_read(11, 11);  // update shadow registers
}	

//-----------------------------------------------------------------------------
// Inputs:
//      seekup:  0 = seek down
//               1 = seek up
// 
// Outputs:
//		zero = seek found a station
// 		nonzero = seek did not find a station
//
//-----------------------------------------------------------------------------
u8 si470x_seek (u8 seekup)
{
	// set or clear seekup bit in address 0x02 
	if (seekup)
		si470x_shadow[ 2] |= 0x0200;
	else 
		si470x_shadow[ 2] &= ~0x0200;
	
	// set seek bit in address 0x02 
	si470x_shadow[ 2] |= 0x0100;
	
	si470x_reg_write(2, 2);
	
	// wait for stc bit to be set
	do {
		si470x_reg_read(10, 10);
	} while ((si470x_shadow[10] & 0x4000) == 0); 		  
	
	// clear seek bit in address 0x02
	si470x_shadow[ 2] &= ~0x0100;
	si470x_reg_write(2, 2);

	// wait for stc bit to be cleared
	do {
		si470x_reg_read(10, 10);
	} while ((si470x_shadow[10] & 0x4000) != 0); 		  
	
	// read adresses 0x0a - 0x0b to read status (optional)
    // Address 0x0a just read, so just read 0x0b here
    si470x_reg_read(11, 11);  // update shadow registers

	return (si470x_shadow[10]&0x2000);  //return seek fail indicator
}	  


//-----------------------------------------------------------------------------
// Outputs:
//	returns current channel number in a format that can be 
//  used as parameter in to tune or chan2freq
//
//-----------------------------------------------------------------------------
u16 si470x_get_frequency(void)
{
    return (chanToFreq(si470x_shadow[11] & 0x03ff));
}	


//-----------------------------------------------------------------------------
// Outputs:
//	returns current rssi value
//		
//-----------------------------------------------------------------------------
u8 si470x_get_rssi(void)
{
	si470x_reg_read(10, 10);  // update shadow registers
	return ((u8)(si470x_shadow[10]&0xff));		
}	


//-----------------------------------------------------------------------------
// Returns rssi and stereo indicator in one word
//
// Outputs:
//	returns current rssi value and stereo indicators
// 		bit    8 = Stereo indicator
//      bits 7:0 = rssi
//		
//-----------------------------------------------------------------------------
u16 si470x_get_rssi_and_stereo(void)
{
	si470x_reg_read(10, 10);  // update shadow registers
	return ((u8)(si470x_shadow[10]&0x1ff));		
}	


//-----------------------------------------------------------------------------
// Converts from a frequency value to a channel number
//
// Inputs:
// 	frequency in 10kHz steps
//
// Output:
//	channel number using current channel spacing
//
//-----------------------------------------------------------------------------
static u16 freqToChan (u16 frequency) 
{
	u16 channelSpacing;
	u16 bottomOfBand;
	u16 channel;
	
	if ((si470x_shadow[5] & 0x0080) == 0x0000) 
		bottomOfBand = 8750;
	else 
		bottomOfBand = 7600;

	if (frequency < bottomOfBand)
		frequency = bottomOfBand;

	if ((si470x_shadow[5] & 0x0030) == 0x0000) 
		channelSpacing = 20;
	else if ((si470x_shadow[5] & 0x0030) == 0x0010) 
		channelSpacing = 10;
	else 
		channelSpacing = 5;

	channel = (frequency - bottomOfBand) / channelSpacing;
	
	return (channel);
}


//-----------------------------------------------------------------------------
// Converts from a channel number to a frequency value
//
// Inputs:
//  Channel number using current channel spacing
//
// Output:
//  Frequency in 10kHz steps
//
//-----------------------------------------------------------------------------
static u16 chanToFreq (u16 channel) {

	u16 channelSpacing;
	u16 bottomOfBand;
	u16 frequency;

	// calculate frequency

	if ((si470x_shadow[5] & 0x0080) == 0x0000) 
		bottomOfBand = 8750;
	else 
		bottomOfBand = 7600;

	if ((si470x_shadow[5] & 0x0030) == 0x0000) 
		channelSpacing = 20;
	else if ((si470x_shadow[5] & 0x0030) == 0x0010) 
		channelSpacing = 10;
	else 
		channelSpacing = 5;

	frequency = bottomOfBand + channelSpacing * channel;

	return (frequency);

}


⌨️ 快捷键说明

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