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

📄 tea5767.c

📁 多功能MP3代码
💻 C
字号:
/*
TEA5767驱动程序:

unsigned char TEA5767_INTI(void);           //初始化TWI
unsigned char set5767(void);                //写TEA5767寄存器
void read5767(void);                        //读TEA5767寄存器
void set_frequency(unsigned long frequency) //设定频率  (输入设定频率)
void frequency_UP_DOWN(unsigned char mode)  //当前频率+/-   步进 0.1MHz
																		  
正点原子@SCUT
V1.2  
/////////////////////////////////////////////////////////////////////////////////////////////////
TEA5767 FEATURES
FM band:

US/Europe  (87.5 to 108 MHz)
Japanese   (76 to 91MHz)

TEA5767 GENERAL DESCRIPTION
The TEA5767HN is a single-chip electronically tuned FM
stereo radio for low-voltage application with fully integrated
IF selectivity and demodulation. The radio is completely
adjustment-free and only requires a minimum of small and
low cost external components. The radio can be tuned to
the European, US and Japanese FM bands.		    
*/
#include "myiic.h"			 

#define TWINT 7
#define TWSTA 5
#define TWEN  2 
#define TWSTO 4
#define TWEA  6

#define START       0x08          //TWI 状态指示
#define MT_SLA_ACK  0x18
#define MT_DATA_ACK 0x28

#define LowestFM_US 	    87500 //87.5MHz	
#define HighestFM_US    	108000//108Mhz
#define LowestFM_JA 	    76000 //76MHz	
#define HighestFM_JA    	91000 //91Mhz

#define LOW_US_H            0x69
#define LOW_US_L            0xD8  //87.5 &108 MHz
#define HIG_US_H            0x73            
#define HIG_US_L            0x9E  //PLL FOR US band

#define LOW_JA_H            0x64
#define LOW_JA_L            0x5C  //76 & 91 MHz
#define HIG_JA_H            0x6B
#define HIG_JA_L            0x83  //PLL FOR JA band
 

#define SLA_W 0xC0    //write   TEA5767 地址
#define SLA_R 0xC1    //read      

#define JPS 0X32   //日本模式
#define USA 0X12   //美国模式

unsigned char TEA5767_INTI(void);    //初始化TWI
unsigned char set5767(void);         //写TEA5767寄存器
void read5767(void);                 //读TEA5767寄存器,并转化到相关变量   
u8 search_station(unsigned char UP_DOWN);
void set_frequency(unsigned long frequency);
void frequency_UP_DOWN(unsigned char mode);
										   
u8 senddata[5] ;//发送数据缓冲
u8 readdata[5] ;//接收数据缓冲 
							  
u8 RSIGNAL_STATUS=0;//信号状态  最高位:立体声标志,高三位:停止搜索的信号强度。低四位:信号强度	   
u8 JPUS;//欧美或者日本频段选择 0x12欧美 0x02日本
                                     
u8 sCh_Num=0;   //搜索到的最大的电台个数
u8 sCh_Cho=0;   //当前选择的电台号码 CHx       
 	   
unsigned long Ch_Value[30]; //存储电台    

unsigned long frequency_set=0;//Khz 从寄存器里面读出的 频率值  
unsigned long set_freq=0;//自己设定的 最终频率       
					 
/*
可显示 当前频率
       是否立体声
       ADC电压强度(信号强度)
       搜到电台
       频率到达最大/最小值指示
*/
////////////////////////////////////////////////////////////////// 
//设置TEA5767的寄存器
//CHECK OK 09/05/25
unsigned char set5767(void) 
{ 
    u8 i = 0; 
    if(RSIGNAL_STATUS&0x80)senddata[2]&=0xf7;//bit3=0,立体声
    else senddata[2]|=0x08;//bit3=1,单声道     
    							 
	IIC_Start();         //发送起始信号
	IIC_Send_Byte(SLA_W);//send address 写TEA5767的地址    
   	IIC_Wait_Ack(); 	  

	for (i=0;i<5;i++ )//连续发送5个字节 
    {  
		IIC_Send_Byte(senddata[i]); 
		IIC_Wait_Ack(); 	   	   
    }    
    IIC_Stop();	 			   
	return 1;//发送成功
}     
 
//读tea5767的寄存器,并把相关参数计算出来 
//CHECK OK 09/05/25
void read5767(void) 
{ 
	unsigned long nPLL =0;//PLL 	   
	u8 tbTmp1;//PLL7~PLL0
	u8 tbTmp2;//PLL13~PLL8   
    u8 i = 0; 	
											    
	IIC_Start();  //发送起始信号
	IIC_Send_Byte(SLA_R);// send address 发送地址&读 
    IIC_Wait_Ack(); 
	for (i=0;i<5;i++ ) //接收5个字节
    {            													   
        readdata[i]=IIC_Read_Byte(1);// read data                      
    }  
    IIC_Stop();	
	//计算得到的结果值,具体到各个变量			    
	tbTmp1=readdata[1];//PLL7~PLL0
	tbTmp2=readdata[0];//PLL13~PLL8  
	tbTmp2&=0x3f; 
	nPLL=(unsigned long)tbTmp2*256+tbTmp1;//pll的数值 (0~8192) 
    if(senddata[2]&0x10)
		frequency_set =(unsigned long)(nPLL*(float)8.192-225);
    else
		frequency_set =(unsigned long)(nPLL*(float)8.192+225);  
	RSIGNAL_STATUS&=0xf0;
	RSIGNAL_STATUS|=(readdata[3]&0xF0)>>4;//得到adc值的大小		  					   
} 
//初始化tea5767 
//CHECK OK 09/05/25
unsigned char TEA5767_INTI(void)
{ 
	//load 88.3MHz BIT6用于选择是否搜台模式1是/0否 0x29
	//bit6 1搜索模式
	//BIT7 MUTE1/NO MUTE0    PLL13...8
    senddata[1] = 0xFF; // PLL7...0   F1
    senddata[2] = 0x60; //bit7 0用于选择向上1/向下搜台0 
                        //bit3 MS:1单声道 0:立体声
    //bit 6&5ADC选择 0x20 ADC 5
    //0x40 ADC 7
    //0x60 ADC 10 	     							  
    senddata[3] = JPUS;  //bit5 用于选择日本1/欧洲模式0 
    senddata[4] = 0x00;  //不用改
    return (set5767());
}      
//自动搜索,并保存
//CHECK OK 09/05/25
void auto_search(void)
{                        
    u8 ts;  
    if(senddata[3]&0x20)set_freq=LowestFM_JA;//设置到日本频段的最低端
    else set_freq=LowestFM_US;//设置到美国频段的最低端     
	sCh_Num=0;//初始化为0
	sCh_Cho=0;
	while(1)//一旦执行,不可中断
    {   
        ts=search_station(1);  
        if(ts==2)   //搜索到一个电台
        {  
			if(sCh_Num<30)sCh_Num++;//频道上升                           
            sCh_Cho=sCh_Num-1;
			Ch_Value[sCh_Cho]=set_freq;//保存电台  
        }   
        else if(ts==1)//搜索结束
        {         
			if(sCh_Num==0)//没有搜索到任何电台,还原到初始化
			{									   
				if(JPUS==JPS)set_freq=76000;
				else set_freq=87500;
				
			}else  //搜索到了电台
			{
	            sCh_Cho=0;//回到第一个频道 					 
				set_freq=Ch_Value[sCh_Cho];	
			}
			set_frequency(set_freq);//频段跳到指定点 
			Radio_Freq_Show(set_freq);//显示频率值,同时做延时用
			//Signal_CH_Show();//显示信号强度,频道值 	    
            return;//搜索结束 
        }						   
    }   
} 
//手动设置频率
//同时显示频率值
//CHECK OK 09/05/25
void set_frequency(unsigned long frequency) //设定频率KHz
{
    unsigned int PLL;	  
    if(senddata[2]&0x10)//根据充电电流HLSI计算
		PLL=(unsigned int)((float)((frequency+225)*4)/(float)32.768);
    else
		PLL=(unsigned int)((float)((frequency-225)*4)/(float)32.768);
    senddata[0]=PLL/256;
	senddata[1]=PLL%256;
	senddata[0]&=0x3F;
 	senddata[3] = JPUS;//bit5 用于选择日本1/欧洲模式0
    set5767();   
	delay_ms(20);//等待设置生效
	read5767();  //读取数据		  
}   
//从当前频率向上或者向下搜台
//CHECK OK 09/05/25
u8 search_station(unsigned char UP_DOWN)  //自动搜台程序
{  
    u8 mark=0;      //标志位
    u8 tempadc=0;   //暂存adc值
    u8 times=0;     //偏移限制
    u8 signal_adc;		  
	u32 best_freq=0; //保存最好的频率  
	 
    read5767();        //先读状态     
    if(UP_DOWN)set_freq+=200; //预偏移
    else set_freq-=200;                
    while(1)
    {           
        //if(READY&&key_process()==QUIT)return;//中断搜索   
        if(UP_DOWN)set_freq+=50;
        else set_freq-=50;
        if(senddata[3]&0x20)    //日本频带
        {
            if(set_freq<LowestFM_JA) //到达最低频率
	        {
	            set_freq=HighestFM_JA;
	            return 0;//到达了最高频率
	        }  
	        else if(set_freq>HighestFM_JA) //到达最高频率
	        {
	            set_freq=LowestFM_JA; 
	            return 1;//到达了最低频率
	        }
        }    
	    else                              //美国频带
	    {
	        if(set_freq<LowestFM_US)      //到达最低频率
	        {
	            set_freq=HighestFM_US;     
	            return 0;
	        } 
	        else if(set_freq>HighestFM_US)//到达最高频率
	        {
	            set_freq=LowestFM_US;    
	            return 1;         
	        }
	    }         
        set_frequency(set_freq);  				    
		Radio_Freq_Show(set_freq);//显示频率值,同时做延时用
		//Signal_CH_Show();//显示信号强度,频道值
		signal_adc=RSIGNAL_STATUS&0x0f;		 
        if(signal_adc>=(((RSIGNAL_STATUS>>4)&0x07)+7)&&signal_adc>=tempadc)//得到强信号
        {    
            tempadc=signal_adc;//记录最大值  
            best_freq=set_freq;//记录此次最好的频率 
            mark=1;
        } 
        if(mark)times++; //统计次数增加     
        if(times>4&&signal_adc<=(((RSIGNAL_STATUS>>4)&0x07)+7))//有记录了,并且信号下降
        {   
            set_frequency(best_freq);
            set_freq=best_freq;
            return 2;//搜索到一个台    
        } 
    } 
}
 
// 手动找台 ,mode=1,+0.1MHz;mode=0:-0.1MHz
//CHECK OK 09/05/25
void frequency_UP_DOWN(unsigned char mode)// // 步进 0.1MHz
{  	  												  
    if(mode)set_freq+=100;       //向上0.1MHz
	else set_freq-=100;          //向下0.1MHz  
	
    if(senddata[3]&0x20)                           //日本频带
	{
        if(set_freq<LowestFM_JA)                  //到达最低频率
	    set_freq=HighestFM_JA;  
	    else if(set_freq>HighestFM_JA)            //到达最高频率
	    set_freq=LowestFM_JA;             
	}
	else                                           //美国频带
	{
	    if(set_freq<LowestFM_US)                  //到达最低频率
	    set_freq=HighestFM_US;
	    else if(set_freq>HighestFM_US)            //到达最高频率
	    set_freq=LowestFM_US;
	} 
    set_frequency(set_freq);   
}   						  

	  



⌨️ 快捷键说明

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