/*************************************************************************************************** TEA5767采用I2C接口控制.TEA5767读写数据都是5个字节,其中PLL参数14位. 以下程序中的函数可以直接在主程序中调用.Fosc =11.0592Mhz. PCB:WRT-TEST BOARD VER:A0 ****************************************************************************************************/ #include #include #include "tea5767.h" #include "iic.h" #include "key.h" #include "led.h" /***********************************************************************************/ #define XTAL32K #define max_freq 108000 //108Mhz #define min_freq 87500 //87.5Mhz #define max_pll 0x339b //108MHz时的pll. #define min_pll 0x299d //87.5MHz时的pll. #define Add_Freq 1 #define Dec_Freq 0 #ifdef XTAL32K #define REFERENCE_FREQ 32.768 #else #define REFERENCE_FREQ 50.000 #endif unsigned char radio_write_data[5]={0x2A,0xB6,0x40,0x11,0x40}; //初始化写入TEA5767的数据(FM89.8Mhz) unsigned char radio_read_data[5]; unsigned int Pll_Data; unsigned long Frequency_Data; /***********************************************************************************/ void Initialization(void) { TMOD = 0x11; TH0 = 0x5d; TL0 = 0x3d; TR0 = 0; //25ms TH1 = 0x5d; TL1 = 0x3d; TR1 = 0; //25ms T2CON = 0x30; T2MOD = 0x00; RCAP2H = 0xFE; TH2 = RCAP2H; RCAP2L = 0xFB; TL2 = RCAP2L; TR2 = 0; //2400bps PCON = 0x00; SCON = 0xD0; IP = 0x14; EX0 = 1; IT0 = 1; ET0 = 1; EX1 = 1; IT1 = 1; ES = 0; EA = 0; } /***********************************************************************************/ //读TEA5767状态,并转换成频率 void Radio_Read(void) { unsigned char i; unsigned char temp_l,temp_h; Pll_Data = 0; ATIICxx_PRead(&radio_read_data[0],5); temp_l = radio_read_data[1]; temp_h = radio_read_data[0]; temp_h &= 0x3f; Pll_Data = temp_h*256+temp_l; Get_Frequency(); } /***********************************************************************************/ //由PLL计算频率 void Get_Frequency(void) { unsigned char hlsi; unsigned int npll = 0; npll = Pll_Data; hlsi = radio_read_data[2]&0x10; if (hlsi) Frequency_Data = (unsigned long)((float)(npll)*(float)REFERENCE_FREQ*(float)0.25-225); //频率单位:KHz else Frequency_Data = (unsigned long)((float)(npll)*(float)REFERENCE_FREQ*(float)0.25+225); //频率单位:KHz } /***********************************************************************************/ //由频率计算PLL void Get_Pll(void) { unsigned char hlsi; hlsi = radio_read_data[2]&0x10; if (hlsi) Pll_Data = (unsigned int)((float)((Frequency_Data+225)*4)/(float)REFERENCE_FREQ); //频率单位:k else Pll_Data = (unsigned int)((float)((Frequency_Data-225)*4)/(float)REFERENCE_FREQ); //频率单位:k } /***********************************************************************************/ //手动设置频率,mode=1,+0.1MHz; mode="0:-0".1MHz ,不用考虑TEA5767用于搜台的相关位:SM,SUD void Search(unsigned char mode) { Radio_Read(); if(mode) { Frequency_Data += 100; if(Frequency_Data > max_freq) Frequency_Data = min_freq; } else { Frequency_Data -= 100; if(Frequency_Data < min_freq) Frequency_Data = max_freq; } Get_Pll(); radio_write_data[0] = Pll_Data/256; radio_write_data[1] = Pll_Data%256; radio_write_data[2] = 0x41; radio_write_data[3] = 0x11; radio_write_data[4] = 0x40; ATIICxx_PWrite(&radio_write_data[0],5); } /***********************************************************************************/ //自动搜台,mode=1,频率增加搜台; mode="0:频率减小搜台". void Auto_Search(unsigned char mode) { Radio_Read(); Get_Pll(); if(mode) { radio_write_data[2] = 0xb1; if(Pll_Data > max_pll) { Pll_Data = min_pll; } } else { radio_write_data[2] = 0x41; if(Pll_Data < min_pll) { Pll_Data = max_pll; } } radio_write_data[0] = Pll_Data/256+0x40; radio_write_data[1] = Pll_Data%256; radio_write_data[3] = 0x11; radio_write_data[4] = 0x40; ATIICxx_PWrite(&radio_write_data[0],5); Radio_Read(); while(!(radio_read_data[0]&0x80)) //RF电台就绪标志 { Radio_Read(); } } /***********************************************************************************/ void main(void) { unsigned char i; Initialization(); radio_write_data[0] = 0x2A; radio_write_data[1] = 0xB6; radio_write_data[2] = 0x41; radio_write_data[3] = 0x11; radio_write_data[4] = 0x40; ATIICxx_PWrite(&radio_write_data[0],5);//初始化TEA5767(87.5Mhz) Frequency_Data = 89800; while(1) { i = GetKey(); Led_Display(Frequency_Data); switch (i) { case 0x00: { Search(Add_Freq); }; break; case 0x01: { Search(Dec_Freq); }; break; case 0x02: { Auto_Search(Add_Freq); }; break; case 0x03: { Auto_Search(Dec_Freq); }; break; default: break; } } } #include #include #include "iic.h" #include "key.h" /*********************************************************************/ /* IIC读写程序芯片型号*/ /*********************************************************************/ /*********************************************************************/ sbit I2C_SCK=P3^5; /*实时时钟时钟线引脚 */ sbit I2C_SDA=P3^4; /*实时时钟数据线引脚 */ /*********************************************************************/ #define ATIIcxxDriverAddressW 0xC0 #define ATIIcxxDriverAddressR 0xC1 #define _Nop() _nop_(),_nop_(),_nop_(),_nop_(),_nop_() /*定义空指令*/ /*********************************************************************/ struct bytedata_2 { unsigned char ByteH; unsigned char ByteL; }; union int2byte { unsigned int IntData; struct bytedata_2 ByteData; }; /*********************************************************************/ //启动I2C总线,退出时SCL为低 void I2C_Start(void) { I2C_SDA=1; /*发送起始条件的数据信号*/ _Nop(); I2C_SCK=1; _Nop(); /*起始条件建立时间大于4.7us,延时*/ _Nop(); _Nop(); _Nop(); _Nop(); I2C_SDA=0; /*发送起始信号*/ _Nop(); /* 起始条件锁定时间大于4μs*/ _Nop(); _Nop(); _Nop(); _Nop(); I2C_SCK=0; /*钳住I2C总线,准备发送或接收数据 */ } //*停止I2C总线 void I2C_Stop(void) { I2C_SCK=0; I2C_SDA=0; /*发送结束条件的数据信号*/ _Nop(); /*发送结束条件的时钟信号*/ I2C_SCK=1; /*结束条件建立时间大于4μs*/ _Nop(); _Nop(); _Nop(); _Nop(); _Nop(); I2C_SDA=1; /*发送I2C总线结束信号*/ } //MCU等待应答位(返回0表示应答) bit I2C_WaitAck(void) { unsigned char ucErrTime = 200; //因故障接收方无ACK,超时值。 I2C_SCK=0; I2C_SDA=1; _Nop(); I2C_SCK=1; while(I2C_SDA) { ucErrTime--; if (ucErrTime == 0) { I2C_Stop(); return 0; } } I2C_SCK=0; return 1; } //MCU应答信号 void I2C_Ack(void) { I2C_SCK=0; I2C_SDA=0; _Nop(); _Nop(); _Nop(); _Nop(); _Nop(); I2C_SCK=1; _Nop(); _Nop(); _Nop(); _Nop(); _Nop(); I2C_SCK=0; } //MCU发送非应答信号 void I2C_Noack(void) { I2C_SCK=0; I2C_SDA=1; _Nop(); _Nop(); I2C_SCK=1; _Nop(); _Nop(); I2C_SCK=0; } void I2C_Send_Byte(unsigned char sendbyte) { unsigned char i = 8; while( i-- ) { I2C_SCK = 0; _Nop(); //_Nop(); if ( sendbyte &0x80 ) I2C_SDA =1; else I2C_SDA =0; _Nop(); //_Nop(); I2C_SCK = 1; _Nop(); //_Nop(); sendbyte <<= 1; } I2C_WaitAck(); } static unsigned char I2C_Receive_Byte(void) { unsigned char i = 8, data_buffer; I2C_SDA = 1; while ( i--) { I2C_SCK =0; _Nop();_Nop(); I2C_SCK =1; _Nop();_Nop(); data_buffer <<= 1; if ( I2C_SDA ) data_buffer++; } return (data_buffer); } void ATIICxx_PWrite(unsigned char *McuAddress,unsigned char count) { I2C_Start(); I2C_Send_Byte( ATIIcxxDriverAddressW ); while(count--) { I2C_Send_Byte( *(unsigned char*)McuAddress ); ((unsigned char*)McuAddress)++; } I2C_Stop(); } void ATIICxx_PRead(unsigned char *McuAddress,unsigned char count) { I2C_Start(); I2C_Send_Byte( ATIIcxxDriverAddressR ); while(count--) { *McuAddress = I2C_Receive_Byte(); I2C_Ack(); McuAddress++; } I2C_Noack(); I2C_Stop(); } #include #include #include "key.h" /************************************************************************/ #define KEY P0 //定义P0口为键盘接口 /************************************************************************/ /************************************************************************/ void DelayK(unsigned char Time) { unsigned char i; while( --Time != 0) { for(i = 0; i < 125; i++); //i 从0加到125,CPU大概就耗时1 毫秒 。 } } /************************************************************************/ unsigned char GetKey() //键盘处理函数 { unsigned char m,n,e=0xff; //定义3 个变量 KEY = 0x0f; //键盘口置00001111 if (KEY != 0x0f) //查寻键盘口的值是否变化 { DelayK(20); //延时20毫秒 if (KEY != 0x0f) //有键按下处理 { m = KEY; //键值放入寄存器m } KEY = 0xf0; //将键盘口置为11110000 n = KEY; //将第二次取得值放入寄存器n m |= n; //将两个数据熔合 switch(m) //对比数据值 { case 0x7e: e = 0x00; break;//对比得到的键值给e一个应用数据 case 0xbe: e = 0x01; break; case 0xde: e = 0x02; break; case 0xee: e = 0x03; break; case 0x7d: e = 0x04; break; case 0xbd: e = 0x05; break; case 0xdd: e = 0x06; break; case 0xed: e = 0x07; break; case 0x7b: e = 0x08; break; case 0xbb: e = 0x09; break; case 0xdb: e = 0x0a; break; case 0xeb: e = 0x0b; break; case 0x77: e = 0x0c; break; case 0xb7: e = 0x0d; break; case 0xd7: e = 0x0e; break; case 0xe7: e = 0x0f; break; default: break; //键值错误处理 } } KEY = 0x0f; while (KEY != 0x0f); return (e); //将e作为返回值 } /************************************************************************/ #include #include #include "led.h" /************************************************************************/ sbit ge="P1"^3; sbit shi="P1"^2; sbit bai="P1"^1; sbit qan="P1"^0; #define LED P1 //unsigned char tab[]={ 0x3f,0x30,0x6d,0x79,0x72,0x5b,0x5f,0x31,0x7f,0x7b,0x40};//共阴 //0, 1, 2 3 4 5 6 7 8 9 unsigned char tab[]={ 0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90};//共阳 //0, 1, 2 3 4 5 6 7 8 9 /************************************************************************/ void DelayD(unsigned char Time) { unsigned char i; while( --Time != 0) { for(i = 0; i < 125; i++); //i 从0加到125,CPU大概就耗时1 毫秒 。 } } /************************************************************************/ void Led_Display(unsigned long i) //显示函数 { LED = tab[i/100000]; qan = 1; bai = 0; shi = 0; ge = 0; DelayD(1); LED = tab[(i%100000)/10000]; qan = 0; bai = 1; shi = 0; ge = 0; DelayD(1); LED = tab[((i%100000)%10000)/1000]; qan = 0; bai = 0; shi = 1; ge = 0; DelayD(1); LED = tab[(((i%100000)%10000)%1000)/100]; qan = 0; bai = 0; shi = 0; ge = 1; DelayD(1); } /*头文件*/ #ifndef _IIC_H_ #define _IIC_H void ATIICxx_PWrite(unsigned char *McuAddress,unsigned char count); void ATIICxx_PRead(unsigned char *McuAddress,unsigned char count); void I2C_Send_Byte(unsigned char sendbyte); unsigned char I2C_Receive_Byte(void); void I2C_Start(void); void I2C_Stop(void); void I2C_Ack(void); void I2C_Noack(void); #endif #ifndef _KEY_H_ #define _KEY_H_ unsigned char GetKey(); void Delay(unsigned char Time); #endif #ifndef _LED_H_ #define _LED_H_ void Led_Display(unsigned long i); void DelayD(unsigned char Time); #endif #ifndef _TEA5767_H_ #define _TEA5767_H_ void Initialization(void); void Get_Pll(void); void Get_Frequency(void); void Search(unsigned char mode); void Auto_Search(unsigned char mode); #endif
|