#define WREN 0x06 //写允许
#define WRDI 0x04 //写禁止
#define RDSR 0x05 //读状态寄存器
#define WRSR 0x01 //写状态寄存器,看门狗和块锁定
#define READ0 0x03 //从选定的开始地址0单元读数据
#define WRITE0 0x02 //从选定的开始地址0单元写数据
#define READ1 0x0b //从选定的开始地址1单元读数据
#define WRITE1 0x0a //从选定的开始地址1单元写数据
void delays(UCHAR time) //延时程序
{
UCHAR idata i,j;
for(i=0;i<time; i++)
for(j=0;j<3;j++);
}
//关闭看门狗
void Disable_dog(void)
{
UCHAR temp;
temp=ReadSR();
temp&=0x30;
if(temp==0x00)
{
WP_X=ON; //ON=1写保护高电平
WriteSR(0x30); //看门狗禁止
}
WP_X=OFF; //OFF=0写饱和,禁止想5045写数据
}
//打开看门狗
void Enable_dog(void)
{
UCHAR temp;
temp=ReadSR();
temp&=0x30;
if(temp!=0x00)
{
WP_X=ON;
WriteSR(0x00); //1.4秒
}
WP_X=OFF;
}
void Reset_Watchdog(void)
{
CS_X=1; //WDI引脚上高到低的电平变化将复位看门狗定时器
delays(3);
CS_X=0;
delays(3);
CS_X=1;
}
//读一个字节的数据
unsigned char Read8()
{
bit bData; //位定义
unsigned char cLoop;
unsigned char cData="0";
CS_X=0;SO_X=1;
for(cLoop=0;cLoop<8;cLoop++)
{
SCK_X=1; //串行时钟的下降沿开始读数
delays(3);
SCK_X=0;
delays(3);
bData=SO_X;
cData<<=1;
if(bData)
cData|=0x01;
}
return cData;
}
//写一个字节的数据
void Write8(unsigned char cData)
{
unsigned char cLoop;
CS_X=0;
for(cLoop=0;cLoop<8;cLoop++)
{
if(cData&0x80)
SI_X=1;
else
SI_X=0;
delays(3);
SCK_X=0; //串行时钟的上升沿从SI写入
delays(3);
SCK_X=1;
delays(3);
cData<<=1;
}
}
//读状态寄存器的值
unsigned char ReadSR()
{
unsigned char cData;
CS_X=0;
Write8(RDSR);
cData=Read8();
CS_X=1;
return (cData);
}
void readsdat(void) //wait for 5043 ready
{
UCHAR idata i="255";
UCHAR idata temp;
while(i--)
{temp=ReadSR();
temp&=0x01; //状态寄存器的WIP位 WIP="1表示忙",WIP=0表示空闲
if(!temp) break; //WIP=0空闲退出
Reset_Watchdog(); //WIP=1忙复位看门狗定时器(定时喂狗)
}
}
//写状态寄存器的值
void WriteSR(unsigned char cData)
{
readsdat(); //等待5045准备
delays(3);
CS_X=0;
Write8(WREN);
CS_X=1; //特别注意CS_X变为高电平
delays(3);
CS_X=0;
Write8(WRSR);
Write8(cData);
CS_X=1;
}
以上是关于开狗,关狗程序,
读字节,写字节程序,
读状态寄存器,写状态寄存器程序
下面是关于在指定地址写入字节和在指定地址读出字节程序在其他程序中的调用(这里是通过按键存储调用写字节程序,主程序初始化时侯调用读字节程序初始化载入让仪器具有记忆功能!)
void Read_set(void)
{
unsigned char i,page;
readsdat(); //wait for 5043 ready
//each page 16 Byte 经分析5045共32页 32*16=512Byte
for(page=0;page<8;page++)
{
CS_X=0;
Write8(READ0);
Write8(page<<4);
switch(page)
{
case 0: //第0页
for(i=0;i<2;i++) //vaildid
{ validid=Read8();
delays(1);
}
break;
case 1: //第1页
my_ipaddr=0; //my_ipaddr
for(i=0;i<4;i++)
{
my_ipaddr=my_ipaddr|((ULONG)Read8()<<(8*i));
delays(1);
}
my_ipaddr_comp=my_ipaddr;
delays(1);
for(i=0;i<6;i++) //my_hwaddr
{
my_hwaddr=Read8();
delays(1);
}
delays(1);
break;
case 2: //第2页
EManager_ipaddr=0; //em ipaddr
for(i=0;i<4;i++)
{
EManager_ipaddr=EManager_ipaddr|((ULONG) Read8()<<(8*i));
delays(1);
}
delays(1);
break;
case 3: //第3页
gateway_ipaddr=0;
for(i=0;i<4;i++) //gateway addr
{
gateway_ipaddr=gateway_ipaddr|((ULONG) Read8()<<(8*i));
delays(1);
}
delays(1);
break;
case 4: //第4页
my_subnet = 0;
for(i=0;i<4;i++) //subnet mask
{
my_subnet=my_subnet|((ULONG) Read8()<<(8*i));
delays(1);
}
break;
case 5: //第5页
UPFREQ=0;
for(i=0;i<2;i++) //UP Freq;
{
UPFREQ=UPFREQ|(Read8()<<(8*i));
delays(1);
}
if(UPFREQ>202) UPFREQ="202";
else if(UPFREQ<50) UPFREQ="50";
DNFREQ=0; //DN Freq
for(i=0;i<2;i++)
{
DNFREQ=DNFREQ|(Read8()<<(8*i));
delays(1);
}
if(DNFREQ>1190) DNFREQ="1190";
else if(DNFREQ<1080) DNFREQ="1080";
break;
case 6: //第6页
cont_peroids=0;
contmode=Read8();
delays(1);
for(i=0;i<2;i++)
{
cont_peroids=cont_peroids|(Read8()<<(8*i));
delays(1);
}
break;
case 7: //第7页
fskoutattdb=Read8();
delays(1);
brightness=Read8();
delays(1);
break;
default:break;
}
CS_X=1;
delays(3);
if(validid[0]!=0x66&&validid[1]!=0x88) //如何理解此句???
break;
}
CS_X=1;
delays(3);
}
void Write_set(void)
{
unsigned char i,temp,page;
WP_X=ON; //可以写
for(page=0;page<8;page++)
{
//temp=page<<4&0xf0;
readsdat(); //延时等待5045准备
CS_X=0;
Write8(WREN);
CS_X=1;delays(3);
CS_X=0;
Write8(WRITE0);
Write8(page<<4);
switch(page)
{
case 0: //validid
Write8(0x66); delays(1);
Write8(0x88); delays(1);
break;
case 1:
my_ipaddr_comp=my_ipaddr;
for(i=0;i<4;i++) //my_ipaddr
{ temp=0xff&(my_ipaddr>>(i*8));
Write8(temp); delays(1);
}
for(i=0;i<6;i++)
{ temp=my_hwaddr; //my_hwaddr
Write8(temp); delays(1);
}
break;
case 2:
for(i=0;i<4;i++) //em ipaddr
{
temp=0xff&(EManager_ipaddr>>(i*8));
Write8(temp); delays(1);
}
break;
case 3:
for(i=0;i<4;i++) //gateway addr
{
//temp掩码地址中单个的字节,从地址0.0011.0000开始存储到0.0011.0011前五个字节为页数,后四个字节为页码中的地址
//这也是对一个ULONG四个字节的存储在连续的地址单元中
temp=0xff&(gateway_ipaddr>>(8*i));
Write8(temp); delays(1);
}
break;
case 4:
for(i=0;i<4;i++) //my subnet mask
{
temp=0xff&(my_subnet>>(8*i));
Write8(temp); delays(1);
}
break;
case 5:
for(i=0;i<2;i++)
{
temp=0xff&(UPFREQ>>(i*8)); //up frequence
Write8(temp); delays(1);
}
for(i=0;i<5;i++)
{
temp=0xff&(DNFREQ>>(i*8)); //down frequence
Write8(temp); delays(1);
}
break;
case 6:
temp=contmode;
Write8(temp); delays(1);
for(i=0;i<2;i++)
{
temp=0xff&(cont_peroids>>(i*8)); //up frequence
Write8(temp); delays(1);
}
break;
case 7:
temp=fskoutattdb; //fsk att
Write8(temp); delays(1);
temp=brightness; //vfm brightness
Write8(temp); delays(1);
break;
default:
break;
}
SCK_X=0;
delays(3);
CS_X=1;
delays(3);
}
SCK_X=0;
delays(3);
CS_X=1;
delays(3);
WP_X=OFF;
}
用户169156 2009-1-18 20:41