• 最近研究si47xx系列芯片


    发现比较复杂,可能是因为功能比较多,参考网上的程序
    发现比较乱,不过总算移植到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;
    
    }
    
    






  • 相关阅读:
    ruby安装方法
    移动端适配问题px->rem方法
    判断元素阶段类型
    domReady
    电梯导航
    判断浏览器的版本以及浏览器内核( 转发 )
    AWS
    Amazon S3
    Pipeline 模型
    RESTful API
  • 原文地址:https://www.cnblogs.com/pulan/p/2921577.html
Copyright © 2020-2023  润新知