📄 tea5767.h
字号:
/*
TEA5767驱动程序:
unsigned char TEA5767_INTI(void); //初始化TWI
unsigned char set5767(void); //写TEA5767寄存器
void read5767(void); //读TEA5767寄存器
void show_frequency(void) //更新TEA5767的数据,为显示用
void search_station(unsigned char UP_DOWN) //自动搜台程序 当前频率(向上/向下)搜台 到达顶点自动装载新频率,继续搜台
void set_frequency(unsigned long frequency) //设定频率 (输入设定频率)
void frequency_UP_DOWN(unsigned char mode) //当前频率+/- 步进 0.1MHz
占用AVR资源:
I/O口两个:SDA & SCL
两线串行接口TWI
状态:测试通过______2008_2_29
作者:龙南
E_mail: lisn3188@163.com
/////////////////////////////////////////////////////////////////////////////////////////////////
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 <avr/io.h>
#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 uchar uint8_t
#define uint uint16_t
#define SLA_W 0xC0 //write TEA5767 地址
#define SLA_R 0xC1 //read
unsigned char TEA5767_INTI(void); //初始化TWI
unsigned char set5767(void); //写TEA5767寄存器
void read5767(void); //读TEA5767寄存器
void show_frequency(void);
void search_station(unsigned char UP_DOWN);
void set_frequency(unsigned long frequency);
void frequency_UP_DOWN(unsigned char mode);
uchar senddata[5] ;
uchar readdata[5] ;
uchar radio_frequency[6];
uchar STEREO=0,SIGNAL_ADC=0;
/*
可显示 当前频率
是否立体声
ADC电压强度(信号强度)
搜到电台
频率到达最大/最小值指示
*/
///////////////////////////////////TWINT 标志的清零必须通过软件写 "1" 来完成
unsigned char set5767(void)
{
uchar i = 0;
TWCR = (1<<TWINT)|(1<<TWSTA)|(1<<TWEN); // SEND START SIGNAL
while (!(TWCR & (1<<TWINT))); // WAIT FOR START SIG 等待START信号发送完成
if ((TWSR & 0xF8) != START) return 0;
TWDR = SLA_W; // send address 写TEA5767的地址
TWCR = (1<<TWINT)|(1<<TWEN); //清TWI中断标志,使能发送。。。
while (!(TWCR & (1<<TWINT))); //等待发送完成。。。
if ((TWSR & 0xF8) !=MT_SLA_ACK) return 0; //ACK
for ( i = 0; i < 5; i++ )
{
TWDR = senddata[i]; //写数据
TWCR = (1<<TWINT)|(1<<TWEN); // send data
while (!(TWCR & (1<<TWINT))); //等待发送完成
if ((TWSR & 0xF8) != MT_DATA_ACK) return 0;//ACK
}
TWCR = (1<<TWINT)|(1<<TWEN)|(1<<TWSTO); //SEND STOP SIGNAL
return 1;
}
///////////////////////////////////////////////////////////////////////////////////////
void show_frequency(void)
{
uint32_t nPLL =0; //PLL
uint32_t frequency = 0; //Khz
uchar tbTmp1=readdata[1];
uchar tbTmp2=readdata[0];
tbTmp2&=0x3f;
nPLL=tbTmp2*256+tbTmp1;
if(senddata[2]&0x10)
frequency =(unsigned long)(nPLL*(float)8.192-225);
else
frequency =(unsigned long)(nPLL*(float)8.192+225);
radio_frequency[0] = frequency / 100000 ;
if ( radio_frequency[0] == 0 ) radio_frequency[0] = 0x20;
else radio_frequency[0] += 0x30;
radio_frequency[1] = (frequency / 10000)%10 +0x30;
radio_frequency[2] = (frequency / 1000)%10 +0x30;
radio_frequency[3] = '.';
radio_frequency[4] = (frequency / 100)%10 +0x30;
radio_frequency[5] = (frequency / 10)%10 +0x30;
if(readdata[2]&0x7F)STEREO=1;else STEREO=0;
SIGNAL_ADC=(readdata[3]&0xF0)>>4;
}
///////////////////////////////////////////////////////////////////////////////////////
void read5767(void)
{
uchar i = 0;
TWCR = (1<<TWINT)|(1<<TWSTA)|(1<<TWEN); // SEND START SIGNAL
while (!(TWCR & (1<<TWINT))); // WAIT FOR START SIG 等待起始信号发送成功
//if ((TWSR & 0xF8) != START) return;
TWDR = SLA_R;
TWCR=(1<<TWINT)|(1<<TWEN); // send address 发送地址&读
while (!(TWCR & (1<<TWINT))); //等待发送完成
//if ((TWSR & 0xF8) !=MT_SLA_ACK) return; //ACK
for ( i = 0; i < 5; i++ )
{
TWCR=(1<<TWINT)|(1<<TWEN)|(1<<TWEA); // read data 使能自动应答
while (!(TWCR & (1<<TWINT))); //是否收到一个字节
readdata[i] = TWDR ; //保存到缓冲区
}
TWCR = (1<<TWINT)|(1<<TWEN)|(1<<TWSTO); //SEND STOP SIGNAL
show_frequency();
}
///////////////////////////////////////////////////////////////////////////////////////
unsigned char TEA5767_INTI(void)
{
TWBR = 12; //分频系数 SCL frequency = CPU Clock frequency/(16+2*(TWBR)*4)
//约 70KHz 的时钟频率
TWCR = (1<<TWEN); //SEND STOP SIGNAL
senddata[0] = 0x29; //load 88.3MHz BIT6用于选择是否搜台模式1是/0否 0x29
//BIT7 MUTE1/NO MUTE0 PLL13...8
senddata[1] = 0xF5; // PLL7...0 F1
senddata[2] = 0x60; //bit7 用于选择向上1/向下搜台0 ADC选择 0x20 ADC 5
//0x40 ADC 7
//0x60 ADC 10
senddata[3] = 0x12; //bit5 用于选择日本1/欧洲模式0
senddata[4] = 0x00; //不用改
return (set5767());
}
///////////////////////////////////////////////////////////////////////////////////////
void search_station(unsigned char UP_DOWN) //自动搜台程序
{
uchar falg;
uint32_t nPLL =0; //Dec
uint32_t frequency = 0; //Khz
read5767(); //先读状态
if(readdata[0]&0x40) //是否到达频率极限
{
uchar tbTmp1=readdata[1];
uchar tbTmp2=readdata[0];
tbTmp2&=0x3f;
senddata[0] = (readdata[0]&0x3F)|0x40; //
senddata[1] = readdata[1];
nPLL=tbTmp2*256+tbTmp1;//save版本:nPLL=pll ;//tbTmp2*256+tbTmp1;
if(senddata[2]&0x10)
frequency =(unsigned long)(nPLL*(float)8.192-225);
else
frequency =(unsigned long)(nPLL*(float)8.192+225);
if(senddata[3]&0x20) //日本频带
{
if(frequency==LowestFM_JA)//到达最低频率//装载高频率的PLL,向下搜台
{
senddata[0]=HIG_JA_H;
senddata[1]=HIG_JA_L;
senddata[2]&=0x7F; //向下搜台0
}
else //到达最高频率//装载低频率的PLL,向上搜台
{
senddata[0]=LOW_JA_H;
senddata[1]=LOW_JA_L;
senddata[2]|= 0x80; //向上搜台1
}
falg=set5767();
return;
}
else //美国频带
{
if(frequency==LowestFM_US)//到达最低频率//装载高频率的PLL,向下搜台
{
senddata[0]=HIG_US_H;
senddata[1]=HIG_US_L;
senddata[2]&=0x7F; //向下搜台0
}
else //到达最高频率//装载低频率的PLL,向上搜台
{
senddata[0]=LOW_US_H;
senddata[1]=LOW_US_L;
senddata[2]|= 0x80; //向上搜台1
}
falg=set5767();
return;
}
}
else //没到达极限
{
senddata[0] = (readdata[0]&0x3F)|0x40; // BIT6用于选择是否搜台模式1是/0否
senddata[1] = readdata[1];
if(UP_DOWN)
senddata[2]|= 0x80; //向上搜台1
else senddata[2]&=0x7F; //向下搜台0
falg=set5767();
return;
}
}
/////////////////////////////////////////////////////////////////////////////////////////////
//手动设置频率
void set_frequency(unsigned long frequency) //设定频率KHz
{
unsigned int PLL;
unsigned char falg;
if(senddata[2]&0x10)
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;
falg=set5767();
}
/////////////////////////////////////////////////////////////////////////////////////////////
// 手动找台 ,mode=1,+0.1MHz;mode=0:-0.1MHz
void frequency_UP_DOWN(unsigned char mode)// // 步进 0.1MHz
{
uint32_t nPLL =0; //
uint32_t frequency = 0; //Khz
read5767(); //读状态
uchar tbTmp1=readdata[1];
uchar tbTmp2=readdata[0];
tbTmp2&=0x3f;
nPLL=tbTmp2*256+tbTmp1; //tbTmp2*256+tbTmp1;
if(senddata[2]&0x10) //算出当前频率
frequency =(unsigned long)(nPLL*(float)8.192-225);
else
frequency =(unsigned long)(nPLL*(float)8.192+225);
if(mode)frequency+=100; //向上0.1MHz
else frequency-=100; //向下0.1MHz
if(senddata[3]&0x20) //日本频带
{
if(frequency<LowestFM_JA) //到达最低频率
frequency=HighestFM_JA;
else if(frequency>HighestFM_JA) //到达最高频率
frequency=LowestFM_JA;
}
else //美国频带
{
if(frequency<LowestFM_US) //到达最低频率
frequency=HighestFM_US;
else if(frequency>HighestFM_US) //到达最高频率
frequency=LowestFM_JA;
}
set_frequency(frequency);
read5767(); //更新
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -