发现比较复杂,可能是因为功能比较多,参考网上的程序
发现比较乱,不过总算移植到stm32上了。这几天再仔细看下手册,优化一下程序。pcb基本完成了,中间改了好几个地方。有机会作个板子。
网上的一段简版代码
/******************************************************
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
********************************************************/
#define DURATION_INIT_1 600ns mininum
#define DURATION_INIT_2 600ns minimum
#define DURATION_INIT_3 600ns minimum
#define DURATION_START_1 600ns minimum
#define DURATION_START_2 600ns minimum
#define DURATION_START_3 800ns minimum
#define DURATION_STOP_1 800ns minimum
#define DURATION_STOP_2 600ns minimum
#define DURATION_STOP_3 1300ns minimum
#define DURATION_HIGH 900ns minimum
#define DURATION_LOW 1600ns minimum
#define POWER_SETTLING 50~100ms
//#define DELAY(DURATION) {unsigned short i; for(i = 1; i <= DURATION; i++){}}
#define READ 1
#define WRITE 0
void ResetSi4700_2w(void)
{
SDIO_DIR = OUT;
SENB = 1;
SDIO = 0;
RST = 0;
SCLK = 1;
DELAY(DURATION_INIT_1);
RST = 1;
DELAY(DURATION_INIT_2);
SDIO = 1;
DELAY(DURATION_INIT_3);
}
unsigned char OperationSi4700_2w(unsigned char operation, unsigned char *data, unsigned char numBytes)
{
unsigned char controlWord, j, error = 0;
int i;
/***************************************************
START: make sure here SDIO_DIR =OUT, SCLK = 1, SDIO = 1
****************************************************/
SCLK = 1;
SDIO = 1;
DELAY(DURATION_START_1);
SDIO = 0;
DELAY(DURATION_START_2);
SCLK = 0;
DELAY(DURATION_START_3);
/***************************************************
WRITE CONTROL DATA: make sure here: SLCK = 0; SDIO = 0
****************************************************/
if(operation == READ)
controlWord = 0x21;
else
controlWord = 0x20;
for(i = 7; i>=0; i--)
{
SDIO = (controlWord >> i) & 0x01;
DELAY(DURATION_LOW/2);
SCLK = 1;
DELAY(DURATION_HIGH);
SCLK = 0;
DELAY(DURATION_LOW/2);
}
/***************************
CHECK ACK for control word
***************************/
SDIO_DIR = IN;
DELAY(DURATION_LOW/2);
SCLK = 1;
DELAY(DURATION_HIGH);
if(SDIO != 0)
{
error = 1;
goto STOP;
}
SCLK = 0;
DELAY(DURATION_LOW/2);
/***************************************
WRITE or READ data
****************************************/
for(j = 0; j < numBytes; j++, data++)
{
if(operation == WRITE)
SDIO_DIR = OUT;
else
<input type="image" src=""> SDIO_DIR = IN;
for(i = 7; i>=0; i--)
{
if(operation == WRITE)
SDIO = (*data >> i) & 0x01;
DELAY(DURATION_LOW/2);
SCLK = 1;
DELAY(DURATION_HIGH);
if(operation == READ)
*data = (*data << 1) | SDIO;
SCLK = 0;
DELAY(DURATION_LOW/2);
}
/******************************
CHECK ACK or SEND ACK=0
*******************************/
if(operation == WRITE)
SDIO_DIR = IN;
else
{
SDIO_DIR = OUT;
if(j == (numBytes -1))
SDIO = 1;
else
SDIO = 0;
}
DELAY(DURATION_LOW/2);
SCLK = 1;
DELAY(DURATION_HIGH);
if(operation == WRITE)
if(SDIO != 0)
{
error = 1;
goto STOP;
}
SCLK = 0;
DELAY(DURATION_LOW/2);
}
/****************************
STOP: make sure here: SCLK = 0
*****************************/
STOP:
SDIO_DIR = OUT;
SDIO = 0;
DELAY(DURATION_STOP_1);
SCLK = 1;
DELAY(DURATION_STOP_2);
SDIO = 1;
DELAY(DURATION_STOP_3);
return(error);
}
/**************************************
Si4700_Intialization():
after initialization please make sure:
0x00: 0x1242
0x01: 0x0800/0850
0x07: 0x3c04
0x08: 0x00ff
0x09: 0x0001
***************************************/
void Si4700_Intialization(void)
{
unsigned char si4700_initialization[] = {0x40,0x01,0x00,0x00,0xC0,0x04,0x0f,0x1f};
unsigned char error_ind = 0;
ResetSi4700_2w();
error_ind = OperationSi4700_2w(WRITE, &(si4700_initialization[0]), 8);
if(error_ind)
return;
DELAY(POWER_SETTLING);
}
/**************************************
Si4700_Channel_Selection()
***************************************/
void Si4700_Channel_Selection(void)
{
unsigned short loop_counter = 0;
unsigned char si4700_reg_data[32];
unsigned char error_ind = 0;
unsigned char si4700_channel_start_tune[]= {0x40,0x01,0x80,0xCA}; //107.7MHz
unsigned char si4700_channel_stop_tune[] = {0x40,0x01,0x00};
//set tune bit
error_ind = OperationSi4700_2w(WRITE, &(si4700_channel_start_tune[0]), 4);
if(error_ind)
return;
//wait STC=1
do
{
error_ind = OperationSi4700_2w(READ, &(si4700_reg_data[0]), 1);
if(error_ind)
return;
loop_counter++;
}
while(((si4700_reg_data[0]&0x40) == 0) && (loop_counter < 0xffff));
loop_counter = 0;
//clear tune bit
error_ind = OperationSi4700_2w(WRITE, &(si4700_channel_stop_tune[0]), 3);
if(error_ind)
return;
//wait STC=0
do
{
error_ind = OperationSi4700_2w(READ, &(si4700_reg_data[0]), 1);
if(error_ind)
return;
loop_counter++;
}
while(((si4700_reg_data[0]&0x40) != 0) && (loop_counter < 0xffff));
loop_counter = 0;
//read REG0A&0B
error_ind = OperationSi4700_2w(READ,&(si4700_reg_data[0]), 4);
if(error_ind)
return;
}
/**************************************
Si4700_Channel_Seek()
return 1: I2C error
return 2: seek fail
***************************************/
unsigned char Si4700_Channel_Seek(void)
{
unsigned short loop_counter = 0;
unsigned char si4700_reg_data[32];
unsigned char error_ind = 0, seek_error = 0;
unsigned char si4700_channel_seek_start[] = {0x41};
unsigned char si4700_channel_seek_stop[] = {0x40};
//set seek bit
error_ind = OperationSi4700_2w(WRITE,&(si4700_channel_seek_start[0]), 1);
if(error_ind)
return 1;
//wait STC=1
do
{
error_ind = OperationSi4700_2w(READ,&(si4700_reg_data[0]), 1);
if(error_ind)
return 1;
loop_counter++;
}
while(((si4700_reg_data[0]&0x40) == 0) && (loop_counter < 0xffff));
loop_counter = 0;
//check whether SF=1
if((si4700_reg_data[0]&0x20) != 0)
seek_error = 2;
//clear seek bit
error_ind = OperationSi4700_2w(WRITE,&(si4700_channel_seek_stop[0]), 1);
if(error_ind)
return 1;
//wait STC=0
do
{
error_ind = OperationSi4700_2w(READ,&(si4700_reg_data[0]), 1);
if(error_ind)
return 1;
loop_counter++;
}
while(((si4700_reg_data[0]&0x40) != 0) && (loop_counter < 0xffff));
loop_counter = 0;
//read REG0A&0B
error_ind = OperationSi4700_2w(READ,&(si4700_reg_data[0]), 4);
if(error_ind)
return 1;
return seek_error;
}