⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 main.c

📁 用S3C2410做的收音机驱动板,也可以移殖到S3C2440上,成品后工作正常,可以随意切换频道,收音机芯片为Si4700
💻 C
字号:
#include <stdlib.h>
#include <string.h>
#include "2410addr.h"
#include "2410lib.h"

#define SIGN_ON "\n系统初始化完毕!" __DATE__ " " __TIME__ "\n" 
#define SDIO   9
#define SCLK   11
#define RST    12
#define SOURCE  13
#define uchar unsigned char
#define ushort unsigned short
 /******************************************************
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 	6000
#define DURATION_INIT_2	6000
#define DURATION_INIT_3 	6000

#define DURATION_START_1	6000
#define DURATION_START_2	6000
#define DURATION_START_3	8000
#define DURATION_STOP_1	8000
#define DURATION_STOP_2	6000
#define DURATION_STOP_3	13000

#define DURATION_HIGH		9000
#define DURATION_LOW		9000

#define POWER_SETTLING		1000

#define READ		1
#define WRITE	0

void HaltUndef(void);
void HaltSwi(void);
void HaltPabort(void);
void HaltDabort(void);
void Isr_Init(void);
void Target_Init(void);
void SET_GPFC(int x,int y);
void SET_GPFD(int x,int y);
void SET_GPFU(int x,int y);
void DELAY(int x);
uchar OperationSi4700_2w(uchar operation, uchar *data, uchar numBytes);
void ResetSi4700_2w(void);
void Si4700_Intialization(void);
void Si4700_Channel_Selection(void);
uchar Si4700_Channel_Seek(void);

    uchar si4700_reg_data[32];
    uchar si4700_voice[] = {0x40,0x01,0x00,0xCA,0x90,0x04,0x0c,0x1f};
    uchar si4700_channel_start_tune[] = {0x40,0x01,0x80,0xCA};	//107.7MHz-87.5M/0.1=0XCA
	uchar si4700_channel_stop_tune[] = {0x40,0x01,0x00};
	uchar si4700_channel_seek_start[] = {0x41};
	uchar si4700_channel_seek_stop[] = {0x40};
	
    uchar recnum,errint,channel,voice;

void Main(void)
{

    Target_Init(); 

    Uart_SendString(SIGN_ON);

    SET_GPFC(SDIO,1);
    SET_GPFC(SCLK,1);
    SET_GPFC(RST,1);
    SET_GPFC(SOURCE,1);
    
    SET_GPFU(SDIO,0);
    SET_GPFU(SCLK,0);
    SET_GPFU(RST,0);
    SET_GPFU(SOURCE,0);
    SET_GPFD(SOURCE,1); 
    voice=4;
    Si4700_Intialization();
    while(1)
    {
        recnum = Uart_Getch();
        if (recnum==49)//向上搜台
        {
            si4700_channel_seek_start[0] = 0x41;
            errint=Si4700_Channel_Seek();
            SET_GPFD(SOURCE,0);
            DELAY(0x00ffffff);
            SET_GPFD(SOURCE,1);
            channel=si4700_reg_data[3];
        }
        if (recnum==50)//向下搜台
        {
            si4700_channel_seek_start[0] = 0x43;
            errint=Si4700_Channel_Seek();
            SET_GPFD(SOURCE,0);
            DELAY(0x00ffffff);
            SET_GPFD(SOURCE,1);
            channel=si4700_reg_data[3];
        }
        if (recnum==51)
        {            
            if (voice<15)
                voice++;
            si4700_voice[3]=channel;
            si4700_voice[7]=si4700_voice[7]&0xf0|voice;
        	OperationSi4700_2w(WRITE, &(si4700_voice[0]), 8);
        }
        if (recnum==52)
        {
            if (voice>0)
                voice--;
            si4700_voice[3]=channel;
            si4700_voice[7]=si4700_voice[7]&0xf0|voice;
            OperationSi4700_2w(WRITE, &(si4700_voice[0]), 8);
        }
        if (recnum==53)
        {
            SET_GPFD(RST,0);
        }
        if (recnum==54)
        {
            Si4700_Intialization();
        }
        if (recnum==55)
        {
            SET_GPFD(SOURCE,0);
        }
        if (recnum==56)
        {
            SET_GPFD(SOURCE,1);
        }
    }
}
/**************************************************************************
- 函数名称:  void Target_Init(void)
- 函数说明 :  目标板初始化
- 输入参数 :  无
- 输出参数 :  无
**************************************************************************/
void SET_GPFC(int x,int y)
{
    rGPCCON = (rGPCCON & ~(3<<(x<<1)))|(y<<(x<<1));
}
void SET_GPFD(int x,int y)
{
    rGPCDAT = (rGPCDAT & ~(1<<x))|(y<<x);
}
void SET_GPFU(int x,int y)
{
    rGPCUP  = (rGPCUP & ~(1<<x))|(y<<x);
}
void Target_Init(void)
{
    MMU_Init();
    ChangeClockDivider(1,1);          // 1:2:4    
    ChangeMPllValue(0xa1,0x3,0x1);    // FCLK=202.8MHz 
    Port_Init();
    Uart_Init(0,115200);
    Uart_Select(0);     
}
void Isr_Init(void)
{
    pISR_UNDEF  = (unsigned)HaltUndef;
    pISR_SWI    = (unsigned)HaltSwi;
    pISR_PABORT = (unsigned)HaltPabort;
    pISR_DABORT = (unsigned)HaltDabort;
    
    rINTMOD     = 0x0;                     //All=IRQ mode
//    rINTCON=0x5;                           //Non-vectored,IRQ enable,FIQ disable    
    rINTMSK     = BIT_ALLMSK;              //All interrupt is masked.
    rINTSUBMSK  = BIT_SUB_ALLMSK;          //All sub-interrupt is masked. <- April 01, 2002 SOP

//    rINTSUBMSK  = ~(BIT_SUB_RXD0);         //Enable Rx0 Default value=0x7ff
//    rINTMSK     = ~(BIT_UART0);            //Enable UART0 Default value=0xffffffff    
    
//    pISR_UART0=(unsigned)RxInt;            //pISR_FIQ,pISR_IRQ must be initialized
}
void HaltUndef(void)
{
    Uart_Printf("Undefined instruction exception.\n");
    while(1);
}

//===================================================================
void HaltSwi(void)
{
    Uart_Printf("SWI exception.\n");
    while(1);
}

//===================================================================
void HaltPabort(void)
{
    Uart_Printf("Pabort exception.\n");
    while(1);
}

//===================================================================
void HaltDabort(void)
{
    Uart_Printf("Dabort exception.\n");
    while(1);
}
void ResetSi4700_2w(void)
{
    SET_GPFD(SDIO,0);
    SET_GPFD(RST,0);
    SET_GPFD(SCLK,1);
	DELAY(DURATION_INIT_1);
	SET_GPFD(RST,1);
	DELAY(DURATION_INIT_2);
	SET_GPFD(SDIO,1);
	DELAY(DURATION_INIT_3);
}

uchar OperationSi4700_2w(uchar operation, uchar *data, uchar numBytes)
{
	uchar controlWord,  j, error = 0;
	int i;
/***************************************************

START: make sure here SDIO_DIR =OUT, SCLK = 1,	SDIO = 1

****************************************************/
    SET_GPFD(SCLK,1);
    SET_GPFD(SDIO,1);
	DELAY(DURATION_START_1);
	SET_GPFD(SDIO,0);
	DELAY(DURATION_START_2);
    SET_GPFD(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--)
	{
	    SET_GPFD(SDIO,(controlWord >> i) & 0x01);
		DELAY(DURATION_LOW/2);
		SET_GPFD(SCLK,1);
		DELAY(DURATION_HIGH);
		SET_GPFD(SCLK,0);
		DELAY(DURATION_LOW/2);
	}

	
/***************************

CHECK ACK for control word

***************************/
    SET_GPFC(SDIO,0);
	DELAY(DURATION_LOW/2);
	SET_GPFD(SCLK,1);
	DELAY(DURATION_HIGH);
	
	if((rGPCDAT>>SDIO&0x01)!= 0)
	{
		error = 1;
		goto STOP;
	}
	
    SET_GPFD(SCLK,0);
	DELAY(DURATION_LOW/2);

/***************************************

WRITE or READ data

****************************************/

	for(j = 0; j < numBytes; j++,data++)
	{
		if(operation == WRITE)
			SET_GPFC(SDIO,1);
		else
			SET_GPFC(SDIO,0);
		for(i = 7; i>=0; i--)
		{
			if(operation == WRITE)
			    SET_GPFD(SDIO,(*data >> i) & 0x01);
			DELAY(DURATION_LOW/2);
			SET_GPFD(SCLK,1);
			DELAY(DURATION_HIGH);
			
            if(operation == READ)
            {
				*data = (*data << 1) | (rGPCDAT>>SDIO&0x01);
			}
			SET_GPFD(SCLK,0);
			DELAY(DURATION_LOW/2);
		}
/******************************

CHECK ACK or SEND ACK=0

*******************************/

		if(operation == WRITE)
		{
			SET_GPFC(SDIO,0);
		}
		else
		{
			SET_GPFC(SDIO,1);
			if(j == (numBytes -1))
				SET_GPFD(SDIO,1);
			else
				SET_GPFD(SDIO,0);
		}
		DELAY(DURATION_LOW/2);
		SET_GPFD(SCLK,1);
		DELAY(DURATION_HIGH);
		if(operation == WRITE)
		{
	        if((rGPCDAT>>SDIO&0x01)!= 0)
	        {
		        error = 1;
		        goto STOP;
	        }
	    }
	    SET_GPFD(SCLK,0);
		DELAY(DURATION_LOW/2);
	}
	
/****************************

STOP: make sure here: SCLK = 0

*****************************/

	STOP:
    SET_GPFC(SDIO,1);
    SET_GPFD(SDIO,0);
	DELAY(DURATION_STOP_1);
	SET_GPFD(SCLK,1);
	DELAY(DURATION_STOP_2);
	SET_GPFD(SDIO,1);
	DELAY(DURATION_STOP_3);

	return(error);

}



/**************************************

Si4700_Intialization():
after initialization please make sure(FW/B15):
0x00: 0x1242
0x01: 0x080F/0A0F
0x07: 0x3C04
0x08: 0x0008
0x09: 0x0001

***************************************/
void Si4700_Intialization(void)
{
//	uchar si4700_initialization[] = {0x40,0x00,0x00,0x00,0x90,0x04,0x0c,0x14,0x00,0x48,0xc1,0x00};
	uchar si4700_initialization[] = {0x40,0x01,0x00,0x00,0x90,0x04,0x0c,0x14,0x00,0x48};
//	uchar si4700_initialization2[] = {0x40,0x01};
	uchar error_ind = 0;
	ResetSi4700_2w();
	DELAY(POWER_SETTLING);	
	    
	error_ind = OperationSi4700_2w(WRITE, &(si4700_initialization[0]), 10);
	if(error_ind)
		return;

	DELAY(POWER_SETTLING);	
	
//	error_ind = OperationSi4700_2w(WRITE, &(si4700_initialization2[0]), 2);
//	if(error_ind)
//		return;
		
//	DELAY(POWER_SETTLING);
}

/**************************************

Si4700_Channel_Selection()

***************************************/

void Si4700_Channel_Selection(void)
{
	ushort loop_counter = 0;
	uchar error_ind = 0;

 	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 < 0xff));		
	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 < 0xff));		
	loop_counter = 0;
    
	//read REG0A&0B
	error_ind = OperationSi4700_2w(READ,&(si4700_reg_data[0]), 4);	
	if(error_ind)
		return;	
	

}

/*****************************************************************************************************

Si4700_Channel_Seek()
return 0: good, current channel is valid
return 1: I2C error 
return 2: used in SKMODE0, seek fail, no any valid channel, should end seek
return 2: used in SKMODE1, Band Limit, Stop seeking at the upper or lower band limit, should end seek
return 3: AFC rail, current channel is invalid, should seek next one

******************************************************************************************************/
uchar Si4700_Channel_Seek(void)
{
	uchar loop_counter = 0;
	uchar error_ind = 0, seek_error = 0;

	//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 < 0xfff));	//for loop_counter, when seek, the loop time must > 2s		
	loop_counter = 0;

	//if you use SKMODE = 0, you can check Seek Fail here
	//if you use SKMODE = 1, you can check Band Limit here
	
	if((si4700_reg_data[0]&0x20) != 0)
		seek_error = 2;
		
	//you can check AFC Rail here
	else if((si4700_reg_data[0]&0x10) != 0)
		seek_error = 3;   
	    
    //you can read REG0A&0B for channel number or RSSI here
	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 < 0xff));		
	loop_counter = 0;

	error_ind = OperationSi4700_2w(READ,&(si4700_reg_data[0]), 4);
	if(error_ind)
		return 1;

	return seek_error;
	
}
void DELAY(int x)
{
    int i;
    for(i = 0;i < x; i++)
    {}
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -