|
現在網上很多網友都在做和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);
- }
復制代碼
希望大家可以繼續改進,讓這個東東的功能達到完善。
|
評分
-
查看全部評分
|