单片机论坛

 找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 5354|回复: 6
收起左侧

SI4730 收音机芯片资料与程序

[复制链接]
liuda 发表于 2015-1-20 15:33 | 显示全部楼层 |阅读模式
在网上看到关于这个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=====================


回复

使用道具 举报

李友明 发表于 2015-1-20 16:02 | 显示全部楼层
这个没有显示频率的,我不会加上显示频率,用的是1602,
回复

使用道具 举报

李友明 发表于 2015-1-20 16:08 | 显示全部楼层
include"reg52.h"
#include"intrins.h"
#include "LCD1602_4w.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;

//LCD1602_4w
sbit LCD_RS = P1^0;            
sbit LCD_RW = P1^1;
sbit LCD_EP = P1^2;
#define LCD_EN  LCD_EP
#define LCD_DATA    P0



/******************************************************
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=====================

新建文件夹 (3).rar (5.93 KB, 下载次数: 30)
回复

使用道具 举报

李友明 发表于 2015-1-20 16:11 | 显示全部楼层
我只是你这程序加上#include "LCD1602_4w.h",然后加上1602的接线定义后翻译出错,请求版主大家帮看一下,怎么样在你发的程序上加上频率显示,MCU你可随便定义,我改就行,期盼你的回复
回复

使用道具 举报

q642071377 发表于 2015-3-29 15:02 | 显示全部楼层
我现在也要做si4730收音机,一起努力吧
回复

使用道具 举报

xyz101531411 发表于 2015-8-16 00:13 | 显示全部楼层
好东西,学习,学习,
回复

使用道具 举报

51单片机1234 发表于 2019-1-10 16:35 | 显示全部楼层

好东西,学习,学习,
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

QQ|手机版|小黑屋|单片机论坛 |51黑电子论坛单片机. 联系QQ:125739409;技术交流QQ群582644647

Powered by 单片机教程网

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