|
在网上看到关于这个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=====================
|
|