嵌入式设计 | 基于51单片机的TEA5767 FM收音机

我们现在想要实现,51单片机控制TEA5767收音模块,自动搜台,功放发声,并在1602液晶上面显示

还是那句话,要学会看芯片手册。这个项目无非通过就是I²C写数据输出,喇叭发声,然后把变化的数据显示在1602液晶上


1.TEA5767芯片

让我们看看TEA5767的介绍

TEA5767HN是一款低功耗立体声收音 IC,广泛应用于手机、MP3、MP4播放器等便携系统。**接收频率76MHz~108MHz(**日本 /美国 /欧洲频段选择),中频频率 225kHz,采用锁相环调谐系统 ,带有AGC电路,并可以使用软件进行静音和消除噪音。主要 电性能指标 :工作 电压 :2.5V~5.0V,工作 电流 10mA,灵敏度 15 V,立体声分离度30dB,信噪比60dB,输出信号 电平 75mV。总线通信界面 i2C和3线总线可选 ,具有 RF信号强度 ADC输出,软件静音

1.1 I²C协议

嵌入式设计 | 基于51单片机的TEA5767 FM收音机_第1张图片
A是应答的意思,这个是公认的格式,主要看芯片手册。

有需要看ic总线教程的 可以看我之前发的https://blog.csdn.net/Yizkkkkang/article/details/107223724

1.2 器件地址

1100 000R/W 可见 读就是0xc1,写就是0xc0,我们这里不用到读数据
只用0xc0
嵌入式设计 | 基于51单片机的TEA5767 FM收音机_第2张图片

1.3 时序图

嵌入式设计 | 基于51单片机的TEA5767 FM收音机_第3张图片

TEA5767内部有一个5个字节的控制寄存器,在IC上电复位后必须通过总线接口向其中写入适当的控制字,它才能够正常工作。所以初始化函数必须写5个数据

写数据
1.
嵌入式设计 | 基于51单片机的TEA5767 FM收音机_第4张图片

第一个
嵌入式设计 | 基于51单片机的TEA5767 FM收音机_第5张图片
7是静音位,6是搜索或不搜索,0-5是PLL位(后面第二点再详细说明,先知道有这个东西)

第二个
嵌入式设计 | 基于51单片机的TEA5767 FM收音机_第6张图片
这里八位全是PLL位

第三种
嵌入式设计 | 基于51单片机的TEA5767 FM收音机_第7张图片
第七位是向上或向下搜索,第六位搜索停止电平见下图,HLSI高端本振,我买的模块是32.MHZ的这里为1,
嵌入式设计 | 基于51单片机的TEA5767 FM收音机_第8张图片
第四种
嵌入式设计 | 基于51单片机的TEA5767 FM收音机_第9张图片
第五种
嵌入式设计 | 基于51单片机的TEA5767 FM收音机_第10张图片
总结一波
嵌入式设计 | 基于51单片机的TEA5767 FM收音机_第11张图片

1.2 锁相环

许多通信设备要正常工作,通常需要外部的输入信号与内部的震荡信号同步,一般的晶振由于工艺和成本的原因,做不到很高的频率,所以在使用的时候,需要VCO转为高频,但却不稳定,所以要锁相环路,就可以实现稳定的高频的时钟信号。
嵌入式设计 | 基于51单片机的TEA5767 FM收音机_第12张图片
就像我们在开车,输入信号相当于我们看到的马路,眼睛(鉴相器)看看车会不会开偏了,会的话就要用手(滤波器)矫正方向盘,车变正(振荡器),如果不够正就会一直循环(u0t)

嵌入式设计 | 基于51单片机的TEA5767 FM收音机_第13张图片简单理解PLL(图中的N)相当于我们平时电台某节目FM99.3转换过来的在芯片中计算的一个数值,然后说明书里面的 fRF 就是电台节目FM的值,我们也要把这个FM显示在LED液晶屏上,这里的fIF是中频频率,开头也介绍了TEA5767这个模块的中频频率 225kHz,晶体振荡器为 32.768kHZ,及时没有学过锁相环这个知识,也可以使用此芯片。

TEA5767引脚图

嵌入式设计 | 基于51单片机的TEA5767 FM收音机_第14张图片
这里我们的busmood用低电平,因为能节省I²O口,而且刚好也学过,很方便。SDA和CLK数据和时钟总线,为了保持稳定,高电平需要10K上拉电阻,也是I²C的内容,我们没有用到MPXO,不用接。ANT是天线,可以用导线代替,但一定要长一定要长一定要长,重要的事情说三遍,最好有一米!输出呢我们用一个8Ω0.5W的喇叭,所以只接一个单声道。
嵌入式设计 | 基于51单片机的TEA5767 FM收音机_第15张图片
这个是输出口的电压,从左到右依次是 min typ max。typ是典型,所以我们假设输出口输出75mv给功率放大器,那么根据功率放大器的输入电压最大值(区别工作电压)就能确定中间需要多大阻值的电阻防止失真,或者直接采用滑动变阻器或者是电位器就可以调节音量。


那接下来就讲一讲功放芯片
嵌入式设计 | 基于51单片机的TEA5767 FM收音机_第16张图片
引脚1、8两端开路,放大器增益是20倍(26db),tea5767输出75mV电压,那么75mV*20=1.5V,虽然没有达到饱和电源电压,但是在实际过程中,当搜索不到电台的频率会出现尖叫声。所以笔者在tea5767输出端,LM386输入端的接线上串联了一个小电容滤波和一个6.3K电阻分压,如果有条件可以用10K的滑动变阻器,就能够实现调节音量。


嵌入式设计 | 基于51单片机的TEA5767 FM收音机_第17张图片

接下来老生常谈

  • 供电:我用了USB供电下载模块,某宝上面花了10块买的,又可以烧录又可以供电一举两得,充电宝和电脑或者5V手机充电器都可以供电。

  • 晶振,晶振当然是11.0592MHz啦,再并联两个电容

  • 复位电路,其实可有可无,如果有了岂不是跟完整?具体查看教程https://blog.csdn.net/Yizkkkkang/article/details/106025607

  • 1602液晶教程https://blog.csdn.net/Yizkkkkang/article/details/107179031

  • I²C教程https://blog.csdn.net/Yizkkkkang/article/details/107223724

  • 独立键盘教程https://blog.csdn.net/Yizkkkkang/article/details/106598640消抖可参照矩阵键盘




#include 
#include 
#define uchar unsigned char
#define uint unsigned int
	
uchar code table[]={
     0x30,0x50,0x70,0x16,0x80};
uchar code table1[]="   FM TEA5767";
uchar code table2[]="     85Mhz";
uchar bai,shi,ge,xiao;
uchar TEA5767WriteData[5];
uchar TEA5767_init_date[5];
sbit scl=P1^0;
sbit sda=P1^1;
sbit key_up=P3^3;
sbit key_down=P3^4;
sbit lcden=P2^7;
sbit lcdrs=P2^5;

//我们用的是I2C,BM低电平
void delay()
{
     ;;}
	
void delay1(uchar z)
{
     
	uchar x,y;
	for(x=z;x>0;x--)
		for(y=110;y>0;y--);
}

void start()//起始信号
{
     
	sda=1;
	delay();
	scl=1;
	delay();
	sda=0;
	delay();
}

void stop()//终止信号
{
     
	sda=0;
	delay();
	scl=1;
	delay();
	sda=1;
	delay();
}

void responds()//响应信号
{
     
	uchar i;
	scl=1;
	delay();
	while((sda==1)&&(i<250))i++;
	scl=0;
	delay();
}

void write_byte(uchar TEA5767WriteData)//写地址
{
     
	uchar i,temp;
	temp=TEA5767WriteData;
	scl=0;
	delay();
	
	for(i=0;i<8;i++)
	{
     
		temp=temp<<1;
		sda=CY;//最高位  
		delay();
		scl=1;
		delay();
		scl=0;
		delay();
	}
	sda=1;
	delay();
}

void TEA5767_SetFrequency(float fFrequency) //算出
{
     
  uint PLL,time;
  PLL = (uint)((fFrequency * 1000000 + 225000) / 32768 * 4);
	
  TEA5767WriteData[0] = PLL/256;
	TEA5767WriteData[1] = PLL%256;
  TEA5767WriteData[2] = 0xb0; //1001 0000 
  TEA5767WriteData[3] = 0x10; //0001 0000
  TEA5767WriteData[4] = 0x00;    //0000 0000
	
	start();
	write_byte(0xc0);
	responds();
	for(time=0;time<5;time++)
	{
     
	 write_byte(TEA5767WriteData[time]);    
	 responds();
	}
   stop();
}

void TEA5767_init() //5767的初始化函数,85Mhz
{
     
	uint pll,time;
	pll=(uint)((85 * 1000000 + 225000) / 32768 * 4);

	TEA5767_init_date[0]=pll/256;
	TEA5767_init_date[1]=pll%256;
	TEA5767_init_date[2]=0x20;
	TEA5767_init_date[3]=0x11;
	TEA5767_init_date[4]=0x00;
	
	start();
	write_byte(0xc0);//注明接下来写给0xc0时钟芯片
	responds();
		for(time=0;time<5;time++)
	{
     
	 write_byte(TEA5767_init_date[time]);
	 responds();
	}
	 stop();
}


void write_1602_com(uchar com)//写1602指令
{
     
	lcdrs=0; // set writing com
	P0=com; // input value data
	delay1(5);
	lcden=1;
	delay1(5);
	lcden=0;
}

void write_1602_data(uchar date)//写1602数据
{
     
	lcdrs=1; //选择数据
	P0=date; 
	delay1(5);
	lcden=1;
	delay1(5);
	lcden=0;
}

void LED_init()//初始化1602
{
     
	lcden=0;
	write_1602_com(0x38);
	write_1602_com(0x0f);
	write_1602_com(0x06);
	write_1602_com(0x80);
}

void display_1602(float fFrequency)   //显示在第二行 多少频率 
{
     
	uint time;
	uchar uge;
	write_1602_com(0x01);
	write_1602_com(0x80);
		for(time=0;time<13;time++)
	{
     
		write_1602_data(table1[time]);
		delay1(300);
	}
	
	write_1602_com(0x80+0x40);
	if(fFrequency<100.0)
	{
     
		shi=fFrequency/10+0x30;
		uge=(uchar)fFrequency; ge=uge%10+0x30;
		xiao=fFrequency*10/10+0x30;

		write_1602_data(shi);
		delay1(300);
		write_1602_data(ge);
		delay1(300);
		write_1602_data('.');
		delay1(300);
		write_1602_data(xiao);
		delay1(300);
		write_1602_data('H');
		delay1(300);
		write_1602_data('z');
		delay1(300);
	}
	
	if(fFrequency>100.0)
	{
     
		bai=fFrequency/100+0x30;
		shi=fFrequency/10+0x30;
		uge=(uchar)fFrequency; ge=uge%10+0x30;
		xiao=fFrequency*10/10+0x30;
		
		write_1602_data(bai);
		delay1(300);
		write_1602_data(shi);
		delay1(300);
		write_1602_data(ge);
		delay1(300);
		write_1602_data('.');
		delay1(300);
		write_1602_data(xiao);
		delay1(300);
		write_1602_data('H');
		delay1(300);
		write_1602_data('z');
		delay1(300);
	}
}

void main()
{
     
	uint time;
	float fFrequency=85.0;
	LED_init();//液晶初始化
	//液晶上面先写FM TEA5767
	for(time=0;time<13;time++)
	{
     
		write_1602_data(table1[time]);
		delay1(300);
	}
	write_1602_com(0x80+0x40);//重启一行
	
	TEA5767_init();//5767芯片初始化
	for(time=0;time<10;time++)
	{
     
		write_1602_data(table2[time]);
		delay1(300);
	}
	
	while(1)
	{
     
		//向上搜索
		if(key_up==0)
		{
     
			delay1(5);//消抖
			if(key_up==0)
			{
     
				fFrequency=fFrequency+0.1;
				if(fFrequency==108.0)
				{
     
				fFrequency=85.0;
				}
				TEA5767_SetFrequency(fFrequency);
				display_1602(fFrequency);
			}
			while(key_up==0);
		}
		
		//向下搜索
		if(key_down==0)
		{
     
			delay1(5);//消抖
			if(key_down==0)
			{
     
				fFrequency=fFrequency-0.1;
				if(fFrequency==85.0)
				{
     
					fFrequency=108.0;
				}
				TEA5767_SetFrequency(fFrequency);
				display_1602(fFrequency);
			}
			while(key_down==0);
		}
	}
}
  }
}




总结

  1. 对于新手来说可能一开始手头无措,并不知道简单的一个项目从何做起,所以首要的就是确立目标,了解原理,然后寻找芯片,研究芯片工作方式和各项数据,就能够制定电路,最后完成项目

  2. 看芯片手册的时候,尽量看英文版,养成好的习惯,否则以后从事相关事业的时候对中文翻译手册具有太大的依赖性,是个坏习惯。

  3. 看手册的时候一开始看不懂不要紧,先记住一些关键的词,标注出来,因为中文版你也可能看不懂具体是什么意思,通篇浏览之后再回来看,基本上就能够看懂了。


如果有兴趣可点击下方链接查看PCB电路,焊接电路具体过程,一些个人经验。 https://blog.csdn.net/Yizkkkkang/article/details/107490762

你可能感兴趣的:(嵌入式设计,单片机,嵌入式)