一、简介 TEA5767是由菲利普公司推出的一款低功耗立体声收音机接收器芯片。频率范围从76-108MHz自动数字调谐。高灵敏度,高稳定性,低噪音,收音模块。一片低功耗电调谐调频立体声收音机电路,其内部集成了中频选频和解调网络,可以做到完全免调。 电源 5V
I2C 总线通讯
可以使用软件进行静音和消除噪音
二、硬件连接
功能口 引脚
SCL PB.6
SDA PB.5
三、添加I2C驱动
四、移植文件
注意:以下出现缺失common.h文件错误,去除即可。uint8改为uint8_t或unsigned char或自己宏定义
将 board_i2c.c、board_i2c.h、board_tea5767.c 、 board_tea5767.h 四个文件加入到工程
4.1 board_tea5767.c
- /*********************************************************************
- * INCLUDES
- */
- #include "stdlib.h"
- #include "stm32f10x.h"
- #include "board_i2c.h"
- #include "board_tea5767.h"
- #include "common.h"
- /*********************************************************************
- * GLOBAL VARIABLES
- */
- unsigned long g_frequency = TEA5767_MIN_KHZ;
- /*********************************************************************
- * LOCAL VARIABLES
- */
- static uint8 s_radioWriteData[5] = {0x31,0xA0,0x20,0x11,0x00}; // 要写入TEA5767的数据,默认存台的PLL,104.3MHz
- static uint8 s_radioReadData[5] = {0}; // TEA5767读出的状态
- static uint32 s_pll = 0;
- /*********************************************************************
- * PUBLIC FUNCTIONS
- */
- /**
- @brief 向TEA5767写入5个字节数据
- @param 无
- @return 无
- */
- void TEA5767_Write(void)
- {
- uint8 i;
-
- IIC_Start(); // 发送起始信号
- IIC_SendByte(TEA5767_ADDR_W); // TEA5767写地址
- IIC_WaitAck(); // 等待应答
- for(i = 0; i < 5; i++)
- {
- IIC_SendByte(s_radioWriteData); // 连续写入5个字节数据
- IIC_Ack(); // 发送应答
- }
- IIC_Stop(); // 发送停止信号
- }
- /**
- @brief 读TEA5767状态
- @param 无
- @return 无
- */
- void TEA5767_Read(void)
- {
- uint8 i;
- uint8 tempLow;
- uint8 tempHigh;
- s_pll = 0;
-
- IIC_Start();
- IIC_SendByte(TEA5767_ADDR_R); // TEA5767读地址
- IIC_WaitAck();
- for(i = 0; i < 5; i++) // 读取5个字节数据
- {
- s_radioReadData = IIC_ReadByte(); // 读取数据后,发送应答
- }
- IIC_Stop();
- tempLow = s_radioReadData[1]; // 得到s_pll低8位
- tempHigh = s_radioReadData[0]; // 得到s_pll高6位
- tempHigh &= 0x3f;
- s_pll = tempHigh * 256 + tempLow; // PLL值
- }
- /**
- @brief 由频率计算PLL
- @param 无
- @return 无
- */
- void TEA5767_GetPLL(void)
- {
- uint8 hlsi;
- hlsi = s_radioWriteData[2] & 0x10; // HLSI位
- if(hlsi)
- {
- s_pll = (uint32)((float)((g_frequency+225)*4)/(float)32.768); // 频率单位:k
- }
- else
- {
- s_pll = (uint32)((float)((g_frequency-225)*4)/(float)32.768); // 频率单位:k
- }
- }
- /**
- @brief 设置频率
- @param frequency -[in] 频率,单位:KHz
- @return 无
- */
- void TEA5767_SetFrequency(uint32 frequency)
- {
- g_frequency = frequency;
- TEA5767_GetPLL();
- s_radioWriteData[0] = s_pll / 256;
- s_radioWriteData[1] = s_pll % 256;
- s_radioWriteData[2] = 0x20;
- s_radioWriteData[3] = 0x11;
- s_radioWriteData[4] = 0x00;
-
- TEA5767_Write();
- }
- /**
- @brief 由PLL计算频率
- @param 无
- @return 无
- */
- uint32 TEA5767_GetFrequency(void)
- {
- uint8 hlsi;
- uint32 pll = 0;
- pll = s_pll;
- hlsi = s_radioWriteData[2] & 0x10;
- if(hlsi)
- {
- g_frequency = (unsigned long)((float)(pll)*(float)8.192-225); // 频率单位:KHz
- }
- else
- {
- g_frequency = (unsigned long)((float)(pll)*(float)8.192+225); // 频率单位:KHz
- }
-
- return g_frequency;
- }
- /**
- @brief 手动搜索电台,不用考虑TEA5767用于搜台的相关位:SM,SUD
- @param mode -[in] 搜索方式,mode=1,向上搜索,频率值+0.1MHz;mode=0,向下搜索,频率值-0.1MHz
- @return 无
- */
- void TEA5767_Search(uint8 mode)
- {
- TEA5767_Read(); // 读取当前频率值
- if(mode) // 向上搜索
- {
- g_frequency += 100;
- if(g_frequency > TEA5767_MAX_KHZ) // 频率达到最大值
- {
- g_frequency = TEA5767_MIN_KHZ;
- }
- }
- else
- {
- g_frequency -= 100;
- if(g_frequency < TEA5767_MIN_KHZ)
- {
- g_frequency = TEA5767_MAX_KHZ;
- }
- }
- TEA5767_GetPLL(); // 计算PLL值
- s_radioWriteData[0] = s_pll / 256;
- s_radioWriteData[1] = s_pll % 256;
- s_radioWriteData[2] = 0x20;
- s_radioWriteData[3] = 0x11;
- s_radioWriteData[4] = 0x00;
- TEA5767_Write();
- TEA5767_Read();
- if(s_radioReadData[0] & 0x80) // 搜台成功,RF=1,可保存其频率值待用
- {
- printf(" frequency=%d\n", (int)g_frequency);
- }
- }
- /**
- @brief 自动搜索电台
- @param mode -[in] 搜索方式,mode=1,频率增加搜台,频率值+0.1MHz;mode=0,频率减小搜台
- @return 无
- */
- void TEA5767_AutoSearch(uint8 mode)
- {
- uint8 radioRf = 0; // 1=发现一个电台,0=未找到电台
- uint8 radioIf = 0; // 中频计数结果
- uint8 radioLev = 0; // 信号电平ADC输出
-
- // 直到搜台成功,RF=1,0x31<IF<0x3E
- while((radioRf==0) || ((0x31>=radioIf)||(radioIf>=0x3E)))
- {
- if(mode) // 频率增加搜台
- {
- s_radioWriteData[2] = 0xC0; // SUD=1,SSLadc=7,HLSI=0
- g_frequency += 100;
- if(g_frequency > TEA5767_MAX_KHZ) // 频率达到最大值
- {
- g_frequency = TEA5767_MIN_KHZ;
- }
- }
- else // 频率减小搜台
- {
- s_radioWriteData[2] = 0x40; // SUD=0,SSLadc=7,HLSI=0
- g_frequency -= 100;
- if(g_frequency < TEA5767_MIN_KHZ)
- {
- g_frequency = TEA5767_MAX_KHZ;
- }
- }
- TEA5767_GetPLL(); // 转换为PLL值
- s_radioWriteData[0] = s_pll / 256 + 0xC0; // MUTE=1,SM=1
- s_radioWriteData[1] = s_pll % 256;
- s_radioWriteData[3] = 0x11;
- s_radioWriteData[4] = 0x00;
- TEA5767_Write(); // 写入5个字节数据
- TEA5767_Read(); // 读取当前频率值
- radioRf = s_radioReadData[0] & 0x80;
- radioIf = s_radioReadData[2] & 0x7F;
- radioLev = s_radioReadData[3] >> 4;
- printf(" r=%02x\n", radioRf);
- printf(" i=%02x\n", radioIf);
- printf(" l=%d\n", radioLev);
- printf(" f=%d\n", (int)g_frequency);
- }
- TEA5767_GetPLL(); // 转换为PLL值
- s_radioWriteData[0] = s_pll / 256; // MUTE=0,SM=0
- s_radioWriteData[1] = s_pll % 256;
- s_radioWriteData[3] = 0x11;
- s_radioWriteData[4] = 0x00;
- TEA5767_Write(); // 写入5个字节数据
- TEA5767_Read(); // 读取当前频率值
- printf(" frequency=%d\n", (int)g_frequency);
- }
- /**
- @brief 静音
- @param mode -[in] 静音方式,mode=1,静音;mode=0,非静音
- @return 无
- */
- void TEA5767_Mute(uint8 mode)
- {
- if(mode == TEA5767_MUTE_ON)
- {
- s_radioWriteData[0] = s_radioWriteData[0] | 0x80;
- }
- else
- {
- s_radioWriteData[0] = s_radioWriteData[0] & 0x7F;
- }
-
- TEA5767_Write();
- }
- /****************************************************END OF FILE****************************************************/
复制代码
4.2 board_tea5767.h
- #ifndef _BOARD_TEA5767_H_
- #define _BOARD_TEA5767_H_
- /*********************************************************************
- * INCLUDES
- */
- #include "stm32f10x.h"
- #include "common.h"
- /*********************************************************************
- * DEFINITIONS
- */
- #define TEA5767_ADDR_W 0xc0 // TEA5767 写地址
- #define TEA5767_ADDR_R 0xc1 // TEA5767 读地址
- #define TEA5767_MAX_KHZ 108000 // 最高频率 108M
- #define TEA5767_MIN_KHZ 87500 // 最低频率 87.5M
- #define TEA5767_MUTE_ON 1 // 非静音
- #define TEA5767_MUTE_OFF 0 // 静音
- #define TEA5767_SEARCH_UP 1 // 向上搜索
- #define TEA5767_SEARCH_DOWN 0 // 向下搜索
- /*********************************************************************
- * GLOBAL VARIABLES
- */
- extern unsigned long g_frequency;
- /*********************************************************************
- * API FUNCTIONS
- */
- void TEA5767_Write(void);
- void TEA5767_Read(void);
- void TEA5767_GetPLL(void);
- void TEA5767_SetFrequency(uint32 frequency);
- uint32 TEA5767_GetFrequency(void);
- void TEA5767_Search(uint8 mode);
- void TEA5767_AutoSearch(uint8 mode);
- void TEA5767_Mute(uint8 mode);
- #endif /* _BOARD_TEA5767_H_ */
复制代码
五、API调用
需包含头文件 board_tea5767.h
TEA5767_Write
功能 向TEA5767写入5个字节数据
函数定义 void TEA5767_Write(void)
参数 无
返回 无
TEA5767_Read
功能 读TEA5767状态
函数定义 void TEA5767_Read(void)
参数 无
返回 无
TEA5767_GetPLL
功能 由频率计算PLL
函数定义 void TEA5767_GetPLL(void)
参数 无
返回 无
TEA5767_SetFrequency
功能 设置频率
函数定义 void TEA5767_SetFrequency(uint32 frequency)
参数 frequency:频率,单位:KHz
返回 无
TEA5767_GetFrequency
功能 由PLL计算频率
函数定义 uint32 TEA5767_GetFrequency(void)
参数 无
返回 当前频率
TEA5767_Search
功能 手动搜索电台,不用考虑TEA5767用于搜台的相关位:SM,SUD
函数定义 void TEA5767_Search(uint8 mode)
参数 mode:搜索方式,mode=1,向上搜索,频率值+0.1MHz;mode=0,向下搜索,频率值-0.1MHz
返回 无
TEA5767_AutoSearch
功能 自动搜索电台
函数定义 void TEA5767_AutoSearch(uint8 mode)
参数 mode:搜索方式,mode=1,向上搜索,频率值+0.1MHz;mode=0,向下搜索,频率值-0.1MHz
返回 无
TEA5767_Mute
功能 静音
函数定义 void TEA5767_Mute(uint8 mode)
参数 mode:静音方式,mode=1,静音;mode=0,非静音
返回 无
六、使用例子
6.1 手动加减台
±0.1MHz,87.5-108MHz,循环增减
- TEA5767_Search(1); // 加台
- TEA5767_Search(0); // 减台
复制代码
6.2 自动搜台
由于从IC中读回的频率不准,这里采用静态变量g_frequency来记录当前频率,87.5-108MHz,循环增减
- TEA5767_AutoSearch(1); // 向上搜台
- TEA5767_AutoSearch(0); // 向下搜台
复制代码
参考自动搜台流程:
由上面流程可知,决定参数有
rf:1=发现一个电台,0=未找到电台
if:中频计数结果,0x31<IF<0x3E则为符合电台
lev:信号电平ADC输出,可通过写入的5个字节中对应SSLadc的位(查看下面附录),下面SSLadc=7
- void TEA5767_AutoSearch(uint8 mode)
- {
- uint8 radioRf = 0; // 1=发现一个电台,0=未找到电台
- uint8 radioIf = 0; // 中频计数结果
- uint8 radioLev = 0; // 信号电平ADC输出
-
- // 直到搜台成功,RF=1,0x31<IF<0x3E
- while((radioRf==0) || ((0x31>=radioIf)||(radioIf>=0x3E)))
- {
- if(mode) // 频率增加搜台
- {
- s_radioWriteData[2] = 0xC0; // SUD=1,SSLadc=7,HLSI=0
- g_frequency += 100;
- if(g_frequency > TEA5767_MAX_KHZ) // 频率达到最大值
- {
- g_frequency = TEA5767_MIN_KHZ;
- }
- }
- else // 频率减小搜台
- {
- s_radioWriteData[2] = 0x40; // SUD=0,SSLadc=7,HLSI=0
- g_frequency -= 100;
- if(g_frequency < TEA5767_MIN_KHZ)
- {
- g_frequency = TEA5767_MAX_KHZ;
- }
- }
- TEA5767_GetPLL(); // 转换为PLL值
- s_radioWriteData[0] = s_pll / 256 + 0xC0; // MUTE=1,SM=1
- s_radioWriteData[1] = s_pll % 256;
- s_radioWriteData[3] = 0x11;
- s_radioWriteData[4] = 0x00;
- TEA5767_Write(); // 写入5个字节数据
- TEA5767_Read(); // 读取当前频率值
- radioRf = s_radioReadData[0] & 0x80;
- radioIf = s_radioReadData[2] & 0x7F;
- radioLev = s_radioReadData[3] >> 4;
- printf(" r=%02x\n", radioRf);
- printf(" i=%02x\n", radioIf);
- printf(" l=%d\n", radioLev);
- printf(" f=%d\n", (int)g_frequency);
- }
- TEA5767_GetPLL(); // 转换为PLL值
- s_radioWriteData[0] = s_pll / 256; // MUTE=0,SM=0
- s_radioWriteData[1] = s_pll % 256;
- s_radioWriteData[3] = 0x11;
- s_radioWriteData[4] = 0x00;
- TEA5767_Write(); // 写入5个字节数据
- TEA5767_Read(); // 读取当前频率值
- printf(" frequency=%d\n", (int)g_frequency);
- }
复制代码
6.3 软件静音
- TEA5767_Mute(TEA5767_MUTE_ON); // 收音机静音
- TEA5767_Mute(TEA5767_MUTE_OFF); // 收音机开启收听
复制代码
七、附录
7.1 写数据
向TEA5767 写入数据时,地址的最低位是0,即写地址是C0。读出数据时地址的最低位是1,即读地址是C1。TEA5767的控制寄存器要写入5个字节,每次写入数据时必须严格按照下列顺序进行:
地址、字节1、字节2、字节3、字节4、字节5。
每个字节的最高位首先发送。在时钟的下降沿后写入的数据生效。上电复位后,设置为静音,所有其它位均被置低,必须写入控制字初始化芯片。
TEA5767内部有一个5个字节的控制寄存器,在IC上电复位后必须通过总线接口向其中写入适当的控制字,它才能够正常工作。每个数据字节各位的功能含义见表4到表14。
表4 数据字节1的格式 BIT7(MSB) BIT6 BIT5 BIT4 BIT3 BIT2 BIT1 BIT0(LSB)
MUTE SM PLL13 PLL12 PLL11 PLL10 PLL9 PLL8
表5 数据字节1各位的说明
BIT SYMBOL 说明
7 MUTE 若MUTE=1 左右声道静音;若 MUTE=0 左右声道非静音
6 SM 搜索模式;若SM=1 搜索模式;若 SM=0 非搜索模式
5 to 0 PLL(13:8) 预置或搜索电台的频率数据高6位
表6 数据字节2的格式
BIT7(MSB) BIT6 BIT5 BIT4 BIT3 BIT2 BIT1 BIT0(LSB)
PLL7 PLL6 PLL5 PLL4 PLL3 PLL2 PLL1 PLL0
表7 数据字节2各位的说明
BIT SYMBOL 说明
7 to 0 PLL(7:0) 预置或搜索电台的频率数据低8位
表8 数据字节3的格式
BIT7(MSB) BIT6 BIT5 BIT4 BIT3 BIT2 BIT1 BIT0(LSB)
SUD SSL1 SSL0 HLSI MS ML MR SWP1
表9 数据字节3各位的说明
BIT SYMBOL 说明
7 SUD 若 SUD=1 向上搜索;
若 SUD=0 向下搜索
6 and 5 SSL[1:0] 搜索停止电平:见表10-11
4 HLSI 若 HLSI=1 高端本振注入;
若 HLSI=0 低端本振注入
3 MS 若 MS=1 强制单声道;
若 MS=0 开立体声
2 ML 若 ML=1 左声道静音强制单声道;
若 ML=0 左声道非静音
1 MR 若 MR=1 右声道静音强制单声道;
若 MR=0 右声道非静音
0 SWP1 软件可编程输出口1:若 SWP1=1 SWPOR1为高;
若 SWP1=0 SWPOR1为低
表10 搜索停止电平设定
SSL1 SSL0 搜索停止电平
0 0 不搜索
0 1 低电平 ADC output=5
1 0 中电平ADC output=7
1 1 高电平ADC output=10
表11 数据字节4的格式
BIT7(MSB) BIT6 BIT5 BIT4 BIT3 BIT2 BIT1 BIT0(LSB)
SWP2 STBY BL XTAL SMUTE HCC SNC SI
表12 数据字节4各位的说明
BIT SYMBOL 说明
7 SWP2 软件可编程输出口2:若 SWP2=1 口2为高;
若 SWP2=0口2为低
6 STBY 若 STBY=1 待机模式;
若 STBY=0 非待机模式
5 BL 若 BL=1 日本FM波段;
若 BL=0 美/欧 FM 波段
4 XTAL 若 XTAL=1 fxtal=32.768KHz;
若 XTAL=0 fxtal=13MHz
3 SMUTE 若SMUTE=1 软件静音开;
若 MUTE=0 软件静音关
2 HCC 若 HCC=1高音切割开;
若 HCC=0高音切割关
1 SNC 若 SNC =1立体声噪声消除开;
若 SNC=0立体声噪声消除关
0 SI 若SI=1 引脚SWPORT1 作ready flag输出标志;
若 SI=0 引脚SWOPRT1 作软件可编程输出口
表13 数据字节5的格式
BIT7(MSB) BIT6 BIT5 BIT4 BIT3 BIT2 BIT1 BIT0(LSB)
PLLREF DTC - - - - - -
表14 数据字节5各位的说明
BIT SYMBOL 说明
7 PLLREF 若 PLLREF=1 则6.5 MHz 参考频率 PLL可用;
若 PLLREF=0 则6.5 MHz参考频率 PLL不可用
6 DTC 若DTC=1 the 去加重时间常数为75μs;
若 DTC=0 the 去加重时间常数为50μs
5 to 0 - 不用管它
7.2 读数据
和写数据类似,从TEA5767 读出数据时,也要按照“地址、字节1、字节2、字节3、字节4、字节5”这样的顺序读出,读地址是C1。读出的5个字节的含义见表16到表25中的说明。
表15 读模式 数据字节1 数据字节2 数据字节3 数据字节4 数据字节5
表16 数据字节1的格式
BIT7(MSB) BIT6 BIT5 BIT4 BIT3 BIT2 BIT1 BIT0(LSB)
RF BLF PLL13 PLL12 PLL11 PLL10 PLL9 PLL8
表17 数据字节1各位的说明
BIT SYMBOL 说明
7 RF 若RF=1 则发现了一个电台或搜索到头;
若 RF=0 未找到电台
6 BLF 若BLF=1 搜索到头;
若 BLF=0 未搜索到头
5 to 0 PLL[13:8] 搜索或预置的电台频率值的高6位
表18 数据字节2的格式
BIT7(MSB) BIT6 BIT5 BIT4 BIT3 BIT2 BIT1 BIT0(LSB)
PLL7 PLL6 PLL5 PLL4 PLL3 PLL2 PLL1 PLL0
表19 数据字节2各位的说明
BIT SYMBOL 说明
7 to 0 PLL(7:0) 预置或搜索电台的频率数据低8位
表20 数据字节3的格式
BIT7(MSB) BIT6 BIT5 BIT4 BIT3 BIT2 BIT1 BIT0(LSB)
STEREO IF6 IF5 IF4 IF3 IF2 IF1 IF0
表21 数据字节3各位的说明
BIT SYMBOL 说明
7 STEREO 若 STEREO=1 为立体声;
若 STEREO=0 为单声道
6 to 0 IF[6:0] 中频计数结果
表22 数据字节4的格式
BIT7(MSB) BIT6 BIT5 BIT4 BIT3 BIT2 BIT1 BIT0(LSB)
LEV3 LEV2 LEV1 LEV0 CI3 CI2 CI1 CI0
表23 数据字节4各位的说明
BIT SYMBOL 说明
7 to 4 LEV[3:0] 信号电平ADC 输出
3 to 1 CI[3:1] 芯片标记; 设置为0
0 - 该位为 0
表24 数据字节5的格式
BIT7(MSB) BIT6 BIT5 BIT4 BIT3 BIT2 BIT1 BIT0(LSB)
0 0 0 0 0 0 0 0
表25 数据字节5各位的说明
BIT SYMBOL 说明
7 to 0 - 供以后备用的字节;设置为0
7.3 举例
根据上面的算法,以106.8的天津交通台为例,它的PLL为32d1H,第一个字节的BIT7=0非静音,BIT6=0不搜索,第三个字节的BIT4=0低本振,第四个字节的BIT5=0欧美制式,BIT4=1用32768晶振,其余位的设置无所谓,可任意。各字节值见表27~31。
表27字节1:0x32 BIT7(MSB) BIT6 BIT5 BIT4 BIT3 BIT2 BIT1 BIT0(LSB)
MUTE SM PLL13 PLL12 PLL11 PLL10 PLL9 PLL8
0 0 1 1 0 0 1 0
非静音 非搜索 3 2
表28字节2:0xd1 BIT7(MSB) BIT6 BIT5 BIT4 BIT3 BIT2 BIT1 BIT0(LSB)
PLL7 PLL6 PLL5 PLL4 PLL3 PLL2 PLL1 PLL0
1 1 0 1 0 0 0 1
d 1
表29字节3:0xc0 BIT7(MSB) BIT6 BIT5 BIT4 BIT3 BIT2 BIT1 BIT0(LSB)
SUD SSL1 SSL0 HLSI MS ML MR SWP1
1 1 0 0 0 0 0 0
向上搜索 搜索停止中电平 低本振 立体声 非静音 随便
表30字节4:0x17
BIT7(MSB) BIT6 BIT5 BIT4 BIT3 BIT2 BIT1 BIT0(LSB)
SWP2 STBY BL XTAL SMUTE HCC SNC SI
0 0 0 1 0 1 1 1
任意(不用) 非待机 欧美 32.768 非软件静音 高音切割 除噪声 SWP1=RF
表31字节5:0x00
BIT7(MSB) BIT6 BIT5 BIT4 BIT3 BIT2 BIT1 BIT0(LSB)
PLLREF DTC - - - - - -
0 0 0 0 0 0 0 0
不用6.5M 50μs
据此给出的控制字是:0x32,0xd1,0xC0,0x17,0x00,将这个控制字写入TEA5767就可以了。 ————————————————
版权声明:Leung_ManWah |