標(biāo)題:
51單片機+TEA5767+數(shù)碼管的FM收音機制作 電路圖+程序
[打印本頁]
作者:
huxiao
時間:
2015-1-24 15:20
標(biāo)題:
51單片機+TEA5767+數(shù)碼管的FM收音機制作 電路圖+程序
現(xiàn)在網(wǎng)上很多網(wǎng)友都在做和TEA5767有關(guān)的東東,今天找到個MP4的尸體,屏碎了,打開一看剛好有能用的TEA5767,驗證了一下這個東西的實用性,用手上剛好有的51單片機開發(fā)板和lm386,為這個集成模塊搭建了一個測試平臺,下面是試驗圖片,如果在西安的朋友,肯定知道我手的那個電臺了,哈哈!
圖片一:
這個圖可以看到整體結(jié)構(gòu)了,其實硬件電路很簡單,看看pdf文檔完全可以搭建出來,單片機實驗板是以前開發(fā)的商品。
圖片二:
這一部分是主要部分了,中間上面那個就是拆下來的TEA5767,它右邊是LM386,做功率放大的,下面的揚聲器是從一個筆記本里邊拆下來的(太敗家了,衰。。
下面的程序可以直接運行了,絕對沒問題的,這個也是參考了幾個網(wǎng)站的程序,做了些修改,可以手動自動調(diào)臺了,手動調(diào)臺有問題,算法好像不對,但是出來的頻率問題不大,自動搜索的結(jié)果是正確的,我要提醒大家一點,自動搜臺的效果和接受強度,也就是天線,有很大的關(guān)系,我的天線是一截不到15mm的軟導(dǎo)線,good luck!
/***************************************************************************************************
TEA5767采用I2C接口控制,單片機用AT89S52.晶振11.0592Mhz。采用四位LED顯示。
TEA5767采用I2C接口控制.TEA5767讀寫數(shù)據(jù)都是5個字節(jié),其中PLL參數(shù)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; /*實時時鐘數(shù)據(jù)線引腳 */
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的數(shù)據(jù)(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狀態(tài),并轉(zhuǎn)換成頻率
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
}
/***********************************************************************************/
//手動設(shè)置頻率,mode=1,+0.1MHz; mode="0:-0".1MHz ,不用考慮TEA5767用于搜臺的相關(guān)位: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電臺就緒標(biāo)志
{
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; /*發(fā)送起始條件的數(shù)據(jù)信號*/
_Nop();
I2C_SCK=1;
_Nop();_Nop();_Nop();_Nop();_Nop();/*起始條件建立時間大于4.7us,延時*/
I2C_SDA=0; /*發(fā)送起始信號*/
_Nop();_Nop();_Nop();_Nop();_Nop(); /* 起始條件鎖定時間大于4μs*/
I2C_SCK=0; /*鉗住I2C總線,準(zhǔn)備發(fā)送或接收數(shù)據(jù) */
_Nop();_Nop();_Nop();_Nop();_Nop();/*起始條件建立時間大于4.7us,延時*/
}
//*停止I2C總線
void I2C_Stop(void)
{
I2C_SCK=0;
I2C_SDA=0; /*發(fā)送結(jié)束條件的數(shù)據(jù)信號*/
_Nop(); /*發(fā)送結(jié)束條件的時鐘信號*/
I2C_SCK=1; /*結(jié)束條件建立時間大于4μs*/
_Nop();_Nop();_Nop();_Nop();_Nop();
I2C_SDA=1; /*發(fā)送I2C總線結(jié)束信號*/
}
//MCU等待應(yīng)答位(返回0表示應(yīng)答)
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應(yīng)答信號
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發(fā)送非應(yīng)答信號
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) //顯示函數(shù)
{
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);
}
復(fù)制代碼
希望大家可以繼續(xù)改進(jìn),讓這個東東的功能達(dá)到完善。
作者:
daviddavid
時間:
2015-4-7 12:59
看看有作用么??
作者:
wh369258we
時間:
2015-9-27 15:02
樓主這個 ge shi bai qian 數(shù)碼管是怎么接的?
作者:
neemxyang
時間:
2015-11-19 21:50
如何才能讓每次自動調(diào)頻到電臺的頻點時候,停止,然后滴滴兩聲
還能否加上諸如DOLBY降噪的程序呢?
音頻的降噪處理,立體聲如何解析?
如果廣播電臺播出的是5.1聲道的呢?
作者:
zonafrist
時間:
2015-11-24 09:16
謝謝樓主,這回有的折騰啦,哈哈哈
作者:
xxxhim
時間:
2015-11-27 15:30
膜拜!太有才了!西安音樂臺
作者:
新鄉(xiāng)家電維修
時間:
2016-9-25 16:39
wh369258we 發(fā)表于 2015-9-27 15:02
**** 作者被禁止或刪除 內(nèi)容自動屏蔽 ****
sbit ge=P2^3;
sbit shi=P2^2;
sbit bai=P2^1;
sbit qan=P2^0;程序有說明的
作者:
leaf1225
時間:
2016-12-21 19:38
你好,我想請問一下,是一定需要功率放大模塊(比如lm386)嗎?
作者:
jialishoushi
時間:
2017-4-25 00:28
樓主搞得不錯哇
作者:
都市郎
時間:
2018-1-7 23:08
感謝樓主,這是我需要的
作者:
都市郎
時間:
2018-1-7 23:15
樓主把圖紙也發(fā)上來,我也想試下
作者:
liuzclzc
時間:
2018-1-21 22:26
這個代碼就非常好的。
作者:
ekaiyuan
時間:
2020-2-24 19:38
感謝分享啦,謝謝樓主
作者:
wengjiamin
時間:
2021-1-9 09:02
你好,我想請問一下,是一定需要功率放大模塊(比如lm386)嗎? 是的
歡迎光臨 (http://www.torrancerestoration.com/bbs/)
Powered by Discuz! X3.1