原创 TEA5767的简单收音机设计

2009-10-9 17:42 1888 2 2 分类: 工程师职场

TEA5767是飞利浦公司生产的一款收音机芯片,很多手机,MP3、MP4里的收音机功能都是于他实现的。
  TEA5767HN 基本资料:
   高灵敏、低噪声高频放大器,
   收音频率:87.6MHz~108MHz,(支持频率范围在76MHz~87.5MHz 之间的校园收音频道),
   LC 调谐振荡器使成本更低,RF AGC 电路
   内置调频中频选择 ,I2C 总线控制
   内置FM 立体声解调器 ,PLL 合成调谐解码器
   两个可编程端口 ,软静音,SNC(立体声噪声消除)
   自适应立体声解码,自动搜索功能
   等待模式,需要一个32.768KHz 晶体
   40 脚LQFP 封装



CPU:STC89C54RD+
晶震:40M



#include<reg52.h>
#include<stdio.h>
#include<INTRINS.H>


sbit SDA_5767=P1^0;     //数据
sbit SCL_5767=P1^1;    // 时钟
sbit BUS_MODE=P1^2;    // 总线选择
sbit BUS_ENABLE=P1^3;  // 总线使能


#define max_freq 108000     //108Mhz
#define min_freq 87500        //87.5Mhz
#define max_pll 0x339b       //108MHz时的pll.
#define min_pll 0x299d        //87.5MHz时的pll.
#define KEY  P2           //P2口作为按键



#define WADDR   0XC0  //写地址
#define RADDR   0XC1  //读地址


unsigned char write_data[5]={0x2b,0x05,0x61,0x11,0x40};  //每次写入5字节 注释如下(感觉有用的注下 详细了解看手册)
//write_data[0] 第二位为1为搜索模式 后6为表示收音机频率的高6位
//write_data[1] 表示收音机频率的低8位
//write_data[2] 最高位表示搜索模式是向上还是向下 后两位表示搜索的灵敏度 第四位立体声和单声道选择位后四为左右声道设置
//write_data[3] 第三位表示日本频率和国际频率选择位 第四位 震荡频率选择位(与第五字节最高位共同决定)第七为数字降噪功能选择
//write_data[4] 最高位决定内部震荡频率
unsigned char read_data[5];   //读取5字节 读以上各寄存器的状态 主要是频率读取


unsigned long frequencry="0";  //32位读取频率数据
unsigned int pll;            //16位转换数据


 



void delay(void) //延时函数
{
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
}


void start_5767(void)//起始
{
BUS_ENABLE=1;
SDA_5767=1;
SCL_5767=1;
delay();
SDA_5767=0;
delay();
SCL_5767=0;
}


void stop_5767(void)//停止
{
SDA_5767=0;
SCL_5767=1;
delay();
SDA_5767=1;
delay();
SCL_5767=0;
BUS_ENABLE=0;
}


void Check_Ack(void) //检查应答信号
{
SDA_5767=1;
SCL_5767=1;
F0=0;
delay();
if(SDA_5767) //如果数据为高 置位非应答标志FO
F0=1;        //通用标志位 PSW状态寄存器
SCL_5767=0;  //准备下一变化数据
}


void Ack(void) //发响应信号
{
SDA_5767=0;
delay();
SCL_5767=1;
delay();
SCL_5767=0;
}


void no_Ack(void) //发非响应信号
{
SDA_5767=1;
SCL_5767=0;
delay();
SCL_5767=1; //迫使数据传输结束
delay();
}


void send_byte(unsigned char temp) //发送一字节数据
{
unsigned char i="8";
while(i--)
{
  SDA_5767=(bit)(temp&0x80);
  SCL_5767=1;
  delay();
  SCL_5767=0;
  temp<<=1;
}
SCL_5767=0;
delay();
SDA_5767=1; //释放SDA数据线
}


unsigned char read_byte(void) //读一字节数据
{
unsigned char i="8";
unsigned char temp;
while(i--)
{
  temp<<=1;
  if(SDA_5767)
  temp++;
  SCL_5767=1;
  delay();
  SCL_5767=0;
}
SCL_5767=0;
delay();
SDA_5767=1; //释放SDA数据线
return (temp);
}


void write_radio()
{
unsigned char i;
start_5767();
send_byte(WADDR);
Check_Ack();
if(F0)
{
  no_Ack();
  return;
}
Ack();
for(i=0;i<5;i++)
{
send_byte(write_data);
Check_Ack();
if(F0)
{
  no_Ack();
  return;
}
Ack();
}
stop_5767();
}



void  read_radio()
{
unsigned char i;
start_5767();
send_byte(RADDR);
Check_Ack();
if(F0)
{
  no_Ack();
  return;
}
Ack();
for(i=0;i<5;i++)
{
read_data=read_byte();
Check_Ack();
if(F0)
{
  no_Ack();
  return;
}
Ack();
}
stop_5767();
}


unsigned int get_radio()  //获得频率数据
{
 unsigned char tmp_h,tmp_l;
 read_radio();
 tmp_h=read_data[0]&0x3f;
 tmp_l=read_data[1];
 return (tmp_h<<8|tmp_l);
}


void get_frequencry() //将数据转换为标准频率
{
 unsigned char tmp_data;
 unsigned int pll_data;
 pll_data=get_radio();
 tmp_data=read_data[2]&0x10;
 if(tmp_data)
 frequencry= (pll_data*32768/4-225000)/1000;  //(单位KHZ)
 else
 frequencry= (pll_data*32768/4+225000)/1000; // (单位KHZ)
}


void get_pll() //将频率转换数据
{
 unsigned char tmp_data;
 unsigned int pll_data;
 unsigned long  tmp_pll;
 pll_data=get_radio();
 tmp_data=read_data[2]&0x10;
 if(tmp_data)
 tmp_pll=(frequencry+255000)*4/32768;// (单位HZ)
 else
 tmp_pll=(frequencry-255000)*4/32768; //(单位HZ)
 pll=(unsigned int)(tmp_pll/1000);    //(单位 KHZ)
}


void search(bit mode)   //手动搜台
{
  get_frequencry();
  if(mode)
  {
  frequencry+=100;
  if(frequencry>max_freq)
  frequencry="87500";
  }
  else
  {
  frequencry-=100;
  if(frequencry<min_freq)
  frequencry="108000";
  }
  get_pll();
  write_data[0]=(pll>>8)&0x3f;
  write_data[1]=pll&0xff;
  write_data[2]=0x61;
  write_data[3]=0x11;
  write_data[4]=0x40;
  write_radio();
}


void auto_search(bit mode)  //自动搜台
{
 get_frequencry();
 get_pll();
 if(mode)
 {
  write_data[2]=0xe1;
  if(pll>max_pll)
  pll="min"_pll;
 }
 else
 {
 write_data[2]=0x61;
 if(pll<min_pll)
 pll=max_pll;
 }
  write_data[0]=(pll>>8)&0x3f+0x40; //自动搜台
  write_data[1]=pll&0xff;
  write_data[2]=0x61;
  write_data[3]=0x11;
  write_data[4]=0x40;
  write_radio();
  read_radio();
  while(!(read_data[0]&0x80)) //最高位为1 电台就绪 否则一直读
  {
   read_radio();
  }
}


 void delay_xms(unsigned int count) //1MS延时函数
{
 register unsigned char j;
 while (count --)
 {
  for (j=0;j<230;j++);
 }
}



unsigned char GetKey()          //键盘处理函数
{
        unsigned char m,n,e=0xff; 
       
        KEY = 0x0f;        //键盘口置00001111
        if (KEY != 0x0f)          //查寻键盘口的值是否变化
        {
                delay_xms(20);       //延时20毫秒
                if (KEY != 0x0f)         //有键按下处理
                {
                        m = KEY;         //键值放入寄存器m
                }
                KEY = 0xf0;       //将键盘口置为11110000
                n = KEY;          //将第二次取得值放入寄存器n
                m |= n;   
                switch(m)        
  

PARTNER CONTENT

文章评论0条评论)

登录后参与讨论
我要评论
0
2
关闭 站长推荐上一条 /3 下一条