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

📄 sp3767.c

📁 T5767收音机IIC协议和控制部分源码
💻 C
字号:
#include <reg52.h>
#include <stdio.h>
#include <intrins.h>

#include "SP3767.h"

#define		NOP()		_nop_()


sbit	UpKey = P1 ^ 0;
sbit	DnKey = P1 ^ 1;
sbit	LED = P1 ^ 2;
sbit	SDA = P1 ^ 4;
sbit	SCL = P1 ^ 5;





#define HAND	1
//#define HAND
#define NUM 20
unsigned short code FRQ_TAB[] =
{
	880,
	920,
	960,
	1000,
	1040,
	876,
	885,
	897,
	926,
	937,
	966,
	975,
	997,
	1011,
	1017,
	1024,
	1043,
	1058,
	1066,
	1071,
	1079,
};
unsigned char index;

void DelayMs(unsigned char i)
{
	unsigned char j;
	j = 200; 
	do{
		do{
			_nop_();
			_nop_();
			_nop_();
			_nop_();
			_nop_();
			_nop_();
			_nop_();
			_nop_();
			_nop_();
			_nop_();
		}while(j --);
	}while(i --);
}

void I2CStart(void)
{/*
	SDA = 1;
	SCL = 1;
	NOP();
	SDA = 0;
	NOP();
	SCL = 0;*/
	
	SCL = 1;
	SDA = 1;
	SDA = 0;
	NOP();
	NOP();
	NOP();
	SCL = 0;
}

void I2CStop(void)
{/*
	SCL = 0;
	SDA = 0;
	NOP();
	SCL = 1;
	NOP();
	SDA = 1;
	EA = 1;*/
	
	SCL = 1;
	SDA = 0;
	NOP();
	NOP();
	NOP();
	SDA = 1;
	NOP();
	NOP();
	NOP();
}

bit WaitAck(void)
{
	unsigned char retry = 255;		//因故障接收方无ACK,重试255次
	SDA = 1;
	NOP();
	SCL = 1;
	NOP();
//	m24C01Error = 0x00;
	while(SDA)
    {
		retry --;
		if(!retry)
		{
			I2CStop();
//			m24C01Error = ERROR;		// 24C01出错
			return 0;
		}
	}
	SCL = 0;
	return 1;
}

void SendAck(void)
{
	SDA = 0;
	NOP();
	SCL = 1;
	NOP();
	SCL = 0;
}

void SendNotAck(void)
{
	SDA = 1;
	NOP();
	SCL = 1;
	NOP();
	SCL = 0;
}

void I2CSendByte(unsigned char ch)
{
	unsigned char i = 8;
	while(i--)
    {
		SCL = 0;
		NOP();
		SDA = (bit)(ch & 0x80);
		SCL = 1;
		ch <<= 1;
		NOP();
	}
	SCL = 0;
}
unsigned char I2CRecvByte(void)
{
	unsigned char i = 8;
	unsigned char dat = 0;
	SDA = 1;
	while(i--)
	{
		dat <<= 1;
		SCL = 0;
		NOP();
		SCL = 1;
		NOP();
		NOP();
		NOP();
		dat |= SDA;
	}
	SCL = 0;
	return(dat);
}

BYTE SP3767Read(void)
{
	unsigned char i;

	I2CStart();					// 启动总线
	I2CSendByte(0xc1);			// 发送设备写地址

	if(WaitAck())				// 等待应答
	{
		for(i = 0; i < 5; i ++)
		{
			bFmReadData[i] = I2CRecvByte();
			SendAck();			// 发送应答
		}
		SendNotAck();				// 发送NoAck
		I2CStop();					// 停止总线	
		return 1;
	}
	else return 0;

}

BYTE SP3767Write(void)
{
	unsigned char i;

	I2CStart();						// 启动总线
	I2CSendByte(0xc0);				// 发送设备地址
	
	if(WaitAck())					// 等待应答
	{
		for(i = 0; i < 5; i ++)
		{
			I2CSendByte(bFmWriteData[i]);
			if(!WaitAck())
			{
				I2CStop();
				printf("write 3767 err0\n");
				return 0;
			}
		}
		I2CStop();						// 停止总线
		return 1;
	}
	else
	{
		I2CStop();						// 停止总线
		printf("write 3767 err1\n");
		return 0;
	}
}

WORD CalculatePLL(void)
{
	if(fHILOInjection)
		return (WORD)((((DWORD)wFmFreq * 100000) + 225000) >> 13);//HILO injection=1
	else
		return (WORD)((((DWORD)wFmFreq * 100000) - 225000) >> 13);//HILO injection=0
}

WORD ConvertPLL(WORD wPll)
{
	if(fHILOInjection)
		return (((((DWORD)wPll << 13) - 225000) / 100000) + 1);	// HILo injection=1;
	else
		return (((((DWORD)wPll << 13) + 225000) / 100000) + 1);// HILo injection=0;
}

bit FmInit(void)
{
	unsigned char TP_BYTE_0;

	for(TP_BYTE_0 = 0; TP_BYTE_0 < 5; TP_BYTE_0 ++)
	{
		bFmReadData[TP_BYTE_0] = 0;
		bFmWriteData[TP_BYTE_0] = 0;
	}

	fHILOInjection = FM_HI_INJEC;


	bFmWriteData[2] = 0x00;//low injection ,stereo on,left not muted,right not muted,SW port1 low
#ifdef BAND_USA
	bFmWriteData[3] = 0x1e;//SW port2 low,standby off,US/Europe FM band limit,xtal=32.768kHz,Soft-mute on,HCC on,SNC on,pin 14 is SW port1;
#else
	bFmWriteData[3] = 0x3e;
#endif
	bFmWriteData[4] = 0x40;
#define		SP3767_ID		0x00
#define		SP3767_RSV		0x00
	if(SP3767Read())
	{
		if((bFmReadData[3] & 0x0F) == SP3767_ID && bFmReadData[4] == SP3767_RSV)
			return 1;
		else return 0;
	}
	else return 0;
}

bit FmSetFreq(void)
{
	WORD TP_WORD_0;
#define wPLL	TP_WORD_0
	wPLL = CalculatePLL();
	if (fHILOInjection)
		bFmWriteData[2] |= FM_HI_INJECTION_EN;
	else
		bFmWriteData[2] &= FM_LO_INJECTION_EN;

	bFmWriteData[0]=((wPLL >> 8) & FM_CMD_MUTE_DIS) & FM_CMD_SEARCH_DIS; //not mute and not in search mode
	bFmWriteData[1] = wPLL ;
	bFmWriteData[2] &= 0xF0;

	return SP3767Write();
}

bit Search(bit fSearchUp)
{
	unsigned short wPLL;		//		TP_WORD_1 //TP_BYTE_2
	unsigned short wTimeOut2;	//		TP_WORD_3 // TP_BYTE_6
	unsigned char bNowStopLevel;//		TP_BYTE_14

	unsigned char bLevel;
	unsigned char bIFCounter;
	unsigned short wFreqSave;
	

//===========指定频率 =============
	if(fHand)
	{	
//		fHILOInjection = FM_LO_INJEC;
		fHILOInjection = FM_HI_INJEC;
		bNowStopLevel = FM_CMD_STOP_HIGH;			// Use Low Level for search default
		wFreqSave = wFmFreq;		
		printf("wFmFreq: %d.%d MHz\n",(unsigned short)(wFmFreq / 10),(unsigned short)(wFmFreq % 10));
		wPLL = CalculatePLL();
		printf("PLL: %x\n",(unsigned short)wPLL);	
		bFmWriteData[0] = ((BYTE)(wPLL >> 8) & (~FM_CMD_SEARCH_EN) | FM_CMD_MUTE_EN);
		bFmWriteData[1] = (BYTE)wPLL;
		bFmWriteData[2] = (((BYTE)fSearchUp) << 7) | bNowStopLevel;
		bFmWriteData[2] |= FM_HI_INJECTION_EN;
	
		SP3767Write();		//Start Search
		DelayMs(10);
		SP3767Read();
		bLevel = (bFmReadData[3] & 0xF0) >> 4;	
		DelayMs(100);
		SP3767Read();
		bIFCounter = bFmReadData[2] & FM_GET_IF;
		printf("bLevel: %d,		bIFCounter: %x\n",(unsigned short)bLevel,(unsigned short)bIFCounter);
		return 1;
	}
//===================end=======================

//===================下面是自动=======================
RETRY:
	bNowStopLevel = FM_CMD_STOP_MID;			// Use Low Level for search default
	fHILOInjection = FM_HI_INJEC;

	while(1)
	{
		wFreqSave = wFmFreq;
		wPLL = CalculatePLL();
		printf("Search wFmFreq: %d.%d MHz\n",(unsigned short)(wFmFreq / 10),(unsigned short)(wFmFreq % 10));
		printf("Search PLL: %x\n",(unsigned short)wPLL);
		bFmWriteData[0] = ((BYTE)(wPLL >> 8) | FM_CMD_SEARCH_EN | FM_CMD_MUTE_EN);
		bFmWriteData[1] = (BYTE)wPLL;		
		bFmWriteData[2] = (((BYTE)fSearchUp) << 7) | bNowStopLevel;
		bFmWriteData[2] |= FM_HI_INJECTION_EN;

		SP3767Write();		//Start Search
		DelayMs(100);
		wTimeOut2 = 0xFFFF;
		SP3767Read();
		do
		{
			wPLL = bFmReadData[0] & 0x3F;
			wPLL = (wPLL << 8) | bFmReadData[1];
			wFmFreq = ConvertPLL(wPLL);
			printf("current freq: %d\n",wFmFreq);
			wPLL = CalculatePLL();
			bFmWriteData[0] = ((BYTE)(wPLL >> 8) | FM_CMD_SEARCH_EN | FM_CMD_MUTE_EN);
			bFmWriteData[1] = (BYTE)wPLL;
			SP3767Write();		//Start Search
			DelayMs(100);
			if(!SP3767Read()) return FALSE;
			wTimeOut2 --;
			if(wTimeOut2 == 0) return FALSE;	//Time Out
			if(bFmReadData[0] & FM_SEARCH_BAND) //Reach the band limit
			{
				printf("band over\n");
				if(fSearchUp)
					wFmFreq = 875;
				else wFmFreq = 1080;
				goto RETRY;
			}
		}while((bFmReadData[0] & FM_SEARCH_FINISH) == FALSE);	//wait search finish

		bIFCounter = bFmReadData[2] & FM_GET_IF;
		bLevel = (bFmReadData[3] & 0xF0) >> 4;

		if(0x31 < bIFCounter && bIFCounter < 0x3E && bLevel >= 7)
		{
			if(wFmFreq == wFreqSave)
			{
				if(fSearchUp)
					wFmFreq ++;
				else wFmFreq --;
				goto RETRY;
			}
		}
		else
		{
			if(fSearchUp)
				wFmFreq ++;
			else wFmFreq --;

			if(wFmFreq >= BAND_MAX)
				wFmFreq = BAND_MIN;
			if(wFmFreq <= BAND_MIN)
				wFmFreq = BAND_MAX;
			goto RETRY;
		}

		wPLL = ((WORD)(bFmReadData[0] & 0x3f)) << 8;
		wPLL |= bFmReadData[1];
		wFmFreq = ConvertPLL(wPLL);
		printf("bLevel: %d,		bIFCounter: %x\n",(unsigned short)bLevel,(unsigned short)bIFCounter);
		printf("radio return revise PLL: %x\n", wPLL);
		printf("radio return revise freq: %d.%d MHz\n",(unsigned short)(wFmFreq / 10),(unsigned short)(wFmFreq % 10));
		return 1;
	}
}

void mInitSTDIO()
{
	SCON = 0x50;
	PCON = 0x80;
	TMOD = 0x20;
	TH1 = 0xf3;  /* 24MHz晶振, 9600bps */
	TR1 = 1;
	TI = 1;
}

void main(void)
{
	unsigned char cnt;	

	DelayMs(100);

	cnt = 0;
	mInitSTDIO();

	cnt = 5;
	printf("\nstart...\n");
	while(cnt -- > 0)
	{
		LED = 0;
		DelayMs(100);
		LED = 1;
		DelayMs(100);
	}


	printf("Init SP3767\n");
	if(FmInit())
		printf("SP3767 OK\n");
	else printf("SP3767 Err\n");
	cnt = 36;
	printf("Search...\n");
#ifdef HAND
	index = 0;
	fHand = 1;
	wFmFreq = FRQ_TAB[index];
#else
	wFmFreq = 875;
#endif
	if(Search(1))
	{
		if(FmSetFreq())
			printf("set ok!\n\n");
		else
			printf("set error!\n\n");
	}
	else
		printf("search err\n\n");

	while(1)
	{
		if(!UpKey)
		{
			while(!UpKey);
#ifdef HAND
			if(index == NUM) index = 0;
			else index ++;
			wFmFreq = FRQ_TAB[index];
			fHand = 1;
#else
			wFmFreq ++;
#endif
			if(Search(1))
			{
				if(!FmSetFreq())
					printf("set err\n\n");
				else printf("set ok\n\n");
			}
			else printf("search err\n\n");
		}
		if(!DnKey)
		{
			while(!DnKey);
#ifdef HAND
			if(index == 0)
				index = NUM;
			else index --;
			wFmFreq = FRQ_TAB[index];
			fHand = 1;
#else
			wFmFreq --;
#endif
			if(Search(0))
			{
				if(!FmSetFreq())
					printf("set err\n\n");
				else printf("set ok\n\n");
			}
			else printf("search err\n\n");
			fHand = 0;
		}
	}
}

⌨️ 快捷键说明

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