1、 晶振:8M
*/
#include
2、sbit key2 = P2^7; sbit key3 = P2^6; sbit key4 = P2^5; // P3^7; sbit LcdEn = P3^4; sbit LcdRs = P3^5; uchar Channel = 0; uchar FreqTune = 0; const uint MinFreq = 870; //起始频率 * 100KHz const uint MaxFreq = 1080; //最高频率 * 100KHz const uchar FmAddr = 0×22; //FM模块IIC 地址 const uchar Ep
3、Addr = 0xA0; //24C02 EPPRom 的地址 uchar RSSI = 0; //信号强度 uchar ChannelTune[ChannelCount]; uchar code LevlChar[5][8] = {{0x1F,0×11,0x0A,0×04,0×04,0×04,0×04,0×04}, {0×00,0×00,0×00,0×00,0×00,0×00,0×06,0x1E}, {0×00,0×00,0×00,0×00,0×06,0x1E,0x1E,0x1E}, //显示型号强度的自定义字符 {0×00,0×00,
4、0×06,0x1E,0x1E,0x1E,0x1E,0x1E}, {0×06,0x1E,0x1E,0x1E,0x1E,0x1E,0x1E,0x1E}}; uchar vol = 0×8; //音量0~0xF uchar Func = 0×0; //当前功能号 bit AutoScan = 0; //标记当前是不是在自动搜台 bit Mute = 0; //标记是否被静音 uchar KeyNumber = 0; void OpenIIC(); void CloseIIC(); void IICWrite(uchar uaddr, uchar r
5、omaddr, uint rdata,bit _i6b); void IICWriteByte( uchar byte ); uint IICRead(uchar uaddr, uchar romaddr,bit _i6b); uchar IICReadByte(bit next); void FM_SetFreq(); void FM_SetVolume(); uint FM_ReadReg(uchar regAddr); //读取FM模块的寄存器 void FM_WriteReg(uchar regAddr,uint dat); //写FM模块的寄存器 uchar
6、FM_GetRSSI(); //获取当前的信号强大 void Delay(uint c); bit KeyScan(); void BeginScan(); void Lcd_DispNumber(uint number); void Lcd_Init(); void Lcd_Comm(uchar cmd); void Lcd_Data(uchar dat); void Lcd_String(char* dat); void Lcd_DispRssi(); void Lcd_DispFreq(); void Lcd_Refresh(); vo
7、id Lcd_DispDiscript(); void Eprom_LoadInitData(); uint Eprom_Read(uchar addr,bit _16bit); void Eprom_Write(uchar addr,uint dat,bit _16bit); void main() { P3 = 0xff; P2 = 0xff; Delay(10000); //延时,等待外部FM模块的启动 Eprom_LoadInitData(); //从EppRom 加载频道音量等信息 FM_Write
8、Reg(2,0xd281); //启动FM模块 FM_SetVolume(); //设置启动音量 FM_SetFreq(); //设置默认频道的频率 Lcd_Init(); Lcd_Refresh(); while(1) { if( KeyScan()) { Lcd_Refresh(); } } } void Eprom_LoadInitData() { uint result = 0; int i=0; result =Eprom_Read(0,0); if(result>0)
9、{ vol = (uchar)result – 1;}
result =Eprom_Read(1,0);
Channel = (uchar)result;
for(i=0;i 10、t,_16bit);
}
uint Eprom_Read(uchar addr,bit _16bit)
{
return IICRead(EpAddr,addr,_16bit);
}
uint FM_ReadReg(uchar regAddr)
{
return IICRead(FmAddr,regAddr,1);
}
void FM_WriteReg(uchar regAddr,uint dat)
{
IICWrite(FmAddr,regAddr,dat,1);
}
void FM_SetFreq()
{
FM_WriteReg(3,(FreqTu 11、ne<<6) | 0×10);
}
void FM_SetVolume()
{
uint reg2H;
if(vol>0)
{
if(Mute)
{
reg2H = FM_ReadReg(2);
reg2H |= 0×4000;
FM_WriteReg(2,reg2H);
}
Mute = 0;
FM_WriteReg(5,vol);
}
else
{
Mute = 1;
reg2H = FM_ReadReg(2);
reg2H &= 0xBFFF;
FM_WriteReg(2,re 12、g2H);
}
Eprom_Write(0,vol+1,0);
}
void Lcd_Init()
{
uchar CGRamAddr = 0×40;
int i,j;
LcdEn = 0;
Lcd_Comm(0×38);
Lcd_Comm(0x0c);
Lcd_Comm(0×06);
Lcd_Comm(0×01);
for(j=0;j<5;j++){
Lcd_Comm(CGRamAddr + 8 * j); //建立自定义字符 (显示信号强度的)
for(i=0;i<8;i++)
{
Lcd_Data 13、LevlChar[j][i]);
Delay(510);
}
}
}
void Lcd_Comm(uchar cmd)
{
LcdRs =0;
P0 = cmd;
Delay(50);
LcdEn = 1;
Delay(50);
LcdEn = 0;
}
void Lcd_Data(uchar dat)
{
LcdRs = 1;
P0 = dat;
Delay(50);
LcdEn = 1;
Delay(50);
LcdEn = 0;
}
void Lcd_String(char* dat)
{
cha 14、r *p;
int j, i=strlen(dat);
for(j=0;j=1) Lcd_Data(0×01);
if(RSSI>=2) 15、Lcd_Data(0×02);
if(RSSI>=3) Lcd_Data(0×03);
if(RSSI>=4) Lcd_Data(0×04);
}
void Lcd_DispFreq()
{
uint curFreq = MinFreq + FreqTune;
int i;
Lcd_Comm(0×85);
for(i=5;i<16;i++)
{
Lcd_Data(‘ ‘);
}
Lcd_Comm(0×80+6);
if(curFreq>=1000)Lcd_Data(48 +curFreq /1000 % 10);
Lcd_Data(4 16、8 +curFreq /100 % 10);
Lcd_Data(48 +curFreq /10 % 10);
Lcd_Data(‘.’);
Lcd_Data(48 + curFreq % 10);
Lcd_Data(‘M’);
Lcd_Data(‘H’);
Lcd_Data(‘Z’);
}
void Lcd_DispDiscript()
{
int i;
Lcd_Comm(0×80+0×40);
for(i=0;i<15;i++)
{
Lcd_Data(‘ ‘);
}
Lcd_Comm(0×80+0×40);
17、 switch(Func)
{
case 0:
Lcd_String(“Channel:”);
Lcd_DispNumber(Channel+1);
break;
case 1:
Lcd_String(“Volume:”);
Lcd_DispNumber(vol);
break;
case 2:
Lcd_String(“Tune”);
break;
case 3:
Lcd_String(“Auto Scan”);
}
}
void Lcd_Refresh()
{
Lcd_D 18、ispRssi();
Lcd_DispFreq();
Lcd_DispDiscript();
}
void Lcd_DispNumber(uint number)
{
int i=0,len;
char str[6]={‘\0′,’\0′,’\0′,’\0′,’\0′,’\0′};
char temp;
do
{
str[i++] = ’0′ + (number % 10);
number /= 10;
}while(number) ;
len = strlen(str);
for(i=0;i 19、mp = str[i];
str[i] = str[len-i-1];
str[len-i-1] = temp;
}
Lcd_String(str);
}
bit KeyScan()
{
bit keyRel = 0; //按键释放检测
char value=0;
int i;
uint temp;
if(AutoScan) return 0;
if(KeyNumber==0)
{
if(key3==0)
{
Delay(50);
if(key3==0)
{
KeyNumber 20、 =3;
}
}
if(key4==0)
{
Delay(50);
if(key4==0)
{
KeyNumber=4;
}
}
if(key2==0)
{
Delay(50);
if(key2==0)
{
KeyNumber=2;
}
}
return 0;
}
else
{
switch(KeyNumber)
{
case 1:
if(key1== 21、1)keyRel = 1; break;
case 2:
if(key2==1)keyRel = 1; break;
case 3:
if(key3==1)keyRel = 1; break;
case 4:
if(key4==1)keyRel = 1; break;
}
if(keyRel)
{
switch(KeyNumber)
{
case 2:
Func++;
if(Func>3) Func = 0;
break;
22、 case 3:
value = -1;
break;
case 4:
value = 1;
break;
}
if(KeyNumber>2)
{
if(Func==0)
{
if((value > 0 && Channel 23、hannel];
FM_SetFreq();
Eprom_Write(1,Channel, 0);
}
}
else if(Func==1)
{
if((value > 0 && vol<0xF) || (value<0 && vol > 0))
{
vol+=value;
FM_SetVolume();
}
}
else if(Func==2)
{
if((value > 0 & 24、 FreqTune<0xd2) || (value<0 && FreqTune > 0))
{
FreqTune+=value;
ChannelTune[Channel] = FreqTune;
FM_SetFreq();
Eprom_Write(Channel * 2 + 2 ,FreqTune,1);
}
}
else if(Func==3) //开始自动扫描
{
AutoScan = 1;
BeginScan();
25、AutoScan = 0;
Channel = 0;
FreqTune = ChannelTune[0];
Func = 0;
FM_SetFreq();
//覆盖EppRom中的所有的频道
for(i=0;i 26、
}
}
KeyNumber=0;
}
return keyRel;
}
}
//全自动搜索
void BeginScan()
{
uint state;
int i=0,count=0;
bit cmp = 0;
uint seekth = 0×8; //灵敏度 0~127,默认为8 灵敏度越低越可能搜索到假台,高了可能一些信号弱一点的频道被跳过。
uint reg5H;
uint tempTune = 0;
for(i=0;i 27、电台数据
{
ChannelTune[i]=0;
}
reg5H = FM_ReadReg(0×05);
reg5H = (reg5H & 0x80FF) | (seekth<<7);
FM_WriteReg(0×05,reg5H);
for(i=0;i<=MaxFreq – MinFreq;i++)
{
FreqTune = i;
FM_SetFreq();
Lcd_DispFreq();
do
{
state = FM_ReadReg(0x0B);
cmp = (state>> 28、 7 ) & 0×1;
}while(!cmp);
Delay(100);
state = FM_ReadReg(0x0B);
cmp = (state >> 8 ) & 0×1;
if(cmp)
{
ChannelTune[count]=i;
count++;
}
if(count>=ChannelCount){ break; }
}
}
uchar FM_GetRSSI()
{
uint regVal =FM_ReadReg(0x0b);
regVal = regVal>>9;
retu 29、rn (uchar)(regVal/16);
}
void Delay(uint c)
{
int i=0;
for(i=0;i 30、 buf = buf<<8;
buf =buf | IICReadByte(0);
}
else
{
buf = IICReadByte(0);
}
CloseIIC();
return buf;
}
uchar IICReadByte(bit next)
{
uchar buf =0,i=0;
for(i=0;i<8;i++)
{
buf <<=1;
SCL = 1;
buf |= SDA;
Delay(5);
SCL = 0;
Delay(5);
}
if(next)
{
SD 31、A = 0;
SCL = 1;
Delay(5);
SCL = 0;
Delay(5);
SDA = 1;
}
else
{
SDA = 1;
SCL = 1;
Delay(5);
SCL = 0;
Delay(5);
SDA=0;
}
return buf;
}
void IICWrite(uchar uaddr, uchar romaddr, uint rdata,bit _16b)
{
uchar temp;
OpenIIC();
IICWriteByte(uaddr);
I 32、ICWriteByte(romaddr);
if(_16b)
{
temp =(uchar)((rdata>>8) & 0x00ff) ;
IICWriteByte(temp);
}
temp = (uchar) (rdata & 0xff);
IICWriteByte(temp);
CloseIIC();
}
void IICWriteByte( uchar byte )
{
uchar i=0;
int f=30000;
bit bitdata;
for(i=0;i<8;i++)
{
33、 bitdata =byte>>(7-i) & 1;
SDA = bitdata;
SCL =1;
Delay(5);
SCL = 0;
Delay(5);
}
SCL = 1;
while(SDA && –f);
Delay(5);
SCL = 0;
Delay(5);
}
void CloseIIC()
{
SDA = 0 ;
SCL = 1;
Delay(5);
SDA = 1;
Delay(5);
SCL = 1;
SDA = 1;
Delay(150); //防止过快的读取造成EPPROM 来不及反应
}
void OpenIIC()
{
SDA = 1;
SCL = 1;
Delay(5);
SDA = 0;
Delay(5);
SCL = 0;
Delay(5);
}
/****************************************************************************************************************/






