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 3线控制或者I2C控制方式设置对不对 我最近搞4730,时序对了可是无声音出来。有机会交流一下啊。qq:120774639 SI4730软件问题可以找我,QQ:153977234 SI4730的SEN接高电平,所以地址write: 0XC6 read: 0xc7,以上的Radio_reset()函数是在复位时进入I2C BUS,各位看下是不是设置对了。 搞定了,原来是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);
} 现在能收音,但读出状态时,所有的状态返回都是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(); //*结束总线*/
} 搞定了,原来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();
} 刚开始做sl4730,虽然不是很明白,学习了! mark mark mark 学习了 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 天地一号
----------------------------------------------------------------------- 好贴,收藏了啊 yzlyear 发表于 2010-6-26 10:03 static/image/common/back.gif
搞定了,原来I2C_START 与I2C_stop有问题,改为如下:
void i2c_start(void)
{
我想问下,关于他的第六脚SEN是需要我们编程还是电路固定的?我看一些Si4730的模块上没有引出SEN引脚啊 问一个问题,我从楼主的程序改编成PIC16F877的程序,现在可以收音了,但是有一个问题,用0X23,0X01命令检测电平,发现有的电平高,反而没有声音,有的电平不高却有电台。这样什么才能判断有效的电台?请多多指教,不胜感谢。 兄弟,也在玩SI47的收音芯片吗?我的4702有时能收台,有时则是沙沙响,怎么也收不到 MARK 收音
页:
[1]