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

📄 tea5767_driver.c

📁 LPC2148控制tea5767收音模块的收音机的完整源程序
💻 C
字号:
/****************************************Copyright (c)**************************************************
**                               Guangzou ZLG-MCU Development Co.,LTD.
**                                      graduate school
**                                 http://www.zlgmcu.com
**
**--------------File Info-------------------------------------------------------------------------------
** File name:			main.c
** Last modified Date:  2004-09-16
** Last Version:		1.0
** Descriptions:		The main() function example template
**
**------------------------------------------------------------------------------------------------------
** Created by:			Chenmingji
** Created date:		2004-09-16
** Version:				1.0
** Descriptions:		The original version
**
**------------------------------------------------------------------------------------------------------
** Modified by:
** Modified date:
** Version:
** Descriptions:
**
********************************************************************************************************/
#include "config.h"
#include "I2C1INT.h"
/*****************************************************************************/
#define		tea5767_address			0xc0
#define		tea5767_write			0xc0	//地址+读写位(写为0,读为1)
#define		tea5767_read			0xc1	//地址+读写位(写为0,读为1)
/*write	mode*/
	/*byte 1*/
#define		tea5767_mute			0x80	//byte1,该位为1时静音
#define		tea5767_search_mode		0x40	//byte1,该位为1时在搜索模式
#define		tea5767_pll13_8			0x3f	//byte1,该六位组合位设置可编程频率合成器的搜索值或预置值pll(13-8)
	/*byte 2*/
#define		tea5767_pll7_0			0xff	//byte2,该八位组合位设置可编程频率合成器的搜索值或预置值pll(7-0)
	/*byte 3*/
#define		tea5767_search_dir		0x80	//byte3,该位为1时向上搜索,为0时向下搜索
#define		tea5767_search_level	0x60	//byte3,该两位组合位设置搜索停止级别,为00时允许在搜索模式,为01时为低级ADC=5;
											   //为10时为中级ADC=7,为11时为高级ADC=10
#define		tea5767_hlsi			0x10	//byte3,该位为1时注入最高频率,为零时注入最低频率
#define		tea5767_mono_stereo		0x08	//byte3,该位为1时强制为单声道,为0时为立体声
#define		tea5767_mono_left		0x04	//byte3,该位为1时右声道静音,强制为左声道单声道
#define		tea5767_mono_right		0x02	//byte3,该位为1时左声道静音,强制为右声道单声道
	/*byte 4*/
#define		tea5767_standby			0x40	//byte4,该位为1时进入待机模式
#define		tea5767_band_limits		0x20	//byte4,该位为1时为日本频带,为0进入美国欧洲频段
#define		tea5767_xtal			0x10	//byte4,该位为1时使用32768HZ的晶振,为0时使用13M的晶振
#define		tea5767_soft_mute		0x08	//byte4,该位为1时软静音
#define		tea5767_hcc				0x04  	//byte4,该位为1时高切开关开
#define		tea5767_snc				0x02	//byte4,该位为1时立体声噪声消除开		
	/*byte 5*/
#define		tea5767_pll_ref			0x80	//byte5,该位为1时使能PLL的6.5MHZ的参考频率
#define		tea5767_dtc				0x40	//byte5,该位为1时预加重时间常数为75us,为0时为50us
/*read mode*/
	/*byte 1*/
#define		tea5767_ready_flag		0x80	//byte1,该位为1表示找到电台或到达频带极限,为0表示没有找到电台
#define		tea5767_band_limit_flag 0x40	//byte1,该位为1表示已经到达频带极限
#define		tea5767_pll13_8_read   	0x3f	//byte1,该六位组合位设置可编程频率合成器的搜索值或预置值pll(13-8)
	/*byte 2*/
#define		tea5767_pll7_0_read		0xff	//byte2,该八位组合位设置可编程频率合成器的搜索值或预置值pll(7-0)
	/*byte 3*/
#define		tea5767_stereo_flag		0x80	//byte3,该位为1表示为立体声接受
#define		tea5767_if_counter		0x7f	//byte3,该七位组合位表示IF计数器的值
	/*byte 4*/
#define		tea5767_level_adc_out	0xf0	//byte4,该四位组合位表示ADC输出级别	


#define		max_num		20				//设置存储的电台数量

uint8	tea5767_tx[5];					//要发送的5个字节
uint8	tea5767_rx[5]={0,0,0,0,0};		//要接收的5个字节

uint8 	hlsi;			//高/低电流注入
uint32 	fm_freq;   		//当前频率
uint8 	n;           	//当前电台
uint32 	station[max_num];	//电台存储
/*********************************************************************************************************
** 函数名称 :delay_ns()
** 函数功能 :长软件延时
** 入口参数 :dly	延时参数,值越大,延时越久
** 出口参数 :无
*********************************************************************************************************
*/
void delay_ns (uint32 dly)
{
	uint32 i;
	
	for ( ; dly>0; dly--)
		for (i=0; i<5000; i++);
}
/*函数定义*/
/******************************************************************************/
void write_tea5767(void)
{
	sendnbyte(tea5767_address,tea5767_tx,5);
}
void read_tea5767(void)
{
	sendnbyte(tea5767_read,tea5767_rx,5);
	delay_ns(1);
}
void mute_tea5767(uint8 in)
{
	if (in==1)
	{
		tea5767_tx[0]|=tea5767_mute;
		tea5767_tx[3]|=tea5767_soft_mute;
	}
	else if (in==0)
	{
		tea5767_tx[0]&=~(tea5767_mute);
		tea5767_tx[3]&=~(tea5767_soft_mute);
	}
}
void soft_mute(uint8 in)
{
	if (in==1)
		tea5767_tx[3]|=tea5767_soft_mute;
	else if (in==0)
		tea5767_tx[3]&=~(tea5767_soft_mute);
}
void enable_search(uint8 in)
{
	if (in==1)
		tea5767_tx[0]|=tea5767_search_mode;
	else if (in==0)
		tea5767_tx[0]&=~(tea5767_search_mode);
		
}
void search_up_down(uint8 dir)
{
	if (dir==1)
		tea5767_tx[2]|=tea5767_search_dir;
	else if (dir==0)
		tea5767_tx[2]&=~(tea5767_search_dir);
}
void search_level(uint8 level)
{
	switch(level)
	{
		case 0:tea5767_tx[2]=tea5767_tx[2]&(~(tea5767_search_level));break;
		case 1:tea5767_tx[2]=tea5767_tx[2]&(~(tea5767_search_level))|(1<<5);break;
		case 2:tea5767_tx[2]=tea5767_tx[2]&(~(tea5767_search_level))|(1<<6);break;
		case 3:tea5767_tx[2]=tea5767_tx[2]&(~(tea5767_search_level))|(1<<5)|(1<<6);break;
		default:break;
  	}
}
void tea5767_high_low_in(uint8 in)
{
	if (in==1)
		tea5767_tx[2]|=tea5767_hlsi;
	else if (in==0)
		tea5767_tx[2]&=~(tea5767_hlsi);
}
void mono_stereo_tea5767(uint8 in)
{
	if (in==1)
		tea5767_tx[2]|=tea5767_mono_stereo;
	else if (in==0)
		tea5767_tx[2]&=~(tea5767_mono_stereo);
}
void mono_left(uint8 in)
{
	if (in==1)
		tea5767_tx[2]|=tea5767_mono_left;
	else if (in==0)
		tea5767_tx[2]&=~(tea5767_mono_left);
}
void mono_right(uint8 in)
{
	if (in==1)
		tea5767_tx[2]|=tea5767_mono_right;
	else if (in==0)
		tea5767_tx[2]&=~(tea5767_mono_right);
}
void standby_tea5767(uint8 in)
{
	if (in==1)
		tea5767_tx[3]|=tea5767_standby;
	else if (in==0)
		tea5767_tx[3]&=~(tea5767_standby);
}
void band_japan_us(uint8 in)
{
	if (in==1)
		tea5767_tx[3]|=tea5767_band_limits;
	else if (in==0)
		tea5767_tx[3]&=~(tea5767_band_limits);
}
void xtal_32768_13(uint8 in)
{
	if (in==1)
		tea5767_tx[3]|=tea5767_xtal;
	else if (in==0)
		tea5767_tx[3]&=~(tea5767_xtal);
}
void hcc_on(uint8 in)
{
	if (in==1)
		tea5767_tx[3]|=tea5767_hcc;
	else if (in==0)
		tea5767_tx[3]&=~(tea5767_hcc);
}
void snc_on(uint8 in)
{
	if (in==1)
		tea5767_tx[3]|=tea5767_snc;
	else if (in==0)
		tea5767_tx[3]&=~(tea5767_snc);
}
void tea5767_pll_ref_con(uint8 in)
{
	if (in==1)
		tea5767_tx[4]|=tea5767_pll_ref;
	else if (in==0)
		tea5767_tx[4]&=~(tea5767_pll_ref);
}
void tea5767_dtc_con(uint8 in)
{
	if (in==1)
		tea5767_tx[4]|=tea5767_dtc;
	else if (in==0)
		tea5767_tx[4]&=~(tea5767_dtc);
}
/**********************************************************************/
void tea5767_init(void)
{
	//相应IO口和i2c总线初始化
	uint32 Fi2c1=100000;										//i2c总线速度设置(100k)
   	PINSEL0 = (PINSEL0 & (~(0x03 << 22))) | (0x03 << 22) |
   			  (PINSEL0 & (~(0x03 << 28))) | (0x03 << 28);
	I2C1SCLH = (Fpclk/Fi2c1 + 1) / 2;					//设定I2C1时钟 					
	I2C1SCLL = (Fpclk/Fi2c1)/2;
	I2C1CONCLR = 0x2C;
	I2C1CONSET = 0x40;									//使能主I2C1 						
	
	/* 设置I2C1中断允许 */
	VICIntSelect = 0x00000000;							//设置所有通道为IRQ中断 			
	VICVectCntl0 = (0x20 | 19);							//I2C1通道分配到IRQ slot0,最高优先级 
	VICVectAddr0 = (int32)IRQ_I2C1;						//设置I2C1中断向量 				
	VICIntEnable = (1 << 19);	
	IRQEnable();							       		// IRQ中断使能

	
	
	xtal_32768_13(1);
	tea5767_pll_ref_con(0);
	tea5767_dtc_con(0);
	hcc_on(1);
	snc_on(1);
	
	mute_tea5767(0);
	soft_mute(0);
	enable_search(0);
	standby_tea5767(0);

	tea5767_high_low_in(1);		
	search_up_down(0);
	search_level(1);
	mono_stereo_tea5767(0);
	mono_left(0);				
	mono_right(0);				
	band_japan_us(1);			
	mute_tea5767(1);

	write_tea5767();
}
void  turn_on_tea5767(void)
{
	mute_tea5767(0);	
	standby_tea5767(0);
	write_tea5767();
}
void  turn_off_tea5767(void)
{
	mute_tea5767(1);
	standby_tea5767(1);
	write_tea5767();
}
	
void  set_freq(void)	
{
	uint32 tx_pll=0;		
	uint8  tmp1;
	uint8  tmp2;
	//把频率(khz)转换成pll的值
	if (hlsi==1)
		tx_pll=(uint32)((float)((fm_freq+225)*4000))/32768;
	else if (hlsi==0)
		tx_pll=(uint32)((float)((fm_freq-225)*4000))/32768;
	tmp1=(uint8)(tx_pll/256);	
	tmp2=(uint8)(tx_pll%256);
	
	tea5767_tx[0]=tea5767_tx[0]&0x80|tmp1;
	tea5767_tx[1]=tmp2;
	write_tea5767();
}	
void  read_freq(void)
{
	uint16 tx_pll=0;
	uint8  tmp1;
	uint8  tmp2;
	read_tea5767();
	tmp1=tea5767_rx[1];
	tmp2=tea5767_rx[0]&0x3f;
	
	tx_pll=tmp2*256+tmp1;
	//把pll值转换成频率(khz)
	if (hlsi)
		fm_freq=(uint32)((float)tx_pll*(float)32.768*(float)0.25-225);
	else 
		fm_freq=(uint32)((float)tx_pll*(float)32.768*(float)0.25+225);
}
/*****************************hlsi的确定*******************************/
void fm_hilo_optimal(void)
{
	uint8 levelhigh, levellow;
	tea5767_high_low_in(1);
	fm_freq+=450;
	set_freq();
	delay_ns(30);
	read_tea5767();
	levelhigh=(tea5767_rx[3]>>4)&0x0f;
	fm_freq-=450;
	
	fm_freq-=450;
	set_freq();
	delay_ns(30);
	read_tea5767();
	levellow=(tea5767_rx[3]>>4)&0x0f;
	fm_freq+=450;

	if(levelhigh > levellow)
	{
		hlsi = 0;
		tea5767_high_low_in(0);
	}	
	else
	{
		hlsi = 1;
		tea5767_high_low_in(1);
	}
}
/***************手动对电台进行微调,步进频率为0.1MHz********************/
void fm_manual_scan(uint8 dir)//手动对电台进行微调
{	
	if(dir)
	{
		if(fm_freq >= 108000)
			fm_freq = 76000;
		else				
			fm_freq += 100;
	}
	else
	{	
		if(fm_freq <= 76000) 
			fm_freq = 108000;
		else				
			fm_freq -= 100;
	}
	if(fm_freq<=89000)
	{
		band_japan_us(0);			
		write_tea5767();
	}
	else 
	{
		band_japan_us(1);			
		write_tea5767();
	}
	fm_hilo_optimal();
	set_freq();
		
}

/*******向上(下)自动搜索,遇到电台即停止,步进频率为0.1MHz*************/
void fm_auto_scan(uint8 dir) //向上(下)自动搜索,遇到电台即停止
{
	uint8  buf[5],curlev, curifc;
	
	while(1)
	{
		fm_manual_scan(dir);
		delay_ns(30);
		read_tea5767();
		buf[2]=tea5767_rx[2];
		buf[3]=tea5767_rx[3];
		curifc =buf[2]&0x7f;
		curlev =(buf[3]>>4)&0x0f;
		if(((curlev >8) && (0x32 < curifc) && (0x3e > curifc)))
			break; 
	}
}
/******从下(上)向上(下)搜索所有电台,并全部保存,步进频率为0.1MHz******/
void auto_scan(uint8 dir)//从下(上)向上(下)搜索所有电台,并全部保存
{
	uint8  buf[5],curlev, curifc,i=0;
	if(dir)
		fm_freq=76000;
	else	
		fm_freq=108000;
	i=0;
start:
	while(fm_freq<=108000&&fm_freq>=76000)
	{
		mute_tea5767(1);
		write_tea5767();
		while(1)
		{
			fm_manual_scan(dir);
			if(fm_freq>=108000)
				goto start;
			delay_ns(30);
			read_tea5767();
			buf[2]=tea5767_rx[2];
			buf[3]=tea5767_rx[3];
			curifc =buf[2]&0x7f;
			curlev =(buf[3]>>4)&0x0f;
			if(((curlev >10) && (0x31 < curifc) && (0x3f > curifc)))
				break; 
		}
		mute_tea5767(0);
		write_tea5767();

		station[i++]=fm_freq;
		if (i==(max_num-1))
		{
			i=0;
			break;
		}
	}
}
/*************收听已存储电台*******************/
void goto_station(uint8 i)
{
	n=i;
	fm_freq=station[n];
	fm_hilo_optimal();
	set_freq();
}	
void check_mute(void)
{
	if((tea5767_tx[0]&0x80)==0x80)
		mute_tea5767(0);
	else
		mute_tea5767(1);
	
	write_tea5767();
}

/*int main(void)
{
	uint8 i;
	i=0;
	tea5767_init();
	turn_on_tea5767();
	enable_search(0);


	
	fm_freq=95500;
	fm_hilo_optimal();
	set_freq();

	auto_scan(1);
	while(1)
	{
		goto_station(i++);
		if(i>=max_num)
			i=0;
	}	
	return 0;
}*/

⌨️ 快捷键说明

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