原创 详细讲解关于x5045 eeprom存储器的使用

2008-12-30 14:51 3600 9 10 分类: MCU/ 嵌入式

#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;
}



 


 


 

PARTNER CONTENT

文章评论1条评论)

登录后参与讨论

用户169156 2009-1-18 20:41

感谢楼主正在吸收
相关推荐阅读
用户1409899 2013-10-31 14:46
modbus协议crc-16算法
/------------------------------------- #if 0 #define uchar unsigned char #define uint  unsig...
用户1409899 2013-10-31 14:42
堆栈指针
  一道嵌入式系统设计师堆栈指针考题引发的思考: 在8086微处理器中,若(SS)=2000H,(SP)=0100H,(AX)=2117H,执行指令 PUSHAX后存放数据21H的物理...
用户1409899 2013-10-24 16:51
转载 :数据结构内存对齐
内存对齐 在我们的程序中,数据结构还有变量等等都需要占有内存,在很多系统中,它都要求内存分配的时候要对齐,这样做的好处就是可以提高访问内存的速度。 我们还是先来看一段简单的程序: 程序一 ...
用户1409899 2013-01-14 09:51
中星微zc301b摄像头
  硬件环境:友善之臂mini2440开发板+中星微zc301b摄像头 软件环境:linux2.6.29内核+上位机Ubuntu8.04 日    期:2012-12-1...
用户1409899 2012-07-05 19:44
国嵌mp3播放器应用程序
************************************************* Function name: main Parameter    : void Descr...
用户1409899 2012-07-05 19:43
国嵌mp3播放器应用程序
1.掌握双向循环链表,对指针,结构体,动态分配内存等C语言要求较高 2.掌握多进程编程,以及共享内存通信相关方面的内容     /*  *     mp3播放器控制程序  * ...
EE直播间
更多
我要评论
1
9
关闭 站长推荐上一条 /3 下一条