|
在網上看到關于這個SI4730的收音機芯片的資料比較少,所以現在特發上來,共有緣人參考,
如有不對之處,請指出。!!
由于時間倉促,自動搜臺就沒有編寫,望有緣人寫好后發上來分享。!!!!
晶振:24MHz
單片機:at89s52
注:轉載請注明出處,否則追究法律責任!!!
日期:2010-03-06
版本:v1.0
設計者:sws
*/
#include"reg52.h"
#include"intrins.h"
typedef unsigned char uchar;
typedef unsigned int uint;
#define HIGH 1
#define LOW 0
#define SI4730_HIGH //4730選擇地址定義
//#define SI4730_LOW
#define Max_freq_FM 10800 //108MHz
#define Min_freq_FM 8750 //87.5MHz
#define max_freq_AM 1701 //1701KHz
#define min_freq_AM 531
#define FM_RECEIVER 0x20 //FM調諧頻率 page.52
#define FM_TRNSMITTER 0x30
#define AM_RECEIVER 0x40 //AM調諧頻率
#define TX_TUNE_MEASURE 0x32
uint Frequency_fm=875;
uint Frequency_am=531;
bit Mode = 0;
sbit KEY_UP = P2^2; //向上搜臺
sbit KEY_DW = P2^3; //向下搜臺
sbit FM_AM_Choose = P2^4; //FM與AM選擇
bit FM_AM_ = 0;
/******************************************************
START condition:
SCLK: -----------|______
SDIO:-----|_____________
1 | 2 | 3
STOP condition:
SCLK: ____|--------------
SDIO:____________|-------
1 | 2 | 3
DATA:
SCLK:_______________|---|________|----|_______
SDIO:___________|------------|____________|----
|<==========>|
RESET:
SENB:__|---------------------------------------------
SDIO:_________________________________________|------
RST: ___________|------------------------------------
SCLK:__|---------------------------------------------
| 1 | 2 | 3
******************************************************/
sbit Si4730_Reset = P1^3;
sbit Si4730_SCLK = P1^2;
sbit Si4730_SDIO = P1^1;
//如果SI4730的第六腳(SEN)接高電平那么地址是0x23,0x22
//如果SI4730的第六腳(SEN)接低電平那么地址是0xc7,0xc6
//#if 0 //address switch
#ifdef SI4730_LOW
#define READ_ADDR 0x23
#define WRITE_ADDR 0x22
#endif
#ifdef SI4730_HIGH
#define READ_ADDR 0xc7
#define WRITE_ADDR 0xc6
#endif
#define SCLK_HIGH Si4730_SCLK = HIGH
#define SCLK_LOW Si4730_SCLK = LOW
#define SDIO_HIGH Si4730_SDIO = HIGH
#define SDIO_LOW Si4730_SDIO = LOW
#define READ_SDIO Si4730_SDIO
//===============FM START===================
void _NOP()
{
_nop_();_nop_();
_nop_();_nop_();
_nop_();_nop_();
}
void Si4730_Delay(unsigned char k)
{
uchar i,j;
for(i=150;i>0;i--)
for(j=k;j>0;j--);
}
#define I2C_CLK_Delay() _NOP()
void ResetSi47XX_2w()
{
Si4730_Reset = LOW;
SCLK_HIGH;
Si4730_Delay(100);
SDIO_HIGH;
Si4730_Delay(250);
Si4730_Reset = HIGH;
}
void Si4730_start()
{
SDIO_HIGH;
I2C_CLK_Delay();
SCLK_HIGH;
I2C_CLK_Delay();
SDIO_LOW;
I2C_CLK_Delay();
SCLK_LOW;
}
void Si4730_ack()
{
SDIO_LOW;
I2C_CLK_Delay();
SCLK_HIGH;
I2C_CLK_Delay();
SCLK_LOW;
I2C_CLK_Delay();
SDIO_HIGH;
}
void Si4730_stop()
{
SDIO_LOW;
I2C_CLK_Delay();
SCLK_HIGH;
I2C_CLK_Delay();
SDIO_HIGH;
I2C_CLK_Delay();
SCLK_LOW;
}
void Si4730_writebyte(uchar write_data)
{
uchar i;
for(i=8;i!=0;i--) // 循環移入8個位
{
READ_SDIO = (bit)(write_data & 0x80);
SCLK_HIGH;
I2C_CLK_Delay();
SCLK_LOW; //SDA數據線上數據變化
write_data <<= 1; //調整發送位
}
}
void Operation_Si4730_Write(uchar *data1,uchar numByte)
{
uchar j;
Si4730_start();
Si4730_writebyte(WRITE_ADDR);//器件地址 0xc6
Si4730_ack();
I2C_CLK_Delay();
for(j=LOW;j<numByte;j++,*data1++)
{
Si4730_writebyte(*data1);
Si4730_ack();
I2C_CLK_Delay();
}
Si4730_stop(); //發送結束
}
void Si4730_Power_Up_FM_AM_Choose(unsigned char mod) //fm,am選擇
{
unsigned char write_buf[3]={0x01,0xd0,0x05};
switch(mod)
{
case FM_RECEIVER: //si4730
write_buf[1] = 0xd0; //使用時鐘晶振,32.768khz ,FM模式
write_buf[2] = 0x05; //模擬L/R輸出
break;
case AM_RECEIVER: //si4730
write_buf[1] = 0xd1; //使用時鐘晶振,32.768khz ,AM模式
write_buf[2] = 0x05; //模擬L/R輸出
break;
}
Operation_Si4730_Write(&(write_buf[0]), 3);//need wait >=300mS
Si4730_Delay(250);
Si4730_Delay(250);
Si4730_Delay(120);
}
void Si4730_Tune(char mod,unsigned short Channel_Freq)
{
unsigned char write_buf[5];
write_buf[0]= mod;
write_buf[1]= 0x00;
write_buf[2] = Channel_Freq >> 8; //寫入高字節
write_buf[3] = Channel_Freq; //寫入低字節
write_buf[4]= 0x00;
Operation_Si4730_Write(&(write_buf[0]), 5);
}
void Search_FM() //調用手動FM 頻率調整子程序 menu = 15
{
if(Mode)
{
Frequency_fm += 10; //步進+0.1MHz
if(Frequency_fm > Max_freq_FM)
Frequency_fm = Min_freq_FM;
}
else
{
Frequency_fm -= 10; //步進-0.1MHz
if(Frequency_fm < Min_freq_FM)
Frequency_fm = Max_freq_FM;
}
// Si4730_Power_Up(FM_RECEIVER); //向上搜臺
Si4730_Tune(FM_RECEIVER,Frequency_fm); //FM收音芯片數據刷新一次
}
//=================fm end============
//===============am start==============
void Si4730_Tune_AM(char mod,unsigned short Channel_Freq)
{
unsigned char write_buf[6];
write_buf[0]= mod;
write_buf[1]= 0x00;
write_buf[2] = Channel_Freq >> 8; //寫入高字節
write_buf[3] = Channel_Freq; //寫入低字節
write_buf[4]= 0x00;
write_buf[5]= 0x00;
Operation_Si4730_Write(&(write_buf[0]), 6);
}
void Search_AM() //調用手動FM 頻率調整子程序 menu = 95
{
if(Mode)
{
Frequency_am += 9; //步進+9KHz
if(Frequency_am > max_freq_AM)
Frequency_am = min_freq_AM;
}
else
{
Frequency_am -= 9; //步進-9KHz
if(Frequency_am < min_freq_AM)
Frequency_am = max_freq_AM;
}
// Si4730_Power_Up(AM_RECEIVER); //向上搜臺
Si4730_Tune_AM(AM_RECEIVER,Frequency_am); //AM收音芯片數據刷新一次
}
//=======================am end========================
//==============main start=======================
void main()
{
ResetSi47XX_2w();
Si4730_Delay(250);
while(1)
{
if(!FM_AM_Choose)
{
Si4730_Delay(100);
if(!FM_AM_Choose)
{
FM_AM_ = ~FM_AM_;
if(!FM_AM_)
{
Si4730_Power_Up_FM_AM_Choose(FM_RECEIVER); //fm選擇
}
else if(FM_AM_)
{
Si4730_Power_Up_FM_AM_Choose(AM_RECEIVER ); //am選擇
}
}
}
if(!FM_AM_)
{
// ResetSi47XX_2w();
if(!KEY_UP)
{
Si4730_Delay(100);
if(!KEY_UP)
{
Mode = HIGH; //向上搜臺
Search_FM();
}
}
if(!KEY_DW)
{
Si4730_Delay(100);
if(!KEY_DW)
{
Mode = LOW; //向下搜臺
Search_FM();
}
}
}
else if(FM_AM_)
{
// ResetSi47XX_2w();
if(!KEY_UP)
{
Si4730_Delay(100);
if(!KEY_UP)
{
Mode = HIGH; //向上搜臺
Search_AM();
}
}
if(!KEY_DW)
{
Si4730_Delay(100);
if(!KEY_DW)
{
Mode = LOW; //向下搜臺
Search_AM();
}
}
}
}
}
//=================main end=====================
|
|