yzlyear 发表于 2010-6-13 18:08:19

SI4730收音芯,晶振不起振,求救啊!

最近在调SI4730收音机,发现晶振不起振,复位后发送POWER UP 返回0XFF,求救啊!
void Radio_reset(void)
{

I2C_SDA_LO();

cbi(PORTC,REST);
I2C_SCL_HI();
delay_ms(300);
sbi(PORTC,REST);
delay_ms(1);
I2C_SDA_HI();
delay_ms(1);
}
void get_ver(void)
{
   uchar i;
   uchar ver={0x00};
   uchar power_up={0x00};
   uchar get_rev={0x10};
   
   power_up=0x01;
   power_up=0x10;
   power_up=0x05;

   Radio_reset();
   delay_ms(500);
   i2c_radio(power_up,3);
   delay_ms(300);
   while(1)
   {
       Read_radio(get_rev,1,ver,9);
   delay_ms(100);
   for(i=0;i<9;i++)
   {
      UART_putchar(ver);
   }
       if(get_key()==MODE_KEY) return;
   }
}
以是返回版本号,但返回全是0XFF

Eiman 发表于 2010-6-13 18:24:47

3线控制或者I2C控制方式设置对不对

liaokeyre 发表于 2010-6-13 20:48:19

我最近搞4730,时序对了可是无声音出来。有机会交流一下啊。qq:120774639

xijianglangzi 发表于 2010-6-14 10:51:32

SI4730软件问题可以找我,QQ:153977234

yzlyear 发表于 2010-6-17 08:26:29

SI4730的SEN接高电平,所以地址write: 0XC6 read: 0xc7,以上的Radio_reset()函数是在复位时进入I2C BUS,各位看下是不是设置对了。

yzlyear 发表于 2010-6-17 09:17:30

搞定了,原来是SCL与SDA串的电阻太大了,改用1K后OK,另外复位也有点问题,应改为如下:
void Radio_reset(void)
{
I2C_SDA_LO();
cbi(PORTC,REST);
I2C_SCL_HI();
delay_ms(10);
sbi(PORTC,REST);
I2C_SDA_HI();
delay_ms(1);
}

yzlyear 发表于 2010-6-24 17:33:24

现在能收音,但读出状态时,所有的状态返回都是0X80,0X00,0X00,0X00,0X00,0X00...
程序如下:
#include <avr/io.h>
#include <avr/pgmspace.h>
#include <avr/eeprom.h>
#include <stdlib.h>

#include "types.h"
#include "i2c.h"
#include "lcd.h"
#include "mem.h"
#include "delay.h"
#include "key.h"
#include "radio.h"
#include "lcd.h"
#include "font.h"
#include "equ.h"
#include "uart.h"

u16 Frequency_fm=8750;
u16 Frequency_am=531;

uchar Band = FM1;

extern const uchar num9 PROGMEM;
extern const uchar num8 PROGMEM;
extern const uchar num12 PROGMEM;
//----------------------------------------
// read radio status
//----------------------------------------
uchar Si4730_status(void)
{
uchar Buffer={0x00};
delay_ms(1);
Read_radio(Buffer,1);
if(Buffer&0x80) return TURE;
else return FLASE;
}
//----------------------------------------
// RESET SI4730
//----------------------------------------
void Radio_reset(void)
{
I2C_SDA_LO();
cbi(PORTC,REST);
I2C_SCL_HI();
delay_ms(10);
sbi(PORTC,REST);
I2C_SDA_HI();
delay_ms(1);
}
//----------------------------------------
//
//----------------------------------------
void si47xx_set_property(u16 propNumber,u16 propValue)
{
uchar i2cBuffer;
i2cBuffer=0x12;
// Initialize the reserved section to 0
i2cBuffer=0;
// Put the property number in the third and fourth bytes.
i2cBuffer=(u08)(propNumber >> 8);
i2cBuffer=(u08)(propNumber & 0x00FF);
// Put the property value in the fifth and sixth bytes.
i2cBuffer=(u08)(propValue >> 8);
i2cBuffer=(u08)(propValue & 0x00FF);
i2c_radio(i2cBuffer,6);
}
//----------------------------------------
// band choose/power up
// band_type: band typeFM1,FM2,AM
//----------------------------------------
void Band_choose(uchar band_type)
{
uchar buffer={0x00};

buffer=0x01;   //powerup command
buffer=0xd0;   //use extern crystal oscillator 32.768KHzl, FM Receiver
buffer=0x05;   //analog audio output LOUT/ROUT
if(band_type==AM) buffer=0xd1;
Radio_reset();
delay_ms(200);
i2c_radio(buffer,3);
delay_ms(300);

}
//--------------------------------------------------------
//extern volatile uchar time0_b;
void get_fm_rsq_status(void)
{
   uchar rsq_status={0x23,0x01};
   uchar rev={0x00};
   uchar i=0;
   
   i2c_radio(rsq_status,2);
   delay_ms(100);   
   Read_radio(rev,8);
   for(i=0;i<8;i++)
   {
   UART_putchar(rev);
   }
}
   
//-----------------------------------------
// search FM
// mode: 0: down search 1: up search
//-----------------------------------------
void Search_FM(uchar mode)
{
   uchar buffer={0x00,0x00,0x00,0x00,0x00};

   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;
   }
   
   buffer = 0x20;   //Command FM tuner frequency
   buffer = 0x00;   //arg1 always write 0
   buffer = (uchar)(Frequency_fm>>8); //write frequency hight byte
   buffer = (uchar)(Frequency_fm&0x00ff);      //write frequency low byte
   buffer = 0x00;            //Antenna tuning capacitor if write0 auto
   i2c_radio(buffer,5);
}
//=================fm end============

//===============am start==============
//-----------------------------------------
// search AM
// mode: 0: down search 1: up search
//-----------------------------------------
void Search_AM(uchar mode)   //调用手动FM 频率调整子程序 menu = 15
{
   unsigned char buffer={0x00,0x00,0x00,0x00,0x00,0x00};
   
   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;
   }


   buffer= 0x40;   //Command AM receiver
   buffer= 0x00;   //arg1 always write 0
   buffer = (uchar)(Frequency_am>>8); //write frequency hight byte
   buffer = (uchar)(Frequency_am&0x00ff);       //write frequency low byte
   buffer= 0x00;
   buffer= 0x00;
   i2c_radio(buffer, 6);
}
//=======================am end========================

//------------------------------------------------------
// show frequency
//------------------------------------------------------
void Show_frequency(void)
{
if(Band==AM)
{
    MHZ_onoff(0);
        KHZ_onoff(1);
    write_led12(SED1_ADD,A);
    write_led12(SED2_ADD,M);
    write_led9(SED3_ADD,1);
        write_led9(SED4_ADD,gang);
                  
        write_led9(SED9_ADD,((Frequency_am%1000)%100)%10);

        Write_1621(SED8_ADD+8,(pgm_read_byte(&num8[((Frequency_am%1000)%100)/10]))|((pgm_read_byte(&num9[((Frequency_am%1000)%100)%10]))>>4));
        Write_1621(SED8_ADD,(pgm_read_byte(&num8[((Frequency_am%1000)%100)/10])));

        write_led9(SED7_ADD,(Frequency_am%1000)/100);
        if(Frequency_am/1000) write_led9(SED6_ADD,Frequency_am/1000);
        else Write_1621(SED6_ADD,0);
}
else
{
    KHZ_onoff(0);
        MHZ_onoff(1);
        write_led12(SED1_ADD,F);
    write_led12(SED2_ADD,M);
        if(Band==FM1) write_led9(SED3_ADD,1);
        if(Band==FM2) write_led9(SED3_ADD,2);
        write_led9(SED4_ADD,gang);

        write_led9(SED9_ADD,(((Frequency_fm%10000)%1000)%100)/10);

    Write_1621(SED8_ADD+8,((pgm_read_byte(&num8[((Frequency_fm%10000)%1000)/100]))|0x80)|((pgm_read_byte(&num9[(((Frequency_fm%10000)%1000)%100)/10]))>>4));
        Write_1621(SED8_ADD,(pgm_read_byte(&num8[((Frequency_fm%10000)%1000)/100])));

        write_led9(SED7_ADD,(Frequency_fm%10000)/1000);
        if(Frequency_fm/10000) write_led9(SED6_ADD,Frequency_fm/10000);
    else Write_1621(SED6_ADD,0);
}

}

//--------------------------------------
// get rev
//--------------------------------------
extern volatile uchar vol_key_value;//only use in vol set
extern volatile uchar vol;
extern volatile uchar SYS_message;
extern uchar key_value;
#define KEY_press    0
#define KEY_vol_flag 1
extern void show_vol(void);
void radio_tuner(void)
{
Radio_reset();
Band_choose(FM1);
//SEE AN332 PAGE52 follow
/*si47xx_set_property(0x0001,0x00c9);    //set GOP_IEN, STCIEN,ERRIEN,CTSIEN,RSQIEN
delay_ms(100);
si47xx_set_property(0x1100,0x01); //set FM_DEEMPHASIS //50 us
delay_ms(100);
si47xx_set_property(0x1105,50);   //set FM_BLEND_STEREO_THRESHOLD //50dBu
delay_ms(100);
si47xx_set_property(0x1106,24);   //set FM_BLEND_MONO_THRESHOLD //24dBu
delay_ms(100);
si47xx_set_property(0x1200,0x008f);    //set FM_RSQ_INT_SOURCE
delay_ms(100);
si47xx_set_property(0x1201,30);    //set FM_RSQ_SNR_HI_THRESHOLD //30dB
delay_ms(100);
si47xx_set_property(0x1202,6);    //set FM_RSQ_SNR_LO_THRESHOLD //6dB
delay_ms(100);
si47xx_set_property(0x1203,50);    //set FM_RSSI_HI_THRESHOLD //50dBu
delay_ms(100);
si47xx_set_property(0x1204,24);    //set FM_RSSI_LO_THRESHOLD //24dBu
delay_ms(100);
si47xx_set_property(0x1207,0x00B2);//set FM_RSQ_BLEND_THRESHOLD
delay_ms(100);
si47xx_set_property(0x1402,10);    //set FM_SEEK_FREQ_SPACING10KHZ STEP
delay_ms(100);
si47xx_set_property(0x1403,6);   //set FM_SEEK_TUNE_SNR_THRESHOLD //6dB
delay_ms(100);
si47xx_set_property(0x1204,20);    //set FM_SEEK_TUNE_RSSI_THRESHOLD //14dB
delay_ms(100); */


while(1)
{
          if(ValBit(SYS_message,KEY_vol_flag))
          {
      switch(vol_key_value)
                {
                  case VOL_DOWN_KEY:
                     if(vol--<=0) vol=0;
                           break;
                  case VOL_UP_KEY:
                     if(vol++>=30) vol=30;
                           break;
                  default:
                     break;
                }
                vol_key_value=0;
                show_vol();
          }
          key_value = get_key();
switch(key_value)
{
    case ADD_KEY:
          Band++;
      if(Band>AM) Band=FM1;
      if(Band==AM)
      {
      Band_choose(AM);
      }
      else if((Band==FM1)||(Band==FM2))
      {
      Band_choose(FM1);
si47xx_set_property(0x0001,0x00c9);    //set GOP_IEN, STCIEN,ERRIEN,CTSIEN,RSQIEN
delay_ms(100);
si47xx_set_property(0x1100,0x01); //set FM_DEEMPHASIS //50 us
delay_ms(100);
si47xx_set_property(0x1105,50);   //set FM_BLEND_STEREO_THRESHOLD //50dBu
delay_ms(100);
si47xx_set_property(0x1106,24);   //set FM_BLEND_MONO_THRESHOLD //24dBu
delay_ms(100);
si47xx_set_property(0x1200,0x008f);    //set FM_RSQ_INT_SOURCE
delay_ms(100);
si47xx_set_property(0x1201,30);    //set FM_RSQ_SNR_HI_THRESHOLD //30dB
delay_ms(100);
si47xx_set_property(0x1202,6);    //set FM_RSQ_SNR_LO_THRESHOLD //6dB
delay_ms(100);
si47xx_set_property(0x1203,50);    //set FM_RSSI_HI_THRESHOLD //50dBu
delay_ms(100);
si47xx_set_property(0x1204,24);    //set FM_RSSI_LO_THRESHOLD //24dBu
delay_ms(100);
si47xx_set_property(0x1207,0x00B2);//set FM_RSQ_BLEND_THRESHOLD
delay_ms(100);
si47xx_set_property(0x1402,10);    //set FM_SEEK_FREQ_SPACING10KHZ STEP
delay_ms(100);
si47xx_set_property(0x1403,6);   //set FM_SEEK_TUNE_SNR_THRESHOLD //6dB
delay_ms(100);
si47xx_set_property(0x1204,20);    //set FM_SEEK_TUNE_RSSI_THRESHOLD //14dB
delay_ms(100);
      }
          break;
        case PRE_KEY:
          if((Band==FM1)||(Band==FM2))
      {
      Search_FM(DN_SEARCH);
                delay_ms(100);
          get_fm_rsq_status();
      }
      else//(Band==AM1)
      {
      Search_AM(DN_SEARCH);
      }
          break;
   case NEXT_KEY:
   if((Band==FM1)||(Band==FM2))
   {
       Search_FM(UP_SEARCH);
           delay_ms(100);
           get_fm_rsq_status();
   }
   else
   {
       Search_AM(UP_SEARCH);
   }
       break;
}//switch(get_key())
Show_frequency();
}//while(1)
}
//-------------------------------------
#include <avr\io.h>
#include <avr\interrupt.h>
#include <avr\sfr_defs.h>

#include "equ.h"
#include "i2c.h"
#include "audio.h"
#include "delay.h"
#include "uart.h"
#include "radio.h"

void I2C_init(void)
{
   DDRC |= (1<<SDA)|(1<<SCL);
   DDRD &= ~_BV(RXD);
}

//------------------------------
// start signal
//------------------------------
void i2c_start(void)
{
I2C_SCL_LO();
delay_us(10);
I2C_SCL_HI();//send start condition clock

delay_us(10);
I2C_SDA_HI();//send start condition data

delay_us(10);//start condition >4.7us

I2C_SDA_LO();
delay_us(10);
I2C_SCL_LO();// lock iic bus, ready send data
}
//------------------------------
// stop signal
//----------------------------
void i2c_stop(void)
{
I2C_SDA_LO(); //send stop condition data
I2C_SCL_LO();
delay_us(10);

I2C_SCL_HI(); //send stop condition clock
delay_us(10); //stop condition >4.7us

I2C_SDA_HI();
delay_us(10);
I2C_SDA_LO();
}
//------------------------------
// ack signal
//------------------------------
void Ack(void)
{
I2C_SCL_LO();//ready send ack
I2C_SDA_LO();
delay_us(10);

I2C_SCL_HI();//clock hold hi level >4.7us
delay_us(10);
I2C_SCL_LO();//clock clr 0
delay_us(10);

I2C_SDA_HI();//stop ack
}
//------------------------------
// No ack signal
//------------------------------
void No_ack(void)
{
I2C_SDA_LO();//ready send No ack
I2C_SCL_LO();
delay_us(10);

I2C_SDA_HI();//clock and data hold hi level, this is No ack
I2C_SCL_HI();

delay_us(10);//hold hi >4.0us

I2C_SCL_LO();//stop No ack
delay_us(10);
I2C_SDA_LO();
}

//------------------------------
void i2c_write(uchar b)
{
uchar i;

sbi(DDRC,SDA);//改变SDA端口方向为输出
delay_us(10);

for(i=0;i<8;i++)
{
    I2C_SCL_LO();//当SCL为低电平时允许数据改变
       
        if (b & 0x80)
    {
      I2C_SDA_HI();
        }
    else
    {
      I2C_SDA_LO();
        }
       
        b<<=1;//移位

        I2C_SCL_HI();// 当时钟线为1时,数据必须保持稳定
}
I2C_SCL_LO(); //每发送8位数据跟随一个时钟信号,等待从机作出应答
delay_us(10);
I2C_SCL_HI();
}


//----------------------------------
uchar i2c_read(void)
{
uchar i,temp=0;

cbi(DDRC,SDA);//改变SDA端口方向为输入
sbi(PORTC,SDA);//enable pullups

delay_us(10);

for(i=0;i<8;i++)
{
    I2C_SCL_LO(); //时钟为低电平,准备接收数据
    delay_us(10); //时钟低电平大于4.7US
        I2C_SCL_HI(); //当时钟线为高时,数据线上的数据有效
        temp<<=1;               
        if(ValBit(PINC,SDA))
        {
          temp |= 1;
        }
   }
   sbi(DDRC,SDA);//改变端口方向为输出   
   return temp;
}

/**************************************************************************/
/* I2C public functions                                                                                                   */
/**************************************************************************/



/*
    Send a byte to PT2313
*/

void i2c_audio(uchar data)
{

i2c_start();      // do start transition
i2c_write(0x88);    // send the address
i2c_write(data);    // send the data
i2c_stop();         // send STOP transition
}

//-------------------------------
//function: 发送多个字节到指定地址
//add: 为要发送数据的地址
//subadd: 器件子地址
//nLen: 为所发送数据的长度
//-------------------------------
void i2c_mp3(uchar *cmd, uchar nLen)
{
   uchar i;
   i2c_start();
   i2c_write(0x80);   //BU72435 addr
   for(i=0;i<nLen;i++)
   {
   i2c_write(*cmd);//send 8 bit to bus
       cmd++;            //指向下一个要发送的数据
   }
   i2c_stop();
}
//*******************************************************************
//function: 发送多个字节到指定地址
//cmd1
//cmd2
//*store_add: 为要接收数据的地址
//store_nLen: 为所接收数据的长度
//********************************************************************/
//*******************
void Read_mp3_status(uchar cmd1, uchar cmd2, uchar *store_add, uchar store_nLen)
{
   uchar i;
   i2c_start();      //*启动总线*/
   i2c_write(0x80);    //*发送器件地址*/
   i2c_write(cmd1);
   i2c_write(cmd2);
   i2c_stop();
   delay_us(100);
   
   i2c_start();
   i2c_write(0x81);   //发送读址
   for(i=0;i<store_nLen;i++)
   {
   *store_add=i2c_read();//*接收数据*/
   store_add++;         //指向下一个要存放数据的地址
   Ack();         //接收到8位数据,发送一个应答信号
   }

   *store_add=i2c_read();   //最后再多读8位
   No_ack();          //发送非应答信号,停止读取数据
   i2c_stop();      //*结束总线*/
}

//-------------------------------
//function: 发送多个字节到指定地址
//add: 为要发送数据的地址
//subadd: 器件子地址
//nLen: 为所发送数据的长度
//-------------------------------
void i2c_radio(uchar *cmd, uchar nLen)
{
   uchar i;
   i2c_start();
   i2c_write(RADIO_WRITE_ADDR);   //si4730 addr
   delay_us(100);
   
   for(i=0;i<nLen;i++)
   {
   i2c_write(*cmd);//send 8 bit to bus
       cmd++;            //指向下一个要发送的数据
   }
   i2c_stop();
}

//*******************************************************************
//function: 发送多个字节到指定地址
//*cmd      命令地址
//cmd_nLen命令字节数
//*store_add: 为要接收数据的地址
//store_nLen: 为所接收数据的长度
//********************************************************************/
void Read_radio(uchar *store_add, uchar store_nLen)
{
   uchar i;
   
   i2c_start();
   i2c_write(RADIO_READ_ADDR);   //发送读地址
   delay_ms(1);

   for(i=0;i<store_nLen;i++)
   {
   *store_add=i2c_read();//接收数据
   store_add++;            //指向下一个要存放数据的地址
   Ack();         //接收到8位数据,发送一个应答信号
   }

   *store_add=i2c_read();   //最后再多读8位
   No_ack();          //发送非应答信号,停止读取数据
   i2c_stop();      //*结束总线*/
}

yzlyear 发表于 2010-6-26 10:03:18

搞定了,原来I2C_START 与I2C_stop有问题,改为如下:
void i2c_start(void)
{
I2C_SDA_HI();
I2C_SCL_HI();
delay_us(10);
I2C_SDA_LO();
delay_us(10);
I2C_SCL_LO();
}
void i2c_stop(void)
{
I2C_SDA_LO();
I2C_SCL_LO();
delay_us(10);
I2C_SCL_HI();
I2C_SDA_HI();
}

monishuzi 发表于 2010-11-16 17:32:51

刚开始做sl4730,虽然不是很明白,学习了!

lwy86 发表于 2010-11-16 17:50:57

mark

fjourdev 发表于 2010-11-16 19:15:07

mark

laolu 发表于 2010-11-16 19:36:12

mark

wwwdege 发表于 2010-11-17 00:01:47

学习了

epgadw 发表于 2011-6-12 23:43:36

void Radio_reset(void)
{

I2C_SDA_LO();

cbi(PORTC,REST);
I2C_SCL_HI();
delay_ms(300);
sbi(PORTC,REST);
delay_ms(1);
I2C_SDA_HI();
delay_ms(1);
}
请问一下,为什么sbi(PORTC,REST);和I2C_SDA_HI(); 之间的延迟不需要?资料里是需要延迟的啊。。
我目前也在调在SI4730,也是晶振不起。回复【5楼】yzlyear 天地一号
-----------------------------------------------------------------------

allen6kid 发表于 2012-5-13 17:48:15

好贴,收藏了啊

pregnant 发表于 2012-6-5 17:30:50

yzlyear 发表于 2010-6-26 10:03 static/image/common/back.gif
搞定了,原来I2C_START 与I2C_stop有问题,改为如下:
void i2c_start(void)
{


我想问下,关于他的第六脚SEN是需要我们编程还是电路固定的?我看一些Si4730的模块上没有引出SEN引脚啊

yuangli 发表于 2012-7-26 11:07:11

问一个问题,我从楼主的程序改编成PIC16F877的程序,现在可以收音了,但是有一个问题,用0X23,0X01命令检测电平,发现有的电平高,反而没有声音,有的电平不高却有电台。这样什么才能判断有效的电台?请多多指教,不胜感谢。

moqutong 发表于 2012-7-27 18:34:12

兄弟,也在玩SI47的收音芯片吗?我的4702有时能收台,有时则是沙沙响,怎么也收不到

icengineer 发表于 2012-10-24 01:33:54

MARK 收音
页: [1]
查看完整版本: SI4730收音芯,晶振不起振,求救啊!