捣鼓TEA5767收音机.docx
《捣鼓TEA5767收音机.docx》由会员分享,可在线阅读,更多相关《捣鼓TEA5767收音机.docx(47页珍藏版)》请在冰豆网上搜索。
捣鼓TEA5767收音机
捣鼓TEA5767
可能好多朋友说一个买收音机也就几块钱,何必花这么大精力鼓捣这个烂玩意,如果真有这个想法的朋友请打住,不要在往下面看了。
之前也一直认为TEA5767较差,实际中发觉选择大厂的模块出来的音频经放大器推动后还是很有震撼力,大大超出我的预期。
不过前提是使用好模块,而不是现在满淘宝卖的那种5-7块左右的那种简装版咯。
TEA5767主要出来的音频没音量控制,也不够推动耳机。
我就外加电子音量调节芯片、小功率放大、调节显示等。
我电子音量选用M62429显示选用了一种非常小尺寸的MINI1602另外使用了手机上那种5向导航键、加了单键开关机电路,小功率放大选用2块TDA2822(3-6V)就是TDA2822这次把我害惨了,PCB出来后所有正常,就是推动2个2W的小喇叭会有那种噗噗声,晕死。
线路输出则很好,在网上一查,发觉很多朋友都有这个问题,现在这个玩意买不到贴片封装的原装进口的,而国产的做BTL方式放大时,由于内部2个放大器的参数国产工艺存在差异较大造成,而做普通双声道放大则不存在这个问题。
唉~~国货呀,你什么时候才能让人放心!
发誓以后再一不会选择使用TDA2822这个垃圾了(需要的朋友我可以送现在看着就恼火)
1、电路图
2、PCB图和尺寸
3、PCB实物
4、之前调试的电路
还是一贯做法,洞洞板加飞线,不要吓着啦~
5、焊接后的样子
因为彻底对TDA2822失望,所以板子上2个TDA2822放大部分就不考虑安装了,下图中是安了其中一只TDA2822的
6、几个主要的元件
A、mini1602显示屏,非常小,这个玩意也少
B、TEA5767
这个玩意版本很多,质量也参差不起,用过3种,这种不错,不是那种简版,当然价格也高了~
C、M62429立体声电子音量芯片
D、按键
电源按键选用4×4×3小巧高质量按键
功能键使用手机上那种小巧的5向摇杆键
E、带通滤波器(BPF)76-108M
F、钽电容
G、mini1602贴片插座
7、工作。
。
使用30多厘米的漆包线绕着圈,加长效果更好
8、功能设计、思路
那个信号强度指示,占用4个字符,其中天线杆符号单独占一个,电平8级指示通过3个字符分割组成,看图应该明白的
9、成本
做了50块PCB,制版打样费摊到6元左右/块PCB
去掉2个TDA2822部分及相关不需要的后实际使用的元件元件值以下面为准
特别注意:
组装时R2电阻0欧姆一定要焊上
10、参考程序和烧写文件
烧写文件:
该文件只允许会员下载登录|注册新用户
内部震荡8M
部分参考程序:
Tea5767.c
#include"Tea5767.h"
#include"TwiLib.h"
//初始化TEA5767
voidTEA5767_Init(ulongFreq,ucharMono)
{
//初始化
TWI_Init();
TEA5767_Adjust(Freq,Mono,TRUE);
}
//调整频率、声道
voidTEA5767_Adjust(ulongFreq,ucharMono,ucharMuteControl)
{
uchardata[5]={0};
ulongpll=TEA5767_GetPLLFromFreq(Freq);
data[0]=(uchar)(pll/256);
data[1]=(uchar)(pll%256);
data[2]=(Mono!
=0)?
0x09:
0x01;
data[3]=0x92;
if(MuteControl)
{
data[0]|=0x80;
TWI_MasterSendBytes(TEA5767_TWI_ADDR,5,data);
data[0]&=0x7f;
DelayMs(500);
}
TWI_MasterSendBytes(TEA5767_TWI_ADDR,5,data);
}
//信号强度
ucharTEA5767_GetLevel()
{
uchardata[5]={0};
TWI_MasterRecvBytes(TEA5767_TWI_ADDR,5,data);
return(data[3]>>4);
}
//由频率计算PLL(频率单位为KHZ)
ulongTEA5767_GetPLLFromFreq(ulongFreq)
{
ulongpll=(ulong)(((Freq-225)*4000)/32768);
returnpll;
}
//由PLL计算频率(频率单位为KHZ)
ulongTEA5767_GetFreqFromPLL(ulongPll)
{
ulongFreq=(ulong)(((float)Pll)*((float)8.192)+225);
returnFreq;
}
Tea5767.h
#ifndef__TEA5767__H__INCLUDED__
#define__TEA5767__H__INCLUDED__
#include"common.h"
//TEA5767的TWI地址
#defineTEA5767_TWI_ADDR0xC0//TEA5767基地址
//初始化TEA5767(频率单位为KHZ)
voidTEA5767_Init(ulongFreq,ucharMono);
//调整频率、声道
voidTEA5767_Adjust(ulongFreq,ucharMono,ucharMuteControl);
//信号强度
ucharTEA5767_GetLevel();
//由频率计算PLL(频率单位为KHZ)
ulongTEA5767_GetPLLFromFreq(ulongFreq);
//由PLL计算频率(频率单位为KHZ)
ulongTEA5767_GetFreqFromPLL(ulongPll);
#endif//__TEA5767__H__INCLUDED__
FM62429.c
#include"FM62429.h"
//初始化函数
voidFM62429_Init(ucharVolume)
{
FM62429_PORT_INIT();
FM62429_AdjustVolume(Volume);
}
//调整音量(0~84)
voidFM62429_AdjustVolume(ucharVolume)
{
uchari=0;
ushortVolData=0;
if(Volume>0)
{
Volume=Volume+3;
VolData=(ushort)(Volume&0x7C);
VolData|=(ushort)((Volume&0x03)<<7);
}
//D9、D10均为1
VolData|=0x600;
FM62429_SDA_L();
FM62429_SCL_L();
for(i=0;i<10;i++)
{
if(VolData&0x01)
FM62429_SDA_H();
else
FM62429_SDA_L();
FM62429_SCL_H();
FM62429_SDA_L();
FM62429_SCL_L();
VolData>>=1;
}
FM62429_SDA_H();
FM62429_SCL_H();
NOP();
FM62429_SCL_L();
}
FM62429.h
#ifndef__FM62429_H_INCLUDED__
#define__FM62429_H_INCLUDED__
#include"Common.h"
//端口定义
#defineFM62429_SDA_H()SET_BIT(PORTB,PB2)
#defineFM62429_SDA_L()CLR_BIT(PORTB,PB2)
#defineFM62429_SCL_H()SET_BIT(PORTB,PB5)
#defineFM62429_SCL_L()CLR_BIT(PORTB,PB5)
#defineFM62429_PORT_INIT()SET_BIT(DDRB,DDB2);SET_BIT(DDRB,DDB5)
//初始化函数
voidFM62429_Init(ucharVolume);
//调整音量(0-83)
voidFM62429_AdjustVolume(ucharVolume);
#endif//__FM62429_H_INCLUDED__
main.c
#include
#include"common.h"
#include"LCD1602.h"
#include"TWILib.h"
#include"Tea5767.h"
#include"FM62429.h"
#defineOPER_MODE_RADIO0//正常收音机模式
#defineOPER_MODE_SET1//设置模式
//正确保存标志
#defineSAVE_MASK0x4B//'K'
//设置模式
#defineSET_MODE_SEARCH1//搜索
#defineSET_MODE_SOUNDMODE2//立体声、单声道模式选中
#defineSET_MODE_MIN1
#defineSET_MODE_MAX2
//声音模式
#defineSOUND_MODE_STEREO1
#defineSOUND_MODE_MONO2
#defineSOUND_MODE_MIN1
#defineSOUND_MODE_MAX2
//音量
#defineVOLUME_MAX84
#defineVOLUME_MIN0
#defineCHANNEL_NUM10
#defineCHANNEL_MIN1
#defineCHANNEL_MAXCHANNEL_NUM
//搜索模式
#defineSTATE_SEARCH1
#defineSTATE_STORE2
//最小频率
#defineFREQ_MIN((ulong)87500)
#defineFREQ_MAX((ulong)120000)
//全局变量
ucharOperMode=OPER_MODE_RADIO;//操作模式
ucharSetMode=SET_MODE_MIN;//搜索频道
ucharSoundMode=SOUND_MODE_MIN;//声音模式
BOOLDoingMenu=FALSE;//是否处于选择菜单方式
ushortBlinkCounter=0;//控制闪烁
ucharVolume=42;//音量
ulongChannelFreq=96600;//频道频率(单位为KHZ)
ulongChannelSearch=FREQ_MIN;//搜索起始频率
ucharChannelIndex=0;//当前播放的频道编号(1-10)
ucharChannelSaveIndex=CHANNEL_MIN;
ucharChannelState=STATE_SEARCH;
//开关健(PD7)
#definePOWER_ON()
#definePOWER_OFF()SET_BIT(DDRD,DDD7);CLR_BIT(PORTD,PD7);
//闪烁控制变量的最大值
#defineBLINK_COUNTER_MAX10
//是否闪烁
#defineIS_BLINK()(BlinkCounter>BLINK_COUNTER_MAX/2)
//======================================================================================================
//预先保持的10个频道
//======================================================================================================
ulongEEMEMChannelConfig[CHANNEL_NUM+1]={0};
ulongChannelArray[CHANNEL_NUM+1]={0};
//读取预先保持的频道
voidReadChannelConfig()
{
ulongdata=0;
ucharmask=0,i=0;
//等待EEPROM空闲
eeprom_busy_wait();
//写入数据
eeprom_read_block(ChannelArray,ChannelConfig,4*(1+CHANNEL_NUM));
//解析第一个字节,构造第一个字节,从地位到高位分别是:
ChannelIndex,Volume,SoundMode,SAVEMASK
data=ChannelArray[0];
ChannelIndex=(uchar)(data&0xFF);
data>>=8;
Volume=(uchar)(data&0xFF);
data>>=8;
SoundMode=(uchar)(data&0xFF);
data>>=8;
mask=(uchar)(data&0xFF);
if((mask!
=SAVE_MASK)||
(ChannelIndexCHANNEL_MAX)||
(SoundModeSOUND_MODE_MAX)||
(Volume>VOLUME_MAX))
{
ChannelIndex=0;
Volume=42;
SoundMode=SOUND_MODE_STEREO;
for(i=0;iChannelArray[i]=0;
}
else
{
ChannelFreq=ChannelArray[ChannelIndex];
}
}
//写设置
voidWriteChannelConfig()
{
//构造第一个字节,构造第一个字节,从低位到高位分别是:
ChannelIndex,Volume,SoundMode,SaveMask
ulongdata=SAVE_MASK;
data<<=8;
data|=SoundMode;
data<<=8;
data|=Volume;
data<<=8;
data|=ChannelIndex;
ChannelArray[0]=data;
//等待EEPROM空闲
eeprom_busy_wait();
//写入数据
eeprom_write_block(ChannelArray,ChannelConfig,4*(1+CHANNEL_NUM));
}
//显示存储频道信息
voidDisplayFreqSave(ucharIndex)
{
uchari=0;
ucharbuffer[17]={0};
//显示音量、声音模式
for(i=0;i<16;i++)buffer[i]='';
buffer[0]='S';
buffer[1]='T';
buffer[2]='O';
buffer[3]='R';
buffer[4]='E';
buffer[5]=':
';
buffer[6]='C';
buffer[7]='H';
buffer[8]=(Index/10)+'0';
buffer[9]=(Index%10)+'0';
LCD1602_Display_String(1,0,buffer);
}
//显示频率信息
voidDisplayFreqInfo(ulongFreq,ucharIndex)
{
uchari=0,j=0;
ulongdata=0;
ucharbuffer[17]={0};
//显示频率
data=Freq/10;
for(i=0;i<16;i++)buffer[i]='';
if(Index<=CHANNEL_MAX)
{
j=3;
buffer[0]=(Index/10)+'0';
buffer[1]=(Index%10)+'0';
}
else
{
j=2;
}
buffer[j+0]='F';
buffer[j+1]='M';
buffer[j+2]=':
';
if(data>9999)
{
data%=100000;
buffer[j+3]=(data/10000)+'0';data%=10000;
buffer[j+4]=(data/1000)+'0';data%=1000;
buffer[j+5]=(data/100)+'0';data%=100;
buffer[j+6]='.';
buffer[j+7]=(data/10)+'0';data%=10;
buffer[j+8]=(data%10)+'0';
buffer[j+9]='M';
buffer[j+10]='H';
buffer[j+11]='Z';
}
else
{
buffer[j+3]=(data/1000)+'0';data%=1000;
buffer[j+4]=(data/100)+'0';data%=100;
buffer[j+5]='.';
buffer[j+6]=(data/10)+'0';data%=10;
buffer[j+7]=(data%10)+'0';
buffer[j+8]='M';
buffer[j+9]='H';
buffer[j+10]='Z';
}
LCD1602_Display_String(2,0,buffer);
}
//=======================================================================
//按键处理
//=======================================================================
//按键S1-S5(PD2-PD7)
//是否为单个键按下
#defineIS_KEY_PRESSED(k)(((k)>0)&&(((k)&((k)-1))==0))
//#defineGET_KEY_CODE()((~PIND)&0x1F)
#defineKEY_CODE(n)(((uchar)1)<<(n))
#defineKEY_S1KEY_CODE(0)
#defineKEY_S2KEY_CODE
(1)
#defineKEY_S3KEY_CODE
(2)
#defineKEY_S4KEY_CODE(3)
#defineKEY_S5KEY_CODE(4)
#defineKEY_S6KEY_CODE(5)
//读取按键
ucharGET_KEY_CODE()
{
ucharkeycode=PIND;
keycode>>=2;
keycode=~keycode;
keycode&=0x3F;//6个键
returnkeycode;
}
//读取按键
ucharGetKey()
{
ucharkey=0;
staticucharlastkey=0;//记录上次的按键
//读取键盘
key=GET_KEY_CODE();
if(!
IS_KEY_PRESSED(key))
{
lastkey=0;
return0;
}
//确定是否新的键按下
if(lastkey==0)
{
lastkey=key;//保存本次扫描结果
DelayMs(10);//去抖处理
key=GET_KEY_CODE();
if(key==lastkey)
{
returnkey;
}
}
return0;
}
//=======================================================================
//设置函数
//=======================================================================
voidSetHandler()
{
ucharkey=0;
//切换闪烁标志
BlinkCounter++;
if(BlinkCounter>BLINK_COUNTER_MAX)
BlinkCounter=0;
//确定是否为选择菜单
if(DoingMenu)
{
key=GetKey();
if(key==KEY_S1)//设置键(确认)
{
DoingMenu=FALSE;//结束菜单选择
if(SetMode==SET_MODE_SOUNDMODE)
S