找回密碼
 立即注冊

QQ登錄

只需一步,快速開始

搜索
查看: 5851|回復(fù): 0
打印 上一主題 下一主題
收起左側(cè)

請大牛看一下代碼TEA5767+PT2257 收音+音量+串口控制從來沒弄過C別人的基礎(chǔ)上改的

[復(fù)制鏈接]
跳轉(zhuǎn)到指定樓層
樓主
ID:92278 發(fā)表于 2015-10-13 21:14 | 只看該作者 回帖獎勵 |倒序瀏覽 |閱讀模式
/***********************************
硬件:STC12C5A60S2 波特率為9600
************************************/
#include<reg52.h>
#include<intrins.h>
#include <stdio.h>

#define uchar unsigned char
#define uint  unsigned int
#define ulong unsigned long        int

# define  BAUD 9600                   //波特率大小
# define SYS 11059200        //晶振大小
# define x   -(SYS/384/BAUD)        /*波特率轉(zhuǎn)換為定時器初值的公式(注意:這里是因為應(yīng)用了
                                                                補碼的知識所以不用再公式的前面加上256 */
#define max_freq 10800
#define min_freq 870
#define write_order 0xc0
#define read_order 0xc1

uchar data fm_write[5]={0x00,0x00,0x31,0x17,0x00};                  
uchar data fm_read[5]={0,0,0,0,0};
uchar xdata table[4];
uchar i;
ulong xdata freq,PLL,frequency,Volume;
bit flag=1;
uchar count;
bit mode,hisi;

sbit SDA=P3^2;     //定義數(shù)據(jù)線端口
sbit SCL=P3^3;     //定義時鐘線端口
sbit SDA1=P3^4;     //定義數(shù)據(jù)線端口1
sbit SCL1=P3^5;     //定義時鐘線端口1
sbit UP=P0^0;      //手動向上調(diào)臺
sbit DOWN=P0^1;    //手動向下調(diào)臺
sbit WTUP=P0^2;    //向上微調(diào)
sbit WTDOWN=P0^3;  //向下微調(diào)

void delayms(uint ms)
{
  uint i;
  while(ms--)
   {
   for(i=0;i<100;i++);
   }
}


void iic_start()   //總線開始
{ SDA=1;
  SCL=1;
  _nop_();
_nop_();
  _nop_();
  SDA=0;
  _nop_();
_nop_();
  _nop_();
  _nop_();
  _nop_();
  SCL=0;
}

void iic1_start()   //總線開始1
{ SDA1=1;
  SCL1=1;
  _nop_();
_nop_();
  _nop_();
  SDA1=0;
  _nop_();
  _nop_();
  _nop_();
  _nop_();
  _nop_();
  SCL1=0;
}


void iic_stop()//總線結(jié)束
{
SDA=0;
_nop_();
_nop_();
_nop_();
SCL=1;
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
SDA=1;
}

void iic1_stop()//總線結(jié)束
{
SDA1=0;
_nop_();
_nop_();
_nop_();
SCL1=1;
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
SDA1=1;
}


uchar read_8bit()//讀取8bit數(shù)據(jù)
{
        uchar i,dat=0;
for(i=0;i<8;i++)
  { SCL=1;
    dat<<=1;
    dat|=(uchar)SDA;
    SCL=0;
   }
  return(dat);
}


void write_8bit(uchar dat)
{
        uchar i;
  for(i=0;i<8;i++)
   {SDA=(bit)(dat&0x80);
    _nop_();
    _nop_();
     SCL=1;
     _nop_();
     _nop_();
     _nop_();
     SCL=0;
     dat<<=1;
     }
}

void write1_8bit(uchar dat)
{
        uchar i;
  for(i=0;i<8;i++)
   {SDA1=(bit)(dat&0x80);
    _nop_();
    _nop_();
     SCL1=1;
     _nop_();
     _nop_();
     _nop_();
     SCL1=0;
     dat<<=1;
     }
}

void send_ack()//發(fā)送認可位,用于讀取數(shù)據(jù)的認可
{ SDA=0;
   _nop_();
   _nop_();
  _nop_();
   SCL=1;
   _nop_();
   _nop_();
   _nop_();
   _nop_();
  _nop_();
   SCL=0;
}

void send1_ack()//發(fā)送認可位,用于讀取數(shù)據(jù)的認可
{ SDA1=0;
   _nop_();
   _nop_();
  _nop_();
   SCL1=1;
   _nop_();
   _nop_();
   _nop_();
   _nop_();
   _nop_();
   SCL1=0;
}

void send_noack()
{
SDA=1;
_nop_();
_nop_();
_nop_();
SCL=1;
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
SDA=0;
SCL=0;
}

void send1_noack()
{
SDA1=1;
_nop_();
_nop_();
_nop_();
SCL1=1;
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
SDA1=0;
SCL1=0;
}

void iicInit(void)
{
SCL = 0;
iic_stop();
}

void iic1Init(void)
{
SCL1 = 0;
iic1_stop();
}



bit check_ack()//檢測確認位,如果返回值是0表示數(shù)據(jù)傳輸成功
{  
   bit ack_bit;
   SDA=1;
  _nop_();
  _nop_();
  SCL=1;
  _nop_();//在第九個周期內(nèi)單片釋放sda,等待從器件給出一個確認位
  _nop_();
  _nop_();
  _nop_();
  ack_bit=SDA;
   SCL=0;
   return(ack_bit);

}


bit check1_ack()//檢測確認位,如果返回值是0表示數(shù)據(jù)傳輸成功
{  
   bit ack1_bit;
   SDA1=1;
  _nop_();
  _nop_();
  SCL1=1;
  _nop_();//在第九個周期內(nèi)單片釋放sda,等待從器件給出一個確認位
  _nop_();
  _nop_();
  _nop_();
  ack1_bit=SDA1;
   SCL1=0;
   return(ack1_bit);

}

void get_frequency()
{  
        ulong y;
   y=PLL;
   hisi=fm_write[2]&0x10;
    if(hisi)
   freq=(y*8192+225000)/10000;
   else
   freq=(y*8192-225000)/10000 ;
}


void get_pll()
{
ulong freq1,y=frequency;
  freq1=y*100000;
  hisi=fm_write[2]&0x10;
  if(hisi)
  PLL=((freq1+225000)*4)/32768;
  else
  PLL=((freq1-225000)*4)/32768;
}


void read_5byte()
{
uchar i,tempH,tempL;
  iic_start();
   write_8bit(read_order);
   check_ack();
    for(i=0;i<5;i++)
    {fm_read[i]=read_8bit();
     send_ack();
    }
        send_noack();
    iic_stop();
   tempH=fm_read[0];
   tempL=fm_read[1];
   tempH&=0x3f;
   PLL=tempH*256+tempL;
   get_frequency();
}


void write_5byte()
{       
        uchar i;
   iic_start();
   write_8bit(write_order);
   check_ack();
   for(i=0;i<5;i++)
   {
   write_8bit(fm_write[i]);
     check_ack();
    }
  iic_stop();
  _nop_();
  _nop_();
  _nop_();
  _nop_();
  _nop_();

}

void Volume_Write(uchar Vol)
{
        uchar Temp_H,Temp_L;
        Temp_H=(Vol/10)|0xe0;
        Temp_L=(Vol%10)|0xd0;                                                   
    iic1_start();        //雙聲道同時改變,-10dB/Step
    write1_8bit(0x88);            //寫PT2257地址
        if(!check1_ack())
        {
            write1_8bit(Temp_H);
                send1_ack();
                write1_8bit(Temp_L);
                send1_ack();
        }
    iic1_stop();
}

void refurbish_5767()//FM收音芯片數(shù)據(jù)刷新一次
{

get_pll();          //計算PLL,
fm_write[0]=PLL/256;
fm_write[1]=PLL%256;

fm_write[2]=0x31;
fm_write[3]=0x11;
fm_write[4]=0x00;

//if(mode)fm_write[2]|=0x80;//給SUD=1,向上搜索模式
//else fm_write[2]&=0x7f;//給SUD=0,向下搜索模式

write_5byte();
delayms(60);
read_5byte();

}


void hand_search()  //手動搜索電臺子程序
{
      read_5byte();
      refurbish_5767();

}

void wt_search()  //微調(diào)子程序
{
read_5byte();
   if(mode)
   {frequency+=1;
        if(frequency>max_freq)
        frequency=min_freq;
    }
   else
    {frequency-=1;
      if(frequency<min_freq)
         frequency=max_freq;
     }
      refurbish_5767();
}
void Uart_init(void)
{
        SM0=0;
        SM1=1;                   //串口工作方式的設(shè)定
        REN=1;

        ES=1;                   //打開串口中斷

        TMOD=0x20;           //定時器1的工作方式為8為自動重裝

        TH1= x;
        TL1= x;                   //填入初值

        EA = 1;                   //打開中斷總開關(guān)
        ET1 = 0        ;      //禁止定時 ,只用于做波特率發(fā)生器
        TR1 = 1;           //打開定時器1的中斷開關(guān)
}
void send_string(uchar *pl)          //發(fā)送數(shù)據(jù)子函數(shù)          
{
     ES = 0;
         do  
        {
      SBUF = *pl++;
             while(!TI);                           //等待數(shù)據(jù)發(fā)送完
          TI=0 ;
        } while(*pl);                           //直到'\0'的時候結(jié)束
        ES=1;
}
void send_data(unsigned long int dat)
{
        uchar xdata buf[32] ;
        sprintf(buf , "%1.0f",(float) dat);  //通過sprintf函數(shù)把數(shù)據(jù)轉(zhuǎn)換為字符型發(fā)送
        send_string(buf);
}

void Enter()
{
                  ES=0;
                  SBUF = '\r';
                  while(!TI);                           //等待數(shù)據(jù)發(fā)送完
                  TI=0 ;       
                  SBUF = '\n';
                     while(!TI);                           //等待數(shù)據(jù)發(fā)送完
                  TI=0 ;       
                  ES=1;
}


void main(void)
{   
    iicInit();
     iic1Init();
        Uart_init();
    delayms(1000);
        send_string("初始化收音機");
        Enter();
        frequency=1076;       //默認收臺為107.6MHz
        get_pll();             //計算PLL
        refurbish_5767();
        Volume_Write(70);

while(1)
{
        if(flag)
        {
           if(i==4)
            {
                hand_search();
                Enter();
                send_string("當(dāng)前頻率是:");
                send_data(frequency/10);
                send_string(".");
                send_data(frequency%10);
                send_string("MHZ");
                Enter();
                flag=0;
             }
            if(i==1)
             {   
              Volume_Write(Volume);
               Enter();
               send_string("當(dāng)前音量是:");
               send_data(Volume);
               Enter();
               flag=0;
              }
        }

}
}

void Uart(void) interrupt 4 using 1        //串口中斷子函數(shù)
{
        if(1==RI)        //必須進行判斷才可以實現(xiàn)中斷的對應(yīng)響應(yīng)
        {
                RI = 0;
                table[i] = SBUF;
                i++;
                if(i==4)
                {
                        i=0;
            frequency=(table[0]-48)*1000+(table[1]-48)*100+(table[2]-48)*10+(table[3]-48);
                  //frequency=table[0]-48;
                        flag=1;
                }
          if(i==1)
          {
              i=0;
             Volume=table[0]*10+table[1];
                 flag=1;
                 }
        }
}
                 

分享到:  QQ好友和群QQ好友和群 QQ空間QQ空間 騰訊微博騰訊微博 騰訊朋友騰訊朋友
收藏收藏1 分享淘帖 頂 踩
回復(fù)

使用道具 舉報

您需要登錄后才可以回帖 登錄 | 立即注冊

本版積分規(guī)則

小黑屋|51黑電子論壇 |51黑電子論壇6群 QQ 管理員QQ:125739409;技術(shù)交流QQ群281945664

Powered by 單片機教程網(wǎng)

快速回復(fù) 返回頂部 返回列表