一直对单片机有兴趣,本身具备一点电子方面的知识,C语音也还能做简单的修改。
这次闲来无事,网上淘来TEA5767完整版芯片,决定做个FM收音机。
资料都是网上搜大神们的作品而来,一并感谢。
芯片使用:
STC89C52RC 单片机 
TEA5767 完整版
TDA2822 放大芯片
其他元件:
电阻
电容
晶振
按键
等等
没有用显示。
外接及电池(4节干电池)两套电源,方便移动。
主要功能:
1、开机预设当地强信号台
2、手动切换预设的12个台,本地强台
3、手动搜索
实现的功能:
耳机收听能清晰收到本地12个FM台(济南)
后续:
解决声音小的问题,有可能的话改成喇叭收听。
实物图:




#include 
#include 
#include 
#define uchar unsigned char
#define uint unsigned int
#define max_freq 108000 //手动搜索最高频率
#define min_freq 87500 //手动搜索最低频率
 
uint tt=0; //手动选预设台标记
sbit SDA=P0^0; //接在TEA5767的数据端口 
sbit SCL=P0^1; //接在TEA5767的时钟端口 
sbit KEY1=P3^5; //频率增加按键端口 
sbit KEY2=P3^4; //频率减小按键端口
sbit KEY3=P3^3; //预设电台增加
sbit KEY4=P3^2; //预设电台减少
unsigned char radio_write_data[5]={0x2a,0x30,0xC0,0x17,0x00}; //要写入TEA5767的数据,88.7M,开机预设
 //前两位是频率,后三位不需要修改
unsigned int pll; 
unsigned long frequency=87500;
void delay1ms (unsigned int b)//1ms延时
{
 for(b;b>0;b--)
 {unsigned int i;
 for(i=0;i<300;i++)
 {;}
 }
}
void Delayus(unsigned char x)
{
 for(;x>0;x--);
}
void iic_start()
{
 SDA=1;
 Delayus(5);
 SCL=1;
 Delayus(5);
 SDA=0;
 Delayus(5);
 SCL=0;
 Delayus(5);
}
void iic_stop()
{
 SCL=0;
 Delayus(5);
 SDA=0;
 Delayus(5);
 SCL=1;
 Delayus(5);
 SDA=1;
 Delayus(5);
}
void iic_ack()
{
 SDA=0;
 Delayus(5);
 SCL=1;
 Delayus(5);
 SCL=0;
 Delayus(5);
 SDA=1;
 Delayus(5);
}
bit iic_testack()
{
 bit ErrorBit;
 SDA=1;
 Delayus(5);
 SCL=1;
 Delayus(5);
 ErrorBit=SDA;
 Delayus(5);
 SCL=0;
 return ErrorBit;
}
void iic_write8bit(unsigned char input)
{
 unsigned char temp;
 for(temp=8;temp>0;temp--)
 {
 SDA=(bit)(input&0x80);
 Delayus(5);
 SCL=1;
 Delayus(5);
 SCL=0;
 Delayus(5);
 input=input<<1;
 }
}
//由频率计算PLL
void get_pll(void)
{
 unsigned char hlsi;
 
 hlsi=radio_write_data[2]&0x10; //HLSI位
 if (hlsi)
 pll=(unsigned int)((float)((frequency+225)*4)/(float)32.768); //频率单位:k
 else
 pll=(unsigned int)((float)((frequency-225)*4)/(float)32.768); //频率单位:k
}
/*//由PLL计算频率
void get_frequency(void)
{
 unsigned char hlsi;
 unsigned int npll=0;
 npll=pll;
 hlsi=radio_write_data[2]&0x10;
 if (hlsi)
 frequency=(unsigned long)((float)(npll)*(float)8.192-225); //频率单位:KHz
 else
 frequency=(unsigned long)((float)(npll)*(float)8.192+225); //频率单位:KHz
}
*/
void radio_write(void)
{
 unsigned char i;
 iic_start();
 iic_write8bit(0xc0); //TEA5767写地址
 if(!iic_testack())
 {
 for(i=0;i<5;i++)
 {
 iic_write8bit(radio_write_data[i]);
 iic_ack();
 }
 }
 iic_stop(); 
}
 //将显示的频率算好后写到TEA5767芯片里面实现调节,不用考虑TEA5767用于搜台的相关位:SM,SUD
void search(bit mode)
{
 //radio_read(); 
 if(mode)
 {
 frequency+=10;
 if(frequency>max_freq)
 frequency=min_freq;
 }
 else
 {
 frequency-=10;
 if(frequency<min_freq)
 frequency=max_freq;
 } 
 get_pll();
 radio_write_data[0]=pll/256;
 radio_write_data[1]=pll%256;
 radio_write_data[2]=0xC0;
 radio_write_data[3]=0x17;
 radio_write_data[4]=0x00;
 radio_write();
}
void main()
{
 delay1ms(150); 
 radio_write();
 while(1)
 {
 if(KEY1==0) 
 {
 delay1ms(15); //延时15ms
 if(KEY1==0)
 while(KEY1==0);//等待按键释放
 search(1);
 }
if(KEY2==0) 
 {
 delay1ms(15); //延时15ms
 if(KEY2==0) 
 while(KEY2==0);//等待按键释放
 search(0);
 }
if(KEY3==0) 
 {
 delay1ms(15); //延时15ms
 if(KEY3==0) 
 while(KEY3==0);//等待按键释放
 if (tt==11)//手动选台判断,保证能循环选择,不严禁能工作,请忽略
 tt=-1;
 tt++;
 switch(tt) //手动选台
 {
 case 0: 
 {
 radio_write_data[0]=0x2A;//写入的频率
 radio_write_data[1]=0x30;
 break;
 }
 case 1: 
 {
 radio_write_data[0]=0x2B;
 radio_write_data[1]=0x3C;
 break;
 }
 case 2: 
 {
 radio_write_data[0]=0x2B;
 radio_write_data[1]=0xB6;
 break;
 }
 case 3: 
 {
 radio_write_data[0]=0x2C;
 radio_write_data[1]=0x86;
 break;
 } 
 case 4: 
 {
 radio_write_data[0]=0x2D;
 radio_write_data[1]=0x6E;
 break;
 } 
 case 5: 
 {
 radio_write_data[0]=0x2E;
 radio_write_data[1]=0xB7;
 break;
 } 
 case 6: 
 {
 radio_write_data[0]=0x30;
 radio_write_data[1]=0xD0;
 break;
 } 
 case 7: 
 {
 radio_write_data[0]=0x31;
 radio_write_data[1]=0x0D;
 break;
 } 
 case 8: 
 {
 radio_write_data[0]=0x31;
 radio_write_data[1]=0xA0;
 break;
 } 
 case 9: 
 {
 radio_write_data[0]=0x32;
 radio_write_data[1]=0xB9;
 break;
 } 
 case 10: 
 {
 radio_write_data[0]=0x33;
 radio_write_data[1]=0x02;
 break;
 }
 case 11: 
 {
 radio_write_data[0]=0x33;
 radio_write_data[1]=0x4B;
 break;
 }
 }
 radio_write_data[2]=0xC0;//写入的其他参数
 radio_write_data[3]=0x17;
 radio_write_data[4]=0x00;
 radio_write();
 if (tt==11)
 tt=0;
 }
if(KEY4==0) 
 {
 delay1ms(15); //延时15ms
 if(KEY4==0) 
 while(KEY4==0);//等待按键释放
 if (tt==0)//手动选台判断,保证能循环选择,不严禁能工作,请忽略
 tt=12;
 tt--;
 switch(tt) //手动选台
 {
 case 0: 
 {
 radio_write_data[0]=0x2A;
 radio_write_data[1]=0x30;
 break;
 }
 case 1: 
 {
 radio_write_data[0]=0x2B;
 radio_write_data[1]=0x3C;
 break;
 }
 case 2: 
 {
 radio_write_data[0]=0x2B;
 radio_write_data[1]=0xB6;
 break;
 }
 case 3: 
 {
 radio_write_data[0]=0x2C;
 radio_write_data[1]=0x86;
 break;
 } 
 case 4: 
 {
 radio_write_data[0]=0x2D;
 radio_write_data[1]=0x6E;
 break;
 } 
 case 5: 
 {
 radio_write_data[0]=0x2E;
 radio_write_data[1]=0xB7;
 break;
 } 
 case 6: 
 {
 radio_write_data[0]=0x30;
 radio_write_data[1]=0xD0;
 break;
 } 
 case 7: 
 {
 radio_write_data[0]=0x31;
 radio_write_data[1]=0x0D;
 break;
 } 
 case 8: 
 {
 radio_write_data[0]=0x31;
 radio_write_data[1]=0xA0;
 break;
 } 
 case 9: 
 {
 radio_write_data[0]=0x32;
 radio_write_data[1]=0xB9;
 break;
 } 
 case 10: 
 {
 radio_write_data[0]=0x33;
 radio_write_data[1]=0x02;
 break;
 }
 case 11: 
 {
 radio_write_data[0]=0x33;
 radio_write_data[1]=0x4B;
 break;
 }
 }
 radio_write_data[2]=0xC0;
 radio_write_data[3]=0x17;
 radio_write_data[4]=0x00;
 radio_write();
 if (tt==0)
 tt=11;
 }
 } 
}