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

📄 si47xx_rx_am.c

📁 si47xx FM 收音机的程序,通过单片机来控制搜台灯功能
💻 C
字号:
/**************************************

Si47XX AM RX part

***************************************/

#include "Si47xx_common.h"

/**************************************

Si47XX_Set_Property_AM_DEEMPHASIS()

***************************************/

T_ERROR_OP Si47XX_Set_Property_AM_DEEMPHASIS(void)
{
	unsigned short loop_counter = 0;
	unsigned char Si47XX_reg_data[32];	
	unsigned char error_ind = 0;
	unsigned char Si47XX_set_property[] = {0x12,0x00,0x31,0x00,0x00,0x01};	//AM deemphasis is 50us

	//send CMD
 	error_ind = OperationSi47XX_2w(WRITE, &(Si47XX_set_property[0]), 6);
	if(error_ind)
		return I2C_ERROR;

	//wait CTS = 1
	do
	{	
		error_ind = OperationSi47XX_2w(READ, &(Si47XX_reg_data[0]), 1);
		if(error_ind)
			return I2C_ERROR;	
		loop_counter++;
	}
	while(((Si47XX_reg_data[0]) != 0x80) && (loop_counter < 0xff));  //loop_counter limit should guarantee at least 300us
	
	if(loop_counter >= 0xff)
		return LOOP_EXP_ERROR;	

	return OK;

}

/**************************************

Si47XX_Set_Property_AM_Seek_Space()

***************************************/

T_ERROR_OP Si47XX_Set_Property_AM_Seek_Space(void)
{
	unsigned short loop_counter = 0;
	unsigned char Si47XX_reg_data[32];	
	unsigned char error_ind = 0;
	unsigned char Si47XX_set_property[] = {0x12,0x00,0x34,0x02,0x00,0x09};	//seek space = 0x09 = 9 = 9KHz

	//send CMD
 	error_ind = OperationSi47XX_2w(WRITE, &(Si47XX_set_property[0]), 6);
	if(error_ind)
		return I2C_ERROR;

	//wait CTS = 1
	do
	{	
		error_ind = OperationSi47XX_2w(READ, &(Si47XX_reg_data[0]), 1);
		if(error_ind)
			return I2C_ERROR;	
		loop_counter++;
	}
	while(((Si47XX_reg_data[0]) != 0x80) && (loop_counter < 0xff));  //loop_counter limit should guarantee at least 300us
	
	if(loop_counter >= 0xff)
		return LOOP_EXP_ERROR;	

	return OK;

}

/**************************************

Si47XX_Set_Property_AM_SNR_Threshold()

Default is 5dB.

***************************************/

T_ERROR_OP Si47XX_Set_Property_AM_SNR_Threshold(void)
{
	unsigned short loop_counter = 0;
	unsigned char Si47XX_reg_data[32];	
	unsigned char error_ind = 0;
	unsigned char Si47XX_set_property[] = {0x12,0x00,0x34,0x03,0x00,0x05};	//SNR threshold = 0x0005 = 5dB

	//send CMD
 	error_ind = OperationSi47XX_2w(WRITE, &(Si47XX_set_property[0]), 6);
	if(error_ind)
		return I2C_ERROR;

	//wait CTS = 1
	do
	{	
		error_ind = OperationSi47XX_2w(READ, &(Si47XX_reg_data[0]), 1);
		if(error_ind)
			return I2C_ERROR;	
		loop_counter++;
	}
	while(((Si47XX_reg_data[0]) != 0x80) && (loop_counter < 0xff));  //loop_counter limit should guarantee at least 300us
	
	if(loop_counter >= 0xff)
		return LOOP_EXP_ERROR;	

	return OK;

}

/**************************************

Si47XX_Set_Property_AM_RSSI_Threshold()

Default is 25dBuV.

***************************************/

T_ERROR_OP Si47XX_Set_Property_AM_RSSI_Threshold(void)
{
	unsigned short loop_counter = 0;
	unsigned char Si47XX_reg_data[32];	
	unsigned char error_ind = 0;
	unsigned char Si47XX_set_property[] = {0x12,0x00,0x34,0x04,0x00,0x19};	//RSSI threshold = 0x0019 = 25dBuV

	//send CMD
 	error_ind = OperationSi47XX_2w(WRITE, &(Si47XX_set_property[0]), 6);
	if(error_ind)
		return I2C_ERROR;

	//wait CTS = 1
	do
	{	
		error_ind = OperationSi47XX_2w(READ, &(Si47XX_reg_data[0]), 1);
		if(error_ind)
			return I2C_ERROR;	
		loop_counter++;
	}
	while(((Si47XX_reg_data[0]) != 0x80) && (loop_counter < 0xff));  //loop_counter limit should guarantee at least 300us
	
	if(loop_counter >= 0xff)
		return LOOP_EXP_ERROR;	

	return OK;

}

/**************************************

static Si47XX_AM_Tune_Freq()

***************************************/

static T_ERROR_OP Si47XX_AM_Tune_Freq(unsigned short channel_freq)
{
	unsigned short loop_counter = 0;
	unsigned char Si47XX_reg_data[32];	
	unsigned char error_ind = 0;
	unsigned char Si47XX_tune_freq[] = {0x40,0x00,0x03,0xE8,0x00,0x00};	//0x03E8=1000KHz
	
	Si47XX_tune_freq[2] = (channel_freq&0xff00) >> 8;
	Si47XX_tune_freq[3] = (channel_freq&0x00ff);	

	//send CMD
 	error_ind = OperationSi47XX_2w(WRITE, &(Si47XX_tune_freq[0]), 6);
	if(error_ind)
		return I2C_ERROR;

	//wait CTS = 1
	do
	{	
		error_ind = OperationSi47XX_2w(READ, &(Si47XX_reg_data[0]), 1);
		if(error_ind)
			return I2C_ERROR;	
		loop_counter++;
	}
	while(((Si47XX_reg_data[0]) != 0x80) && (loop_counter < 0xff));  //loop_counter limit should guarantee at least 300us
	
	if(loop_counter >= 0xff)
		return LOOP_EXP_ERROR;	

	return OK;

}

/**************************************

static Si47XX_AM_Seek_Start()

***************************************/

static T_ERROR_OP Si47XX_AM_Seek_Start(T_SEEK_MODE seek_mode)
{
	unsigned short loop_counter = 0;
	unsigned char Si47XX_reg_data[32];	
	unsigned char error_ind = 0;
	unsigned char Si47XX_seek_start[] = {0x41,0x0C};
			
	
	switch(seek_mode)
	{
		case SEEKDOWN_HALT:
		{
			Si47XX_seek_start[1] = 0x00;
			break;
		}
    case SEEKDOWN_WRAP:
    {
    	Si47XX_seek_start[1] = 0x04;
    	break;
    }
    case SEEKUP_HALT:
    {
    	Si47XX_seek_start[1] = 0x08;
    	break;
    }
    case SEEKUP_WRAP:
    {
    	Si47XX_seek_start[1] = 0x0C;
    	break;
    }
  }
	//send CMD
 	error_ind = OperationSi47XX_2w(WRITE, &(Si47XX_seek_start[0]), 2);
	if(error_ind)
		return I2C_ERROR;

	//wait CTS = 1
	do
	{	
		error_ind = OperationSi47XX_2w(READ, &(Si47XX_reg_data[0]), 1);
		if(error_ind)
			return I2C_ERROR;	
		loop_counter++;
	}
	while(((Si47XX_reg_data[0]) != 0x80) && (loop_counter < 0xff));  //loop_counter limit should guarantee at least 300us
	
	if(loop_counter >= 0xff)
		return LOOP_EXP_ERROR;	

	return OK;

}

/**************************************

static Si47XX_AM_Tune_Status()

***************************************/

static T_ERROR_OP Si47XX_AM_Tune_Status(unsigned short *pChannel_Freq, unsigned char *SeekFail, unsigned char *valid_channel)
{
	unsigned short loop_counter = 0;
	unsigned char Si47XX_reg_data[32];	
	unsigned char error_ind = 0;
	unsigned char Si47XX_fm_tune_status[] = {0x42,0x01};		

	//send CMD
 	error_ind = OperationSi47XX_2w(WRITE, &(Si47XX_fm_tune_status[0]), 2);
	if(error_ind)
		return I2C_ERROR;

	//wait CTS = 1
	do
	{	
		error_ind = OperationSi47XX_2w(READ, &(Si47XX_reg_data[0]), 1);
		if(error_ind)
			return I2C_ERROR;	
		loop_counter++;
	}
	while(((Si47XX_reg_data[0]) != 0x80) && (loop_counter < 0xff));  //loop_counter limit should guarantee at least 300us
	
	if(loop_counter >= 0xff)
		return LOOP_EXP_ERROR;	
		
	//read tune status: you should read out: {0x80,0x81,0x03,0xE8,0x2A,0x1A,0x0D,0x95} //Freq=0x03E8=1000KHz, RSSI=0x2A=42dBuV, SNR=0x1A=26dB
	error_ind = OperationSi47XX_2w(READ, &Si47XX_reg_data[0], 8);	
	if(error_ind)
		return I2C_ERROR;
		
	if(((Si47XX_reg_data[1]&0x80) != 0))
		*SeekFail = 1;
	else
		*SeekFail = 0;
		
	if(((Si47XX_reg_data[1]&0x01) != 0))
		*valid_channel = 1;
	else
		*valid_channel = 0;
		
	*pChannel_Freq = ((Si47XX_reg_data[2] << 8) | Si47XX_reg_data[3]);

	return OK;

}

/**************************************

Si47XX_Set_AM_Frequency()

***************************************/

T_ERROR_OP Si47XX_Set_AM_Frequency(unsigned short channel_freq)
{
	if(Si47XX_AM_Tune_Freq(channel_freq) != OK) return ERROR;
	if(Si47XX_Wait_STC() != OK) return ERROR;	
	return OK;
}

/**************************************

Si47XX_AM_Seek()

SeekFail:"no any station" or not when in WRAP mode

***************************************/

T_ERROR_OP Si47XX_AM_Seek(T_SEEK_MODE seek_mode, unsigned short *pChannel_Freq, unsigned char *SeekFail)
{
	unsigned char valid_channel;
	unsigned short loop_counter = 0;

	do
	{
		if(Si47XX_AM_Seek_Start(seek_mode) != OK) return ERROR;
		if(Si47XX_Wait_STC() != OK) return ERROR;
		//read seek result:
		if(Si47XX_AM_Tune_Status(pChannel_Freq, SeekFail, &valid_channel) != OK) return ERROR;	
		
		loop_counter++;
	}
	while((valid_channel == 0) && (loop_counter < 0xff) && (*SeekFail == 0));  

	if(loop_counter >= 0xff)
		return LOOP_EXP_ERROR;
		
	if((seek_mode == SEEKDOWN_WRAP) || (seek_mode == SEEKUP_WRAP))
		if((valid_channel == 1) && (*SeekFail == 1))
			*SeekFail = 0;

	return OK;
}

/**************************************

Si47XX_AM_Seek_All()

***************************************/

T_ERROR_OP Si47XX_AM_Seek_All(unsigned short *pChannel_All_Array, unsigned char Max_Length, unsigned char *pReturn_Length)
{
	unsigned char SeekFail;
	unsigned short Channel_Result, Last_Channel = 520;
		
	*pReturn_Length = 0;
	
	if(Si47XX_Set_AM_Frequency(520) != OK) return ERROR;
	
	while(*pReturn_Length < Max_Length)
	{
		if(Si47XX_AM_Seek(SEEKUP_WRAP, &Channel_Result, &SeekFail) != OK) return ERROR;
			
		if(SeekFail)
			return OK;
		
		if((Channel_Result) <= Last_Channel)	
		{
			if((Channel_Result) == 520)
			{
				*pChannel_All_Array++ = Channel_Result;
				(*pReturn_Length)++;
			}
			return OK;
		}
		else
		{
			*pChannel_All_Array++ = Last_Channel = Channel_Result;
			(*pReturn_Length)++;
		}
	}
	
	return OK;
}













⌨️ 快捷键说明

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