本帖最后由 cak123jj 于 2015-11-14 14:33 编辑
#include "list.h"
#include "intrins.h"
#define uchar unsigned char
#define uint unsigned int
#define nop _nop_();_nop_();_nop_();
unsigned char code C51BOX2[3] _at_ 0x43; //仿真器用三字节空间
unsigned long frequency=760000; //开机初始化的电台频率为76MHz
unsigned char KeyValue; //键值
unsigned char MenuDelayTime;
sbit FmPow=P1^7;//电源
//sbit KeyGnd =P3^7;
sbit DATA_M62429=P3^0;
sbit KeyUp =P1^2;
sbit KeyDown =P1^3;
sbit CK_M62429=P3^1;
unsigned char Vol;
#define Delay1 45 //AT89C2051+12M晶振使用
#define Delay2 150
#define Delay3 2
#define Delay4 100
void Delayus(unsigned char x)
{
for(;x>0;x--);
}
void iic_start(void)
{
P30=1;
Delayus(4);
P31=1;
Delayus(4);
P30=0;
Delayus(4);
P31=0;
Delayus(4);
}
void iic_stop(void)
{
P31=0;
Delayus(4);
P30=0;
Delayus(4);
P31=1;
Delayus(4);
P30=1;
Delayus(4);
}
/* 延时子函数 */
void uDelay(unsigned char i) //us延时子函数,入口参数每加1约加100us
{
unsigned char j;
for(;i>0;i--)
{
j=Delay1;
while(--j);
}
}
void mDelay(uint Dat) //ms延时子函数
{
uint j;
for (;Dat>0;Dat--)
for (j=Delay2;j>0;j--);
}
/****************以下为EPPROM读写相关函数*******************************/
/*以下为EPPROM保护,每次操作后更改指令值,使EPPROM免于被误操作*/
void EPPROM_Protect()
{
ISP_CONTR=0x00; //更改指令值,防止出现误操作
ISP_CMD=0x00;
ISP_TRIG=0x00;
ISP_ADDRH=0x00;
ISP_ADDRL=0x00;
}
/*以下为扇区擦除指令,入口参数为扇区首地址 */
void EEPROM_Erase(uint Addr)
{
ISP_ADDRH=Addr/0x100; //待写入扇区首地址
ISP_ADDRL=0x00;
ISP_CONTR=0x83;
ISP_CMD=0x03; //扇区擦除指令
ISP_TRIG=0x46; //触发,将擦除整个扇区
ISP_TRIG=0xB9;
EPPROM_Protect(); //更改相关数值,防止误操作
}
/*以下为写入指令,入口参数为写入的地址(16位)和内容(8位),每次要写入的位置*/
void EEPROM_Write(uint Addr,uchar Data)
{
ISP_DATA=Data; //待写入值
ISP_ADDRH=Addr/0x100; //待写入扇区首地址
ISP_ADDRL=Addr%0x100;
ISP_CONTR=0x83;
ISP_CMD=0x02; //写入指令
ISP_TRIG=0x46; //触发,数据写入
ISP_TRIG=0xB9;
EPPROM_Protect(); //更改相关数值,防止误操作
}
void VolSet(uchar Volume)
{
uint Dat;
uchar i;
Volume=87-Volume; //得到要送到芯片的实际数
Dat=0x600|(Volume&0xfc)|((Volume&0x03)<<7); //音量合并成控制数据,详看DATASHEET
for (i=0;i<10;i++) //发送10位数据,共11位,最后1位另外发
{
DATA_M62429=Dat&0x01;
nop;
DATA_M62429=0;
Dat>>=1;
}
DATA_M62429=1;
CK_M62429=1;
nop;
CK_M62429=0;
}
void DatSave()
{
EEPROM_Erase(0x1000);
EEPROM_Write(0x1000,Vol);
EEPROM_Write(0x1001,frequency/0x100);
EEPROM_Write(0x1002,frequency%0x100);
}
/************************按键读取及处理子函数**************************/
void KeyRead() //读键值子函数。返回值:1、2、3、31、4、41。(31、41为长按)
{
unsigned char i=250;
KeyUp=1;
KeyDown=1;
if(KeyUp&KeyDown)
{
KeyValue=0;
return;
}
MenuDelayTime=0; //清延时计数器
mDelay(10);
if(!KeyUp)
{
if(KeyValue)
return; //短按
while(i)
{
if(KeyUp)
{
KeyValue=3;
return;
}
mDelay(3);
i--;
} //短按
KeyValue=31; //长按
return;
}
if(!KeyDown)
{
if(KeyValue)
return;//短按
while(i)
{
if(KeyDown)
{
KeyValue=4;
return;
}
mDelay(3);
i--;
} //短按
KeyValue=41; //长按
return;
}
}
void KeyProc() //键值处理子函数3、4、31、41
{
switch(KeyValue)
{
case 3:
if(FmPow)
break; //关机状态下不处理这个按键
if(Vol)
Vol--;
VolSet(Vol);
KeyValue=0;
DatSave();
break;
case 4:
if(FmPow)
break; //关机状态下不处理这个按键
if(Vol<83)
Vol++; //音量减
VolSet(Vol);
KeyValue=0;
DatSave();
break;
case 31: //KeyUp长按处理
if(FmPow)
break;
if(Vol>4)
Vol-=5;
else
Vol=0;
VolSet(Vol);
mDelay(600);
DatSave();
break;
case 41: //KeyDown长按处理
if(FmPow)
break;
Vol+=5;
if(Vol>83)
Vol=83;
VolSet(Vol);
mDelay(600);
DatSave();
break;
}
}
/****************************主函数*******************************/
void main()
{
mDelay(1000); //开机延时,等待设备稳定
while(frequency != 760000)
{
iic_stop(); //去噪音
}
iic_start();
while(1)
{
KeyRead();
KeyProc();
};
}
|