|
现在网上很多网友都在做和TEA5767有关的东东,今天找到个MP4的尸体,屏碎了,打开一看刚好有能用的TEA5767,验证了一下这个东西的实用性,用手上刚好有的51单片机开发板和lm386,为这个集成模块搭建了一个测试平台,下面是试验图片,如果在西安的朋友,肯定知道我手的那个电台了,哈哈!
图片一:

这个图可以看到整体结构了,其实硬件电路很简单,看看pdf文档完全可以搭建出来,单片机实验板是以前开发的商品。
图片二:

这一部分是主要部分了,中间上面那个就是拆下来的TEA5767,它右边是LM386,做功率放大的,下面的扬声器是从一个笔记本里边拆下来的(太败家了,衰!)。
下面的程序可以直接运行了,绝对没问题的,这个也是参考了几个网站的程序,做了些修改,可以手动自动调台了,手动调台有问题,算法好像不对,但是出来的频率问题不大,自动搜索的结果是正确的,我要提醒大家一点,自动搜台的效果和接受强度,也就是天线,有很大的关系,我的天线是一截不到15mm的软导线,good luck!
- /***************************************************************************************************
- TEA5767采用I2C接口控制,单片机用AT89S52.晶振11.0592Mhz。采用四位LED显示。
- TEA5767采用I2C接口控制.TEA5767读写数据都是5个字节,其中PLL参数14位. Fosc =11.0592Mhz.
- ****************************************************************************************************/
- #include "regx52.h"
- #include "intrins.h"
- /***********************************************************************************/
- #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 Add_Freq 1
- #define Dec_Freq 0
- #define REFERENCE_FREQ 32.768
- #define ATIIcxxDriverAddressW 0xC0
- #define ATIIcxxDriverAddressR 0xC1
- #define _Nop() _nop_(),_nop_(),_nop_(),_nop_(),_nop_() /*定义空指令*/
- #define LED P0
- void Initialization(void);
- void Get_Pll(void);
- void Get_Frequency(void);
- void Search(unsigned char mode);
- void Auto_Search(unsigned char mode);
- unsigned char GetKey();
- void Delay(unsigned char Time);
- void Led_Display(unsigned long i);
- void DelayD(unsigned char Time);
- unsigned char GetKey();
- void Delay(unsigned char Time);
- void ATIICxx_PWrite(unsigned char *McuAddress,unsigned char count);
- void ATIICxx_PRead(unsigned char *McuAddress,unsigned char count);
- void I2C_Send_Byte(unsigned char sendbyte);
- unsigned char I2C_Receive_Byte(void);
- void I2C_Start(void);
- void I2C_Stop(void);
- void I2C_Ack(void);
- void I2C_Noack(void);
- /*********************************************************************/
- /* IIC读写程序芯片型号*/
- sbit I2C_SCK=P3^0; /*实时时钟时钟线引脚 */
- sbit I2C_SDA=P3^1; /*实时时钟数据线引脚 */
- sbit k1=P1^7;
- sbit k2=P1^6;
- sbit k3=P1^5;
- sbit k4=P1^4;
- /*********************************************************************/
- /************************************************************************/
- sbit ge=P2^3;
- sbit shi=P2^2;
- sbit bai=P2^1;
- sbit qan=P2^0;
- unsigned char tab[]={ 0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90};//共阳
- //0, 1, 2 3 4 5 6 7 8 9
- /************************************************************************/
- unsigned char radio_write_data[5]={0x2d,0x56,0x20,0x11,0x00}; //初始化写入TEA5767的数据(FM89.8Mhz)
- unsigned char radio_read_data[5];
- unsigned int Pll_Data;
- unsigned long Frequency_Data;
- /***********************************************************************************/
- void Initialization(void)
- {
- TMOD = 0x11;
- TH0 = 0x5d;
- TL0 = 0x3d;
- TR0 = 0; //25ms
- TH1 = 0x5d;
- TL1 = 0x3d;
- TR1 = 0; //25ms
- T2CON = 0x30;
- T2MOD = 0x00;
- RCAP2H = 0xFE;
- TH2 = RCAP2H;
- RCAP2L = 0xFB;
- TL2 = RCAP2L;
- TR2 = 0; //2400bps
- PCON = 0x00;
- SCON = 0xD0;
- IP = 0x14;
- EX0 = 1;
- IT0 = 1;
- ET0 = 1;
- EX1 = 1;
- IT1 = 1;
- ES = 0;
- EA = 0;
- }
- /***********************************************************************************/
- //读TEA5767状态,并转换成频率
- void Radio_Read(void)
- {
- unsigned char temp_l,temp_h;
- Pll_Data = 0;
- ATIICxx_PRead(&radio_read_data[0],5);
-
- temp_l = radio_read_data[1];
- temp_h = radio_read_data[0];
- temp_h &= 0x3f;
- Pll_Data = temp_h*256+temp_l;
- Get_Frequency();
- }
- /***********************************************************************************/
- //由PLL计算频率
- void Get_Frequency(void)
- {
- unsigned char hlsi;
- unsigned int npll = 0;
-
- npll = Pll_Data;
- hlsi = radio_read_data[2]&0x10;
- if (hlsi)
- Frequency_Data = (unsigned long)((float)(npll)*(float)REFERENCE_FREQ*(float)0.25-225); //频率单位:KHz
- else
- Frequency_Data = (unsigned long)((float)(npll)*(float)REFERENCE_FREQ*(float)0.25+225); //频率单位:KHz
- }
- /***********************************************************************************/
- //由频率计算PLL
- void Get_Pll(void)
- {
- unsigned char hlsi;
- hlsi = radio_read_data[2]&0x10;
- if (hlsi)
- Pll_Data = (unsigned int)((float)((Frequency_Data+225)*4)/(float)REFERENCE_FREQ); //频率单位:k
- else
- Pll_Data = (unsigned int)((float)((Frequency_Data-225)*4)/(float)REFERENCE_FREQ); //频率单位:k
- }
- /***********************************************************************************/
- //手动设置频率,mode=1,+0.1MHz; mode="0:-0".1MHz ,不用考虑TEA5767用于搜台的相关位:SM,SUD
- void Search(unsigned char mode)
- {
- Radio_Read();
-
- if(mode)
- {
- Frequency_Data += 100;
- if(Frequency_Data > max_freq)
- Frequency_Data = min_freq;
- }
- else
- {
- Frequency_Data -= 100;
- if(Frequency_Data < min_freq)
- Frequency_Data = max_freq;
- }
-
- Get_Pll();
- radio_write_data[0] = Pll_Data/256;
- radio_write_data[1] = Pll_Data%256;
- radio_write_data[2] = 0x41;
- radio_write_data[3] = 0x11;
- radio_write_data[4] = 0x40;
- ATIICxx_PWrite(&radio_write_data[0],5);
- }
- /***********************************************************************************/
- //自动搜台,mode=1,频率增加搜台; mode="0:频率减小搜台".
- void Auto_Search(unsigned char mode)
- {
- Radio_Read();
- Get_Pll();
- if(mode)
- {
- radio_write_data[2] = 0xb1;
- if(Pll_Data > max_pll)
- {
- Pll_Data = min_pll;
- }
- }
- else
- {
- radio_write_data[2] = 0x41;
- if(Pll_Data < min_pll)
- {
- Pll_Data = max_pll;
- }
- }
-
- radio_write_data[0] = Pll_Data/256+0x40;
- radio_write_data[1] = Pll_Data%256;
- radio_write_data[3] = 0x11;
- radio_write_data[4] = 0x40;
- ATIICxx_PWrite(&radio_write_data[0],5);
- Radio_Read();
- while(!(radio_read_data[0]&0x80)) //RF电台就绪标志
- {
- Radio_Read();
- }
- }
- /***********************************************************************************/
- void main(void)
- {
- //0x2d,0x56,0x20,0x11,0x00
- unsigned long temp;
- Initialization();
- radio_write_data[0] =0x2A;
- radio_write_data[1] =0xB6;
- radio_write_data[2] =0x41;
- radio_write_data[3] =0x11;
- radio_write_data[4] =0x40;
- ATIICxx_PWrite(&radio_write_data[0],5);//初始化TEA5767(89.8Mhz)
- Frequency_Data = 89800;
- while(1)
- { temp= Frequency_Data;
- Led_Display(Frequency_Data);
- if( k1 == 0)
- { DelayD(2);
- while(k1 == 0);//等待键松开
- Search(Add_Freq);
- }
- if( k2 == 0)
- { DelayD(2);
- while(k2 == 0);//等待键松开
- Search(Dec_Freq);
- }
- if( k3 == 0)
- { DelayD(2);
- while(k3 == 0);//等待键松开
- Auto_Search(Add_Freq);
- }
- if( k4 == 0)
- { DelayD(2);
- while(k4 == 0);//等待键松开
- Auto_Search(Dec_Freq);
- }
- }
- }
- /*********************************************************************/
- struct bytedata_2
- {
- unsigned char ByteH;
- unsigned char ByteL;
- };
- union int2byte
- {
- unsigned int IntData;
- struct bytedata_2 ByteData;
- };
- /*********************************************************************/
- //启动I2C总线,退出时SCL为低
- void I2C_Start(void)
- {
- I2C_SDA=1; /*发送起始条件的数据信号*/
- _Nop();
- I2C_SCK=1;
- _Nop();_Nop();_Nop();_Nop();_Nop();/*起始条件建立时间大于4.7us,延时*/
- I2C_SDA=0; /*发送起始信号*/
- _Nop();_Nop();_Nop();_Nop();_Nop(); /* 起始条件锁定时间大于4μs*/
- I2C_SCK=0; /*钳住I2C总线,准备发送或接收数据 */
- _Nop();_Nop();_Nop();_Nop();_Nop();/*起始条件建立时间大于4.7us,延时*/
- }
- //*停止I2C总线
- void I2C_Stop(void)
- {
- I2C_SCK=0;
- I2C_SDA=0; /*发送结束条件的数据信号*/
- _Nop(); /*发送结束条件的时钟信号*/
- I2C_SCK=1; /*结束条件建立时间大于4μs*/
- _Nop();_Nop();_Nop();_Nop();_Nop();
- I2C_SDA=1; /*发送I2C总线结束信号*/
- }
- //MCU等待应答位(返回0表示应答)
- bit I2C_WaitAck(void)
- {
- unsigned char ucErrTime = 200; //因故障接收方无ACK,超时值。
- I2C_SCK=0;
- I2C_SDA=1;
- _Nop();
- I2C_SCK=1;
- while(I2C_SDA)
- {
- ucErrTime--;
- if (ucErrTime == 0)
- {
- I2C_Stop();
- return 0;
- }
- }
- I2C_SCK=0;
- return 1;
- }
- //MCU应答信号
- void I2C_Ack(void)
- {
- I2C_SCK=0;
- I2C_SDA=0;
- _Nop();
- _Nop();
- _Nop();
- _Nop();
- _Nop();
- I2C_SCK=1;
- _Nop();
- _Nop();
- _Nop();
- _Nop();
- _Nop();
- I2C_SCK=0;
- }
- //MCU发送非应答信号
- void I2C_Noack(void)
- {
- I2C_SCK=0;
- I2C_SDA=1;
- _Nop();
- _Nop();
- I2C_SCK=1;
- _Nop();
- _Nop();
- I2C_SCK=0;
- }
- void I2C_Send_Byte(unsigned char sendbyte)
- {
- unsigned char i = 8;
- while( i-- )
- {
- I2C_SCK = 0;
- _Nop(); //_Nop();
- if ( sendbyte &0x80 ) I2C_SDA =1;
- else I2C_SDA =0;
- _Nop(); //_Nop();
- I2C_SCK = 1;
- _Nop(); //_Nop();
- sendbyte <<= 1;
- }
- I2C_WaitAck();
- }
- static unsigned char I2C_Receive_Byte(void)
- {
- unsigned char i = 8, data_buffer;
- I2C_SDA = 1;
- while ( i--)
- {
- I2C_SCK =0;
- _Nop();_Nop();
- I2C_SCK =1;
- _Nop();_Nop();
- data_buffer <<= 1;
- if ( I2C_SDA ) data_buffer++;
- }
- return (data_buffer);
- }
- void ATIICxx_PWrite(unsigned char *McuAddress,unsigned char count)
- {
- I2C_Start();
- I2C_Send_Byte( ATIIcxxDriverAddressW );
- while(count--)
- {
- I2C_Send_Byte( *(unsigned char*)McuAddress );
- ((unsigned char*)McuAddress)++;
- }
- I2C_Stop();
- }
- void ATIICxx_PRead(unsigned char *McuAddress,unsigned char count)
- {
- I2C_Start();
- I2C_Send_Byte( ATIIcxxDriverAddressR );
- while(count--)
- {
- *McuAddress = I2C_Receive_Byte();
- I2C_Ack();
- McuAddress++;
- }
- I2C_Noack();
- I2C_Stop();
- }
- void DelayD(unsigned char Time)
- {
- unsigned char i;
-
- while( --Time != 0)
- {
- for(i = 0; i < 125; i++); //i 从0加到125,CPU大概就耗时1 毫秒 。
- }
- }
- /************************************************************************/
- void Led_Display(unsigned long i) //显示函数
- {
- LED = tab[i/100000];
- qan = 0;
- bai = 1;
- shi = 1;
- ge = 1;
- DelayD(3);
- LED = tab[(i%100000)/10000];
- qan = 1;
- bai = 0;
- shi = 1;
- ge = 1;
- DelayD(3);
- LED = tab[((i%100000)%10000)/1000]&0x7f;
- qan = 1;
- bai = 1;
- shi = 0;
- ge = 1;
- DelayD(3);
- LED = tab[(((i%100000)%10000)%1000)/100];
- qan = 1;
- bai = 1;
- shi = 1;
- ge = 0;
- DelayD(3);
- }
复制代码
希望大家可以继续改进,让这个东东的功能达到完善。
|
评分
-
查看全部评分
|