📄 tea5767_driver.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 + -