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

📄 si47xx_rds_rx.c

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

Si47XX RDS receive part

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

#include "Si47xx_common.h"

extern void RDS_data_process(unsigned char *group_data);  //group_data length is 8 bytes 

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

Si47XX_RDS_ISR(): RDS data receive interrupt ISR: Non-reentry routine

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

T_ERROR_OP Si47XX_RDS_ISR(void)
{
	unsigned short loop_counter = 0;
	unsigned char Si47XX_reg_data[32];	
	unsigned char group_count, error_ind = 0;
	unsigned char Si47XX_get_int_status[] = {0x14};	
	unsigned char Si47XX_rds_status[] = {0x24,0x00};	
	unsigned char Si47XX_rds_status_clear_RDS_int[] = {0x24,0x01};

	//send CMD
 	error_ind = OperationSi47XX_2w(WRITE, &(Si47XX_get_int_status[0]), 1);
	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) == 0) && (loop_counter < 0x3f));  //loop_counter limit should guarantee at least 300us
	
	  if(loop_counter >= 0x3f)
		  return LOOP_EXP_ERROR;
		  
		loop_counter = 0;
	  /* wait CTS end */

  //check whether it's RDS interrupt
	error_ind = OperationSi47XX_2w(READ, &(Si47XX_reg_data[0]), 1);
	if(error_ind)
		return I2C_ERROR;	
		
	if((Si47XX_reg_data[0]&0x04) != 0)
	{
	  //send CMD
 	  error_ind = OperationSi47XX_2w(WRITE, &(Si47XX_rds_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) == 0) && (loop_counter < 0x3f));  //loop_counter limit should guarantee at least 300us
	
	  if(loop_counter >= 0x3f)
		  return LOOP_EXP_ERROR;
		  
		loop_counter = 0;
	  /* wait CTS end */
		  
		error_ind = OperationSi47XX_2w(READ, &(Si47XX_reg_data[0]), 13);
	  if(error_ind)
		  return I2C_ERROR;	
		  
	  //whether it's RDSRECV:
	  if((Si47XX_reg_data[1]&0x01) != 0)
	  {
	  	group_count = Si47XX_reg_data[3];
	  	if(group_count != 0)
	  	{
	  		RDS_data_process(&Si47XX_reg_data[4]);
	  		group_count--;
	  	
	  	  //if group_count > 1	
	  	  while(group_count != 0)
	  	  {
	  	    error_ind = OperationSi47XX_2w(WRITE, &(Si47XX_rds_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) == 0) && (loop_counter < 0x3f));  //loop_counter limit should guarantee at least 300us
	
	        if(loop_counter >= 0x3f)
		        return LOOP_EXP_ERROR;
		  
		      loop_counter = 0;
	        /* wait CTS end */
		  
		      error_ind = OperationSi47XX_2w(READ, &(Si47XX_reg_data[0]), 13);
	        if(error_ind)
		        return I2C_ERROR;	
		  	  		
		  	  RDS_data_process(&Si47XX_reg_data[4]);  				
	  		  group_count--;
	      }//end while
	    }// end if((group_count != 0)
	  }//end if RDSRECV
	  
	  /*clear RDSINT*/
	  //send CMD
 	  error_ind = OperationSi47XX_2w(WRITE, &(Si47XX_rds_status_clear_RDS_int[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) == 0) && (loop_counter < 0x3f));  //loop_counter limit should guarantee at least 300us
	
	  if(loop_counter >= 0x3f)
		  return LOOP_EXP_ERROR;

	  /* wait CTS end */  
	  /*clear RDSINT end*/
	}//end if RDS int


	return OK;

}

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

Si47XX_Power_Up(): should confirm GPO2OEN bit is set to 1 in POWER_UP for RDS interrupt

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

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

Si47XX_Set_Property_RDS_int_source()

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

T_ERROR_OP Si47XX_Set_Property_RDS_int_source(void)
{
	unsigned short loop_counter = 0;
	unsigned char Si47XX_reg_data[32];	
	unsigned char error_ind = 0;
	unsigned char Si47XX_set_property[] = {0x12,0x00,0x15,0x00,0x00,0x01};	//RDS Received int

	//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_RDS_int_FIFO_count()

Minimum number of RDS groups stored in the RDS FIFO before RDSRECV is set.

For ISR: FIFO count normally should < max(maximum FIFO = 14(RevA), 25(RevB))
For Polling: FIFO count should set to 1 if still use Si47XX_RDS_ISR()
***************************************/

T_ERROR_OP Si47XX_Set_Property_RDS_int_FIFO_count(void)
{
	unsigned short loop_counter = 0;
	unsigned char Si47XX_reg_data[32];	
	unsigned char error_ind = 0;
	unsigned char Si47XX_set_property[] = {0x12,0x00,0x15,0x01,0x00,0x0a};	//maximum FIFO = 14(RevA), 25(RevB), normally should < max

	//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_RDS_config()

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

T_ERROR_OP Si47XX_Set_Property_RDS_config(void)
{
	unsigned short loop_counter = 0;
	unsigned char Si47XX_reg_data[32];	
	unsigned char error_ind = 0;
	unsigned char Si47XX_set_property[] = {0x12,0x00,0x15,0x02,0xaa,0x01};	//3-5 bit error

	//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_GPO_IEN()

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

T_ERROR_OP Si47XX_Set_Property_GPO_IEN(void)
{
	unsigned short loop_counter = 0;
	unsigned char Si47XX_reg_data[32];	
	unsigned char error_ind = 0;
	unsigned char Si47XX_set_property[] = {0x12,0x00,0x00,0x01,0x00,0x04};	//RDSINT int

	//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;

}

⌨️ 快捷键说明

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