|
发表于 2019-8-28 08:23:12
|
显示全部楼层
本帖最后由 isoimg2130 于 2019-8-28 08:27 编辑
#include "reg52.h"
#include "intrins.h"
typedef unsigned char u8;
typedef unsigned int u16;
sfr IAP_DATA = 0xE2; //Flash data register
sfr IAP_ADDRH = 0xE3; //Flash address HIGH
sfr IAP_ADDRL = 0xE4; //Flash address LOW
sfr IAP_CMD = 0xE5; //Flash command register
sfr IAP_TRIG = 0xE6; //Flash command trigger
sfr IAP_CONTR = 0xE7; //Flash control register
#define ENABLE_IAP 0x82 //if SYSCLK<20MHz
#define CMD_READ 1 //IAP字节读命令
#define CMD_PROGRAM 2 //IAP字节编程命令
#define CMD_ERASE 3 //IAP扇区擦除命令
#define cunchudizhi 0 //频率存放地址
#define cunchubiaozhi 0xcb
#define p2 P2 //把大写改成小写,打字累
#define p1 P1 //按Caps Lock键也是要花力气的
sbit jia =P2^3; //频率增加键
sbit jian =P2^2; //频率递减键
u16 pinlv; //频率,请看拼音
bit jishi; //延时用
char chufa; //按键触发值
int zijia; //消抖计时
bit zisuo; //按键自锁,短按避免重复触发
bit changanbiaozhi; //长按标志
sbit key_LTS_KZ =P2^1; //立体声控制键
sbit LTS_LED =P3^3; //立体声显示//INT1
sbit CE =P3^4; //锁存信号//CE
sbit CLK =P3^5; //时钟信号//CLK
sbit DA =P3^6; //数据信号//DA
bit modo; //立体声数据寄存器
#define duanan 10 //100毫秒为短按
#define changan 100 //1秒以上为长按
#define lianxuchufa 5 //连续触发时间为50毫秒一次
unsigned char code shuju[11]={0xC0,0xF9,0xA4,0xB0,0x99,0x92,0x82,0xF8,0x80,0x90};
void yanshi(int a)
{
while(a)
{
if(jishi)
{
jishi=0;
a--;
}
}
}
void nop(void)
{
_nop_();
_nop_();
}
void IapIdle() //关闭IAP
{
IAP_CONTR=0; //关闭IAP功能
IAP_CMD =0; //清除命令寄存器
IAP_TRIG =0; //清除触发寄存器
IAP_ADDRH=0X80; //将地址设置到非IAP区域
IAP_ADDRL=0;
}
u8 durom(u16 addr) //从ISP/IAP/EEPROM区域读取一个字节
{
u8 dat; //数据缓冲区
IAP_CONTR=ENABLE_IAP; //使能IAP 同时设置等待时间
IAP_CMD=CMD_READ; //设置IAP命令
IAP_ADDRL=addr; //设置IAP低地址
IAP_ADDRH=addr>>8; //设置IAP高地址
IAP_TRIG = 0x46; //Send trigger command1 (0x46)
IAP_TRIG = 0xb9; //Send trigger command2 (0xb9)
_nop_(); //等待ISP/IAP/EEPROM操作完成
dat=IAP_DATA; //读ISP/IAP/EEPROM数据
IapIdle(); //关闭IAP功能
return dat; //返回
}
void xierom(u16 addr,u8 dat) //写一个字节数据到ISP/IAP/EEPROM区域
{
IAP_CONTR=ENABLE_IAP; //使能IAP 同时设置等待时间
IAP_CMD=CMD_PROGRAM; //设置IAP命令
IAP_ADDRL=addr; //设置IAP低地址
IAP_ADDRH=addr>>8; //设置IAP高地址
IAP_DATA=dat; //写ISP/IAP/EEPROM数据
IAP_TRIG = 0x46; //Send trigger command1 (0x46)
IAP_TRIG = 0xb9; //Send trigger command2 (0xb9)
_nop_(); //等待ISP/IAP/EEPROM操作完成
IapIdle(); //关闭IAP功能
}
void cachu(u16 addr) //扇区擦除
{
IAP_CONTR=ENABLE_IAP; //使能IAP 同时设置等待时间
IAP_CMD=CMD_ERASE; //设置IAP命令
IAP_ADDRL=addr; //设置IAP低地址
IAP_ADDRH=addr>>8; //设置IAP高地址
IAP_TRIG = 0x46; //Send trigger command1 (0x46)
IAP_TRIG = 0xb9; //Send trigger command2 (0xb9)
_nop_(); //等待ISP/IAP/EEPROM操作完成
IapIdle(); //关闭IAP功能
}
void xianshi(void)
{
p2&=0x0f; //先关位选
if(pinlv/1000) //如果频率超过100兆赫兹就显示
{
p1=shuju[pinlv/1000%10];
p2|=0x10;
}
yanshi(10);
p2&=0x0f;
p1=shuju[pinlv/100%10];
p2|=0x20;
yanshi(10);
p2&=0x0f;
p1=shuju[pinlv/10%10]-0x80;
p2|=0x40;
yanshi(10);
p2&=0x0f;
p1=shuju[pinlv%10];
p2|=0x80;
yanshi(10);
}
void anjian(void)
{
if(jia&&jian&&key_LTS_KZ) //如果没按键按下
{
zijia=0; //清除自加计时
zisuo=0; //置零按键自锁
changanbiaozhi=0; //清除长按标志
}
else if(zisuo==0) //如果有按键按下
{
zijia++; //消抖计时自加
if(zijia>duanan) //如果加到设定时间
{
zijia=0; //置零自加计时
if(!jia)
chufa=1; //触发1号键
if(!jian)
chufa=2; //触发2号键
if(!key_LTS_KZ)
chufa=3; //触发立体声按键
zisuo=1; //按键自锁
}
}
else
{
zijia++; //消抖计时自加
if(changanbiaozhi) //如果连续触发为1
{
if(zijia>lianxuchufa) //如果消抖时间达到连续触发时间
{
zijia=0;
if(!jia)
chufa=1; //触发1号键
if(!jian)
chufa=2; //触发2号键
}
}
else
{
if(zijia>changan) //如果自加超过设定的长按时间
zijia=0,
changanbiaozhi=1; //开启长按标志
}
}
}
///*************************写数据函数*********************************
//将数据送入BH1415中
//*********************************************************************
void send_16data(u16 Data,u8 MODO)
{
u8 i;
CLK=0;
CE=0;
CE=1; //连续保存高电平,可输入数据
for(i=11;i>0;i--)
{
DA=Data & 0x01; //传输BH1415F2个字节频率控制11位D0-D10频率数据
Data>>=1;
nop();
CLK=1;
nop();
CLK=0;
}
DA=MODO;
nop();
CLK=1; //MONO
nop();
CLK=0;
nop();
DA=0;
nop();
CLK=1;
nop();
CLK=0;
nop();
DA=0;
nop();
CLK=1;
nop();
CLK=0;
nop();
DA=1;
nop();
CLK=1;
nop();
CLK=0;
nop();
DA=0;
nop();
CLK=1;
nop();
CLK=0;
CE=0; //输入数据结束
}
void baocunpinlv(void) //保存频率值,下次开机自动进入保存值
{
cachu(cunchudizhi);
xierom(cunchudizhi,cunchubiaozhi);
xierom(cunchudizhi+1,pinlv>>8);
xierom(cunchudizhi+2,pinlv);
}
void chushihuapinlv(void) //初始化频率
{ //如果EEPROM存储地址读数不为存储标志,代表没保存
if(durom(cunchudizhi)!=cunchubiaozhi)
{
pinlv=9790; //那么频率为97.9MHZ
baocunpinlv(); //保存频率至EEPROM
}
else
pinlv=(u16)durom(cunchudizhi+1)<<8|durom(cunchudizhi+2);
}
void main(void)
{
TMOD=0x01;
TH0=0xfc;
TL0=0x18;
TR0=1;
ET0=1;
EA=1;
chushihuapinlv();
send_16data(pinlv,modo);
while(1)
{
if(chufa==1)
{
chufa=0;
pinlv++;
if(pinlv>1080)
pinlv=875;
baocunpinlv();
send_16data(pinlv,modo);
}
else if(chufa==2)
{
chufa=0;
pinlv--;
if(pinlv<875)
pinlv=1080;
baocunpinlv();
send_16data(pinlv,modo);
}
else if(chufa==3)
{
chufa=0;
modo=~modo;
LTS_LED=~modo; //打开关闭立体声
send_16data(pinlv,modo);
}
xianshi();
}
}
void dingshiqi(void) interrupt 1
{
static char a;
TH0=0xfc;
TL0=0x18;
jishi=1;
a++;
if(a>10)
a=0,
anjian();
}
|
评分
-
1
查看全部评分
-
|