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

📄 tuner.c

📁 用TEA7567做的调频收音机,本人经测试通过的
💻 C
字号:
//#include <intrins.h>
#include "global.h"
#include "tuner.h"

void Delay10us(UINT16 twDelay)
{
 UINT16 i;
 for( i=0;i<twDelay;i++ )
 {
 //	_nop_();
 //	_nop_();
 WatchDog;
 }
}	



/****************************************************************************/
/*    Command Delay                                                         */
/****************************************************************************/
void CMD_Delay(BYTE i)
{
    for (; i!=0; i--) ;
}  

void CMD_CheckHighSCL()
{
    I2cSCL = 1;
}

void CMD_SendStart()
{
    I2cSCL = 1;
    CMD_Delay(CMD_DELAY);
    I2cSDA = 0;
    CMD_Delay(CMD_DELAY);
    I2cSCL = 0;
    CMD_Delay(CMD_DELAY);
}

void CMD_SendStop()
{
    I2cSDA = 0;
    CMD_CheckHighSCL();
    CMD_Delay(CMD_DELAY);
    I2cSDA = 1;
    CMD_Delay(CMD_DELAY);
}

BYTE  CMD_SendByte(BYTE bByte)
{
    BYTE i;
    BIT  Acknowledge=1;
    for(i=0;i<8;i++)
       {
         if(bByte&0x80)
            I2cSDA=1;
         else
            I2cSDA=0;
         bByte<<=1;
         CMD_Delay(CMD_DELAY);
         CMD_CheckHighSCL();
         I2cSCL  =0;
       }
    I2cSDA=1;
    I2cSCL=1;
    CMD_Delay(CMD_DELAY);
    if (I2cSDA) Acknowledge=0;
    I2cSCL=0;
    CMD_Delay(CMD_DELAY);
    return Acknowledge;
}

BYTE CMD_GetByte(BYTE Acknowledge)
{
    BYTE i,bByte=0, bMask=0x80;
    for(i=0;i<8;i++)
       {
          CMD_Delay(CMD_DELAY);
          I2cSCL=1;
		if(I2cSDA)bByte|=bMask;
                bMask >>= 1;
                I2cSCL  =0;
       }
    I2cSDA =(Acknowledge)?1:0; 
    CMD_CheckHighSCL();
    CMD_Delay(CMD_DELAY);
    I2cSCL  =0;                
    I2cSDA  =1;
    CMD_Delay(CMD_DELAY);
    return bByte;
}

//////////////////////////////////////////////

void Tuner_I2cSendData()
{
    BYTE i;
	EA=0;
    CMD_SendStart();
    if (CMD_SendByte(0x0c0))			//chip addr of write data to driver
    {
        for (i=0; i<5; i++)
        {
           if (!CMD_SendByte(WriteDataWord[i]))    //0 err
            {
                break;
            }
        }
    }
    CMD_SendStop();         //???
    EA=1;
	CMD_Delay(CMD_DELAY);
    CMD_Delay(CMD_DELAY);	
    
}

void Tuner_I2cReadData()
{

   BYTE i;
   EA=0;       
    CMD_SendStart();
    if (CMD_SendByte(0x0c1))                                        //chip addr of read data 
       {
        for (i=0;i<5;i++)
            ReadDataWord[i] =(i==4)? CMD_GetByte(1):CMD_GetByte(0); //the last byte with ACK.
        CMD_SendStop();
       }
    else CMD_SendStop();
	EA=1;
}

// BYTE tbRead1;                      //for test only
// BYTE tbRead2;
// BYTE tbRead3;
// BYTE tbRead4;

 BIT Stereo=False;
 BIT Ready=False;           

static void AssembleFrequencyWord(void)		
{
   UINT16 twPLL =0;			                //Dec 
   UINT32 tdwPresetVCO  =gdwPresetVCO;			//Khz
   BYTE tbTmp1;
   BYTE tbTmp2;
                  
  // calcu1ate frequency dataword bits from given station frequency BCD:  
    if(FlagHighInjection)
     twPLL =(unsigned int)((float)((tdwPresetVCO +225)*4)/(float)REFERENCE_FREQ);
    else
     twPLL =(unsigned int)((float)((tdwPresetVCO -225)*4)/(float)REFERENCE_FREQ);
  //convert BCD to Hex.
     tbTmp1 =(unsigned char)(twPLL%256);             //6789=Hex1A85 -->133=Hex85
     tbTmp2 =(unsigned char)(twPLL/256);             //             -->26=Hex1A  
    
     WriteDataWord[0]=tbTmp2;                    //high block                            
     WriteDataWord[1]=tbTmp1;  
       
} 

//BYTE Write1;

static void AssembleData(void)
{
  WriteDataWord[3] = 0x11;		        //32k /p1 found.	
  WriteDataWord[4] = 0x00;              //70us去加重电路

  

  if (FlagSearch )							 // search mode			
  {                              
    WriteDataWord[0] |= 0x40;               // Set to 1 for search start; other =0.

	// Set the bits of BYTE3 of search 
    if(FlagSearchtUp) WriteDataWord[2] |= 0x80;						
	else  WriteDataWord[2] &= 0x7f;									//0111 1111

  	if ((FlagLevel & 0x02) == 0x02)	WriteDataWord[2] |=0x40 ;	
   	else WriteDataWord[2] &=0x0bf;									//1011 1111	
	
   	if ((FlagLevel & 0x01) == 0x01)	WriteDataWord[2] |=0x20;	
   	else WriteDataWord[2] &=0x0df;									//1101 1111	 
//      Write1= WriteDataWord[0]   ;

   
  }
  /////PreSet mode
  else
  {     
      AssembleFrequencyWord();        	  
   	  WriteDataWord[0] &= 0x0bf;            // Set to 0 for Preset mode. 1011,1111
  }
    if(FlagMute) WriteDataWord[0] |= 0x80;	
  else  WriteDataWord[0] &= 0x7f	;			            //0111 1111
 //set the public data bit of BYTE3 
    if(FlagHighInjection)   WriteDataWord[2] |= 0x10 ;                
   	else  WriteDataWord[2] &= 0x0ef;						//1110 1111

 	if(FlagMono) WriteDataWord[2] |= 0x08	;
	else  WriteDataWord[2] &= 0x0f7	;		            	//1111 0111

 //set the public data bit of BYTE4 
	if(FlagSWPORT2) WriteDataWord[3] |= 0x80;	
	else  WriteDataWord[3] &= 0x7f	;			            //0111 1111

    if(FlagSoftMute) WriteDataWord[3] |= 0x08;	
	else  WriteDataWord[3] &= 0xf7	;			            //1111 0111

    if(FlagSWPORT1) WriteDataWord[3] |= 0x01;	
	else  WriteDataWord[3] &= 0xfe	;			            //1111 1110


  

}
/*
///****************test
 void DisAssembleFrequencyWord(void)		
{
   UINT16 twPLL =0;			                      //Dec 
   UINT32 tdwtestVCO ;			  //Khz

   BYTE tbTmp1=ReadDataWord[1];
   BYTE tbTmp2=ReadDataWord[0];
   tbTmp2&=0x3f;


   twPLL=65535;
          
   // calculate searched station frequency from dataword bits 
    if(FlagHighInjection)
     tdwtestVCO =(unsigned long)((float)twPLL*(float)REFERENCE_FREQ*(float)0.25-225);
    else
     tdwtestVCO =(unsigned long)((float)twPLL*(float)REFERENCE_FREQ*(float)0.25+225);
               
} 
///****************test
*/

void Tuner_Preset (BIT Mute, BIT SetMono,BIT Pin15,unsigned long VCO)    
{/*
  //***********test
  unsigned char bLevel;
	unsigned char bIFCounter;
	unsigned char brf;
	unsigned char bstero;
	//************test
*/	
  FlagSearch = False;               // Set global parameters
  FlagMono = SetMono;
  FlagSWPORT2 = Pin15;
  gdwPresetVCO = VCO; 
  FlagMute=Mute;                   //0301 mao 
 // RF_Have=1;
     
  AssembleData();
  Tuner_I2cSendData();
//  Delay10us(25000);                 //200ms
  Delay_ms(100);
 /* 
  //**********test*********
  Delay_ms(100);
  Tuner_I2cReadData(); 
  brf=((ReadDataWord[0]>> 7) & 0x01);            //RF位
  bstero=((ReadDataWord[2]>>7) & 0x01);          //立体声标志
  bIFCounter = ReadDataWord[2] & 0x7F;           //中频计数
  bLevel = (ReadDataWord[3] & 0xF0) >> 4;	       //ADC电平  
  DisAssembleFrequencyWord();  
  */                   
} 

//自动向上收下一台	收到台为返回1  收到头返回0  
bit Autosearch_Up()
{
	unsigned char bLevel;
	unsigned char bIFCounter;
	unsigned char brf;
	unsigned char bstero;
	unsigned char bandlimint;
    while(Flash_Times>0)
		{WatchDog;}
 	  do  
	   {
		if(gdwPresetVCO<HighestFM)
		 { 
		 WatchDog;
		 gdwPresetVCO+=100;              
		 bandlimint=0;                    //频率边界标志 向上频率大与108 为1 
 		 AssembleFrequencyWord();
		 Frequency_Change(gdwPresetVCO);
		 WatchDog;
 		 WriteDataWord[0]= ((WriteDataWord[0]|0x80)&0xBF);    //打开静音/定点模式	
		 Tuner_I2cSendData();
		 if(SearchDelayMs(1000))
		 {
		 	while((Up_Key!=1)||(Down_Key!=1))//如果还有按下时,表示有人为的停下要求了
			{
				WatchDog;			  					
			}
		 	break;
		 }
		 WatchDog;
		 Tuner_I2cReadData();
		 brf=((ReadDataWord[0]>> 7) & 0x01);            //RF位
		 bstero=((ReadDataWord[2]>>7) & 0x01);          //立体声标志
		 bIFCounter = ReadDataWord[2] & 0x7F;           //中频计数
	  	 bLevel = (ReadDataWord[3] & 0xF0) >> 4;	       //ADC电平
		 }
		 else
		 {
		  bandlimint=1;
		  break;
		 }
        }
	 while(!((brf==1)&&(bLevel>=8)&&(bIFCounter>=0x32)&&(bIFCounter<=0x3E)));		//收台判断条件
        if (bandlimint==1)
		{
		  Auto_Search_Flag=1;//使能闪烁功能
		  Flash_Times=4;//闪烁次数
          return 0;		                               //收到频率顶端,返回0
		}
        else
		{
  		  WriteDataWord[0]=WriteDataWord[0]&0x3F;      //关闭静音                                
		  Tuner_I2cSendData();  //写收到的台输出
		  Auto_Search_Flag=1;
		  Flash_Times=4;
		  Flag_500ms=0;
          return 1;
		}
}


//自动向下收下一台	收到台为返回1  收到头返回0  
bit Autosearch_Down()
{
	unsigned char bLevel;
	unsigned char bIFCounter;
	unsigned char brf;
	unsigned char bstero;
	unsigned char bandlimint;
	while(Flash_Times>0)
		{WatchDog;}
 	  do  
	   {
		if(gdwPresetVCO>LowestFM)
		 {
		 WatchDog;
		 gdwPresetVCO-=100;         
		 bandlimint=0;                    //频率边界标志 向下频率小与875为1  
		 AssembleFrequencyWord();
		 Frequency_Change(gdwPresetVCO);
		 WatchDog;
 		 WriteDataWord[0 ]= ((WriteDataWord[0]|0x80)&0xBF);    //打开静音/定点模式	
		 Tuner_I2cSendData();
		 if(SearchDelayMs(1000))
		 {	
		 	while((Up_Key!=1)||(Down_Key!=1))//如果还有按下时,表示有人为的停下要求了
			{
				WatchDog;			  					
			}
		 	break;
		 }
		 WatchDog;
		 Tuner_I2cReadData();
		 brf=((ReadDataWord[0]>> 7) & 0x01);            //RF位
		 bstero=((ReadDataWord[2]>>7) & 0x01);          //立体声标志
		 bIFCounter = ReadDataWord[2] & 0x7F;           //中频计数
	  	 bLevel = (ReadDataWord[3] & 0xF0) >> 4;	       //ADC电平
		 
		 }
		 else
		 {
		  bandlimint=1;
		  break;
		 }
        }
	 while(!((brf==1)&&(bLevel>=8)&&(bIFCounter>=0x34)&&(bIFCounter<=0x3E)));
        if (bandlimint==1)
		 {
		  Auto_Search_Flag=1;//使能闪烁功能
		  Flash_Times=4;//闪烁次数
          return 0;		                                    //收到频率顶端,返回0
		  }
        else
		  {
  		  WriteDataWord[0]=WriteDataWord[0]&0x3F;      //关闭静音
		  Tuner_I2cSendData();
		  Auto_Search_Flag=1;//使能闪烁功能
		  Flash_Times=4;//闪烁次数
		  Flag_500ms=0;
          return 1;
		  }
}


void Tuner_Init(void)
{
  BYTE i;
  for(i=0;i<5;i++)							//Clear 5767 data buffer =0
  {
   ReadDataWord[i] = False;
   WriteDataWord[i] =False;
  }
 
  WriteDataWord[0] = 0x2a|0x80;		        //init FM89.8MHz ok.	        //init FM89.8MHz ok.

  WriteDataWord[1] = 0x0b6;
  WriteDataWord[2] = 0x41;	//ADC输出为7,高充电流为0;		
  WriteDataWord[3] = 0x13;	//soft Mute关,立体声去噪打开
  WriteDataWord[4] = 0x00;//50us去加重电路
  Tuner_I2cSendData();
  Delay10us(100); 
 
//  WriteDataWord[0] = 0x2a;		        // init FM89.8MHz ok.
//  WriteDataWord[1] = 0x0b6;
//  WriteDataWord[2] = 0x41;	             //p1 high		
//  WriteDataWord[3] = 0x11;			
//  WriteDataWord[4] = 0x40;
///  Tuner_I2cSendData();

//  Tuner_Preset( False, True,High,89800 )  ;
 // gdwPresetVCO=89800;
//  Frequency_Change(gdwPresetVCO);
  

}
/*
void Check_Ch(void)
{
	
	if(Check_ADC_Count>50)//计时大于3秒了
	{
		Check_ADC_Count=0;//清强度检测计时器
		Tuner_I2cReadData();
		ADC_Val=(ReadDataWord[3] & 0xF0) >> 4;	       //ADC电平
 	    if(ADC_Val<District)//检测不到台的下限值
		{
			WriteDataWord[0]= ((WriteDataWord[0]|0x80)&0xBF);    //打开静音/定点模式
			Tuner_I2cSendData();
	
		}//Tuner_Preset (True, True,False,gdwPresetVCO);//静音
 	    else
		{
			WriteDataWord[0]= (WriteDataWord[0]&0x3F);    //打开静音/定点模式
			Tuner_I2cSendData();
		}//Tuner_Preset (False, True,Low,gdwPresetVCO);//不静音

	}
}
*/

⌨️ 快捷键说明

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