一乐电子

一乐电子百科

 找回密码
 请使用微信账号登录和注册会员

QQ登录

只需一步,快速开始

快捷登录

手机号码,快捷登录

搜索
123
返回列表 发新帖
楼主: LBQ691477940
收起左侧

[其他综合] TEA5767数码管显示调频收音机

  [复制链接]
发表于 2017-2-1 09:17 | 显示全部楼层
本帖最后由 钟义亭 于 2017-2-1 14:31 编辑

3.png

1.png 2.png


/**********************************************************************************************
       AT89S52+12MHZ+TEA5767的數碼管顯示調頻收音機
本程序使用數碼管顯示頻率  晶振是用12M  已通過測試,收音機的頻率調節是用計算的方法  將顯示的頻率算好後寫到TEA5767
芯片裡面實現調節的  兩個按鍵實現自加或自減頻率  加了連續加減功能!
使用的是在淘寶上買的4.5元/片的簡化版的TEA5767模塊.
                    2012-05-08
/*****************************************************************************************/
#include  < reg51.h >
#define uchar unsigned char
#define uint unsigned int  
/*********************************************************************************************/      
sbit SDA = P3^0;  //接在TEA5767的數據端口
sbit SCL = P3^1;  //接在TEA5767的時鐘端口      
sbit KEY1 = P3^4;  //頻率增加按鍵端口     
sbit KEY2 = P3^5;  //頻率減小按鍵端口
sbit KEY3 = P3^6;  //頻率增加按鍵端口     
sbit KEY4 = P3^7;  //頻率減小按鍵端口      
#define duan P0   //頻率顯示的數碼管段選P0端口   
//#define gy   //使用共陰極時屏蔽這行
sbit dula=P2^6;
sbit wela=P2^7;
uchar IF,ADC,CH;
//bit  RF,STEREO;
#ifdef gy
unsigned char code dispbit[]={0x01,0x02,0x04,0x08,0x10,0x20,0x40,0x80};//顯示位碼
unsigned char code dispcode[]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90,0xff};//數碼管顯示編碼
#else
/****************************************************************************************/
unsigned char code dispcode[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0x00}; //數碼管顯示編碼         
unsigned char code dispbit[]={0x7e,0x7d,0x7b,0x77,0x6f,0x5f};/*定義點亮的數碼管與數組的關係*/
#endif
/***************************************************************************************
unsigned char radio_write_data[5] = {0x2c,0xe1,0x70,0x16,0x80}; //頻率為93.9MHz  廣東音樂電台
unsigned char radio_write_data[5] = {0x30,0x5c,0x70,0x16,0x80}; //頻率為101.2MHz 廣東電台音樂之聲
unsigned char radio_write_data[5] = {0x31,0x38,0x70,0x16,0x80}; //頻率為103.0MHz 廣東珠江經濟電台
unsigned char radio_write_data[5] = {0x31,0xd7,0x70,0x16,0x80}; //頻率為104.3MHz 寶安廣播電台
unsigned char radio_write_data[5] = {0x32,0x20,0x70,0x16,0x80}; //頻率為104.9MHz 中央人民廣播電台華夏之聲
unsigned char radio_write_data[5] = {0x33,0x2d,0x70,0x16,0x80}; //頻率為107.1MHz 中國國際廣播電台環球資訊
/*****************************************************************************************/
unsigned char radio_read_data[5];
unsigned char radio_write_data[5];
unsigned long frequency = 104900; //開機初始化的電台頻率為104.9MHz中央民廣播電台華夏之聲
unsigned int PLL;     //計算頻率合成時用的變量
/****************************************************************************************/
void Delayus(unsigned char x)
{
for(;x > 0;x--);
}
/*****************************************************************************************/
void iic_start()  //啟動總線傳輸
{
SDA = 1;
Delayus(4);
SCL = 1;
Delayus(4);
SDA = 0;
Delayus(4);
SCL = 0;
Delayus(4);
}
/**********************************************************************************************/
void iic_stop()  //結束總線傳輸
{
SCL = 0;
Delayus(4);
SDA = 0;
Delayus(4);
SCL = 1;
Delayus(4);
SDA = 1;
Delayus(4);
}
/********************************************************************************************/
void iic_ack()  //發送應答位
{
SDA = 0;
Delayus(4);
SCL = 1;
Delayus(4);
SCL = 0;
Delayus(4);
SDA = 1;
Delayus(4);
}
/****************************************************************************************/
bit iic_testack()
{
bit ErrorBit;
SDA = 1;
Delayus(4);
SCL = 1;
Delayus(4);
ErrorBit = SDA;
Delayus(4);
SCL = 0;
return ErrorBit;
}
/*********************************************************************************************/
void iic_write8bit(unsigned char input) //寫一個字節的數據到總線上
{
unsigned char temp;
for(temp = 8;temp > 0;temp--)
{
  SDA = (bit)(input & 0x80);
  Delayus(4);
  SCL = 1;
  Delayus(4);
  SCL = 0;
  Delayus(4);
  input = input << 1;
}
}
/*********************************************************************************************/
uchar iic_rdbyt() //從總線上讀取一個字節的數據
{
uchar a = 0,i = 0;
for(i = 0;i < 8;i++)
{
  SDA = 1;
  SCL = 1;
  if(SDA == 1)
  {
   a = (a << 1) + 1;
   SCL = 0;
  }
  else if(SDA == 0)
  {
   a = a << 1;
   SCL = 0;
  }
}
return(a);
}
/***********************************************************************************/
void delays (unsigned char b) //按鍵消抖用的延時程序
{
unsigned char i;
for(b;b > 0;b--)
for(i = 0;i < 250;i++);
}
/**************************************************************************************/
void radio_write(void) //寫入TEA5767
{
unsigned char i;
iic_start(); //啟動總線傳輸
iic_write8bit(0xc0);        //TEA5767寫地址
if(!iic_testack())
{
  for(i = 0;i < 5;i++)
  {
   iic_write8bit(radio_write_data); //寫一個字節的數據到總線上
   iic_ack();   //發送應答位
  }
}
iic_stop();  //結束總線傳輸     
}
/**************************************************************************************/
//將顯示的頻率算好後寫到TEA5767芯片裡面實現調節,不用考慮TEA5767用於搜台的相關位:SM,SUD
//寫模式
//數據字節1 數據字節2 數據字節3 數據字節4 數據字節5
void search()
{        
PLL = (unsigned int)((float)((frequency + 225)) / (float)8.192);    //計算合成頻率數據  頻率單位:k
/*********************************************************************************************/
//數據字節1的格式 radio_write_data[0]
//位7(高位)  位6  位5  位4  位3  位2  位1  位0(低位)
// MUTE   SM   PLL13  PLL12  PLL11 PLL10  PLL9   PLL8
//7 MUTE 如果MUTE=1  則左右聲道被靜音;MUTE=0  左右聲道正常工作。
//6 SM   如果SM=1  則處於搜索模式  SM=0  不處於搜索模式。
//5到0   PLL[13:8] 設定用於搜索和預設的可編程頻率合成器。
radio_write_data[0] = PLL / 256; //將算好的頻率高位數據存入將要TEA5767的數組裡
/************************************************************************************************/
//數據字節2的格式 radio_write_data[1]
//位7(高位)  位6  位5  位4  位3  位2  位1  位0(低位)
// PLL7   PLL6  PLL5  PLL4  PLL3  PLL2  PLL1   PLL0
//PLL[7:0] 設定用於搜索和預設的可編程頻率合成器。
radio_write_data[1] = PLL % 256; //將算好的頻率低位數據存入將要TEA5767的數組裡
/***********************************************************************************************/
//數據字節3的格式 radio_write_data[2]
//位7(高位) 位6  位5  位4  位3  位2  位1  位0(低位)
// SUD   SSL1  SSL0  HLSI  MS   ML   MR     SWP1
//SUD SUD=1 增加頻率搜索  SUD=0  減小頻率搜索。
//SLL[1:0] 搜索停止標準:見下表1。
//SSL0 SSL1 搜索停止標準
// 0    0   在搜索模式下禁止  
// 0    1   低:ADC輸出大小為5
// 1    0   中:ADC輸出大小為7
// 1    1   高:ADC輸出大小為10
//HLSI 高/低充電電流切換:HLSI=1  高充電電流   HLSI=0  低充電電流。
//MS 立體聲/單聲道:MS=1  單聲道  MS=0  立體聲。
//ML 左聲道靜音:ML=1  左聲道靜音並置立體聲  ML=0  左聲道正常。
//MR 右聲道靜音:MR=1  右聲道靜音並置立體聲  MR=0  右聲道正常。
//SWP1 軟件可編程端口1:SWP1=1  端口1高電平  SWP1=0  端口1低電平。
radio_write_data[2] = 0x70;   //這是TEA5767開立體聲  關靜音
/******************************************************************************************/
//數據字節4的各個位描述  radio_write_data[3]
//位7(高位) 位6  位5  位4  位3  位2  位1  位0(低位)
// SWP2  STBY  BL  XTAL  SMUTE  HCC  SNC     SI
//SWP2 軟件可編程端口2:SWP2=1,端口2高電平;SWP2=0,端口2低電平。
//STBY 等待:STBY=1  處於待機模式,STBY=0,退出待機模式。
//BL 波段制式:BL=1  日本調頻制式  BL=0,美國/歐洲調頻制式。
//XTAL 如果XTAL=1  那麼fxtal=32.768KHz;如果XTAL=0  那麼fxtal=13MHz。
//SMUTE 軟件靜音:SMUTE=1  軟靜音打開;SMUTE=0,軟靜音關閉。
//HCC 白電平切割:HCC=1  高電平切割打開  HCC=0  高電平切割關閉。
//SNC 立體聲噪聲去除:如果SNC=1,立體聲消噪除打開,如果SNC=0,立體聲消噪除關閉。
//SI 搜索標誌位:SI=1  SWPORT1輸出準備好信號   SI=0  SWPORT1作為軟件可編程端口1用。
radio_write_data[3] = 0x16;   //中國制式  採用32768晶振  軟靜音關  立體聲消噪聲開
/*****************************************************************************************/
//數據字節5的格式 radio_write_data[4]
//位7(高位)  位6  位5  位4  位3  位2  位1  位0(低位)
// PLLREF   DTC  --    --    --  --   --    --
//若PLLREF=1  6.5MHz的鎖相環參考頻率啟用;若PLLREF=0  6.5MHz的鎖相環參考頻率關閉。
//若DTC=1  去加重時間常數為75us;若DTC=0  去加重時間常數為50us。
//位5到0  未用  狀態不必考慮。
radio_write_data[4] = 0x80;   //6.5M鎖相環開  去加重時間50US
/******************************************************************************************/
radio_write();      //寫入TEA5767
}
/********************************************************************************************
//讀模式
//數據字節1 數據字節2 數據字節3 數據字節4 數據字節5
//數據字節1的格式
//位7(高位)  位6   位5   位4   位3   位2  位1   位0(低位)
// RF    BLF  PLL13  PLL12  PLL11  PLL10  PLL9   PLL8
//7 RF 準備好標誌:RF=1  有一個頻道被搜到或者一個制式已經符合;RF=0  沒有頻道被搜到。
//6 BLF 波段制式:BLF=1  一個制式已經符合   BLF=0  沒有制式已經符合。
//5到0 PLL[13:8] 用於搜索和預設後的可編程頻率合成器設定結果。
//數據字節2的格式
//位7(高位)   位6   位5   位4   位3   位2   位1  位0(低位)
// PLL7   PLL6  PLL5  PLL4  PLL3  PLL2  PLL1   PLL0
//數據字節2的各個位描述
//PLL[7:0] 設定用於搜索和預設後的可編程頻率合成器設定結果。
//數據字節3的格式
//位7(高位)  位6  位5   位4  位3  位2  位1  位0(低位)
// STEREO   IF6  IF5  IF4  IF3  IF2  IF1   IF0
//7 STEREO 立體聲標誌位:STEREO=1  立體聲接收  STEREO=0  單聲道接收。
//6到0 IF[6:0] 中頻計數器結果。
//數據字節4的格式
//位7(高位) 位6  位5  位4  位3  位2  位1  位0(低位)
// LEV3   LEV2  LEV1  LEV0  CI3  CI2  CI1   0
//7到4 LEV[3:0] ADC的輸出。
//3到1 CI[3:1] 芯片驗證號。
//0 ------ 該位內部置0。
//數據字節5的格式
//位7(高位)  位6  位5  位4  位3  位2  位1  位0(低位)
//   0    0    0    0    0    0    0    0
//7到0 ------ 預留為擴展用  由內部置0。
/*******************************************************************************************/
void delay()
{
uchar k;
for(k = 0;k < 100;k++);
}
/*****************************************************************************************/
void desplay(uint aa)
{
/*****************************************************************************************
duan = tab[aa / 1000] | 0x80;  //關這位數碼管的小數點
led1 = 0;
delay();
led1 = 1;
duan = tab[aa % 1000 / 100] | 0x80;  //關這位數碼管的小數點
led2 = 0;
delay();
led2 = 1;
duan = tab[aa % 100 / 10] & 0x7f; //點亮這位數碼管的小數點
led3 = 0;
delay();
led3 = 1;
duan = tab[aa % 10] | 0x80;  //關這位數碼管的小數點
led4 = 0;
delay();
led4 = 1;
/*************************************************************************************************/
dula = 0;
if((aa / 1000) == 0)
duan = dispcode[aa / 1000 + 10]; //這位為0數碼管不顯示
else
duan = dispcode[aa / 1000];   //這位數碼管顯示頻率百位
dula = 1;
dula = 0;
wela = 0;
duan = dispbit[2];
wela = 1;
wela = 0;
delay();
delay();
delay();
delay();
delay();
delay();
dula = 0;

duan = dispcode[aa % 1000 / 100];  //這位數碼管顯示頻率十位
dula = 1;
dula = 0;
wela = 0;
duan = dispbit[3];
wela = 1;
wela = 0;
delay();
delay();
delay();
delay();
delay();
delay();
dula = 0;
#ifdef gy
duan = dispcode[aa % 100 / 10] & 0x7F;  //這位數碼管顯示頻率百位  開數碼管的小數點
#else
duan = dispcode[aa % 100 / 10] | 0x80;  //這位數碼管顯示頻率百位  開數碼管的小數點
#endif
dula = 1;
dula = 0;
wela = 0;
duan = dispbit[4];
wela = 1;
wela = 0;
delay();
delay();
delay();
delay();
delay();
delay();
dula = 0;

duan = dispcode[aa % 10];  //這位數碼管顯示頻率小數位
dula = 1;
dula = 0;
wela = 0;
duan = dispbit[5];
wela = 1;
wela = 0;
delay();
delay();
delay();
delay();
delay();
delay();
}
/******************************************************************************************/
//由頻率計算PLL
void get_pll(void)
{
    unsigned char hlsi;
    unsigned int twpll = 0;
    hlsi = radio_write_data[2] & 0x10;
    if (hlsi)
  PLL = (unsigned int)((float)((frequency + 225) * 4) / (float)32.768);    //頻率單位:k
    else
        PLL = (unsigned int)((float)((frequency - 225) * 4) / (float)32.768);    //頻率單位:k
}
/*********************************************************************************************/
//由PLL計算頻率
void get_frequency(void)//讀TEA5767狀態,並轉換成頻率
{
    unsigned char hlsi;
    unsigned int npll = 0;
    npll = PLL;
    hlsi = radio_write_data[2] & 0x10;
    if (hlsi)
        frequency = (unsigned long)((float)(npll) * (float)8.192 - 225);    //頻率單位:KHz
    else
        frequency = (unsigned long)((float)(npll) * (float)8.192 + 225);    //頻率單位:KHz
}
/****************************************************************************************/
//讀TEA5767狀態,並轉換成頻率
void radio_read(void)//讀收音機芯片數據
{
    unsigned char i;
    unsigned char temp_l,temp_h;
    PLL = 0;
iic_stop();  //結束總線傳輸
    iic_start(); //啟動總線傳輸
    iic_write8bit(0xc1);        //TEA5767寫地址
    if(!iic_testack())
    {
        for(i = 0;i < 5;i++)
        {
            radio_read_data = iic_rdbyt();//從總線上讀取一個字節的數據
            iic_ack();  //發送應答位
        }
    }
    iic_stop();  //結束總線傳輸
//RF = radio_read_data[0] & 0x80;
IF = radio_read_data[2] & 0x7f;  //去掉最高位就是IF值
ADC = radio_read_data[3]; //去掉最高位就是IF值
ADC >>= 4;
//STEREO = radio_read_data[2] & 0x80; //最高位就是STEREO值
    temp_l = radio_read_data[1];
    temp_h = radio_read_data[0];
    temp_h &= 0x3f;
    PLL = temp_h * 256 + temp_l;
    get_frequency(); //讀TEA5767狀態,並轉換成頻率
}
/*******************************************************************************************/
#define max_freq 108000
#define min_freq 87500
//自動搜台,mode=1,頻率增加搜台; mode=0:頻率減小搜台
void auto_search(uchar dec)
{
int k = 0;
//unsigned char aa[6] = {0};
radio_write();//寫收音機芯片數據
if(dec)//自動搜台,mode=1,頻率增加搜台
{
  while(frequency < max_freq)//如果當前頻率小於最大頻率上限值
  {   
   get_pll();//由頻率計算PLL
   radio_write_data[0] = PLL / 256;
   radio_write_data[1] = PLL % 256;
   radio_write_data[2] = 0xA0;  //增加頻率搜索,低:ADC輸出大小為5,高充電電流
   radio_write_data[3] = 0x11;  //fxtal=32.768KHz,軟件靜音開
   radio_write_data[4] = 0x80;  //6.5MHz的鎖相環參考頻率開,去加重時間常數為50us。
   radio_write_data[0] |= 0x40; //0100 0000 = SM / SM=1  則處於搜索模式
   radio_write();      //寫入TEA5767
   desplay(frequency / 100);   //調用顯示
   radio_read();     //讀收音機芯片數據
   //if((radio_read_data[0] & 0x80))//如果有一個頻道被搜到或者一個制式已經符合
   if((IF < 0x3e) && (IF > 0x31) && (ADC > 4))//&&(STEREO)&&(RF))//如搜到電台
   {
    frequency += 100;
    return;
   }
  }
  frequency = min_freq;//將最小頻率下限值賦給當前頻率
}
else//自動搜台, mode=0:頻率減小搜台
{
  while(frequency > min_freq)//如果當前頻率大於最小頻率下限值
  {   
   get_pll();//由頻率計算PLL
   radio_write_data[0] = PLL / 256;
   radio_write_data[1] = PLL % 256;
   radio_write_data[2] = 0x20;  //減小頻率搜索,低:ADC輸出大小為5,高充電電流
   radio_write_data[3] = 0x11;  //fxtal=32.768KHz,軟件靜音開
   radio_write_data[4] = 0x80;  //6.5MHz的鎖相環參考頻率開,去加重時間常數為50us。
   radio_write_data[0] |= 0x40; //0100 0000 = SM / SM=1  則處於搜索模式
   radio_write();      //寫入TEA5767  
   desplay(frequency / 100);   //調用顯示
   radio_read();//讀收音機芯片數據
   //if((radio_read_data[0] & 0x80))//如果有一個頻道被搜到或者一個制式已經符合
   if((IF < 0x3e) && (IF > 0x31) && (ADC > 4))//&&(STEREO)&&(RF))//如搜到電台
   {
    frequency -= 100;
    return;
   }
  }
  frequency = max_freq;//將最大頻率上限值賦給當前頻率
}
}
/*****************************************************************************************/
void main()
{
/************************************************************************************************
//觀察變量用
unsigned char B,D;
frequency = 104900;
PLL = (unsigned int)((float)((frequency + 225)) / (float)8.192);
B = PLL/256;
D = PLL % 256;
delay();
/***************************************************************************************************/
delays(1000); //延時消抖
search();  //寫入初始化電台頻率
//radio_read();
while(1)
{
  if(!KEY1)  //手動設置頻率, + 0.1MHz;
  {
   delays(250); //延時消抖
   frequency += 100;
   if(frequency > 108500)  //頻率如果大於108.5MHz
   frequency = 87500;   //頻率設定為87.5MHz
   search();     //將顯示的頻率算好後寫到TEA5767芯片裡面
   desplay(frequency / 100);   //調用顯示
  }
/*************************************************************************************************/
  if(!KEY2)   //手動設置頻率,-0.1MHz;
  {
   delays(20); //延時消抖
   frequency -=100;
   if(frequency < 87500)  //頻率如果小於87.5MHz
   frequency = 108500;   //頻率設定為108.5MHz
   search();     //將顯示的頻率算好後寫到TEA5767芯片裡面
   desplay(frequency / 100);   //調用顯示
  }
/*************************************************************************************************/
  if(!KEY3)   //加頻率
  {
   delays(250); //延時消抖
   if(!KEY3)
   {
     auto_search(1);//自動搜台,mode=1,頻率增加搜台
   }
   while(!KEY3) desplay(frequency / 100);//調用顯示
  }
/****************************************************************************************************/
  if(!KEY4)    //減頻率
  {
   delays(20); //延時消抖
   if(!KEY4)
   {
     auto_search(0);//自動搜台mode=0:頻率減小搜台
   }
   while(!KEY4) desplay(frequency / 100);//調用顯示
  }
  desplay(frequency / 100);    //調用顯示
}
}
/****************************************************************************************************/


作業系統 用繁體  轉出的 簡體碼
用 簡體 OS  ,  就會 亂碼
我的簡體OS  ,  跟你的 不太一樣
繁簡亂碼  看多了

1.png

有的 WINXP 版本 ,  這軟體 有時就會 亂碼
要打 繁體  ,  有的版本  還要裝 繁體字插件
我是用 新注音


1.png

TEA5767-FM.rar (117.42 KB, 下载次数: 72)


1.png

本收音机的频率调节 是用计算的方法,
将显示的频率算好后 写到TEA5767芯片里面 实现调节的
使用 MCS-51单片机进行控制









评分

参与人数 6一乐金币 -220 收起 理由
FJXM-P -30
junyee -40
美人鱼999 -30
384065902 -40
zhqsoft -40 很给力!
snoopy8008 -40

查看全部评分

发表于 2017-2-1 11:13 | 显示全部楼层
本帖最后由 Joe_Black 于 2017-2-1 11:15 编辑

楼主,请用档案把程式贴出来吧!
坛系统会把贴出来的,加上白色垃圾字,防止别人拷贝,转载去其他地方。
发表于 2017-7-21 22:21 | 显示全部楼层
谢谢楼主分享,正好用到。
发表于 2018-2-14 11:34 | 显示全部楼层
谢谢分享!!!

本版积分规则

QQ|一淘宝店|手机版|商店|电子DIY套件|一乐电子 ( 粤ICP备09076165号 ) 公安备案粤公网安备 44522102000183号

GMT+8, 2024-5-1 07:38 , Processed in 0.048950 second(s), 29 queries , Gzip On.

Powered by Discuz! X3.4

Copyright © 2001-2021, Tencent Cloud.

快速回复 返回顶部 返回列表