一、引脚定义及通信协议

SO:串行数据输出脚,在一个读操作的过程中,数据从SO脚移位输出。在时钟的下降沿时数据改变。
SI: 串行数据输入脚,所有的操作码、字节地址和数据从SI脚写入,在时钟的上升沿时数据被锁定。
SCK:串行时钟,控制总线上数据输入和输出的时序。
/CS :芯片使能信号,当其为高电平时,芯片不被选择,SO脚为高阻态,除非一个内部的写操作正在进行,否则芯片处于待机模式;当引脚为低电平时,芯片处于活动模式,在上电后,在任何操作之前需要CS引脚的一个从高电平到低电平的跳变。
/WP:当WP引脚为低时,芯片禁止写入,但是其他的功能正常。当WP引脚为高电平时,所有的功能都正常。当CS为低时,WP变为低可以中断对芯片的写操作。但是如果内部的写周期已经被初始化后,WP变为低不会对写操作造成影响。
二、硬件连接

三、程序设计
状态寄存器:
7   6   5    4   3    2     1  0 
 X  X  WD1  WD0  BL1  BL0  WEL WIP  
WIP:写操作标志位, 为1表示内部有一个写操作正在进行,为0则表示空闲,该位为只读。
WEL: 写操作允许标志位,为1表示允许写操作,为0表示禁止写,该位为只读。
BL0,BL1:内部保护区间的地址选择。被保护的区间不能进行看门狗的定时编程。
WD0,WD1:可设定看门狗溢出的时间。有四种可选择:1.4s,600ms,200ms,无效。
操作码:
WREN 0x06 设置写允许位
WRDI 0x04 复位写允许位
RDSR  0x05 读状态寄存器
WRSR 0x01 写状态寄存器
READ 0x03/0x0b 读操作时内部EEPROM页地址
WRITE 0x02/0x0a 写操作时内部EEPROM页地址
程序代码:
#i nclude 
 sbit CS= P2^7; 
 sbit SO= P2^6; 
 sbit SCK= P2^5; 
 sbit SI= P2^4;
 #define WREN 0x06 //
 #define WRDI 0x04 //
 #define RDSR 0x05 //
 #define WRSR 0x01 //
 #define READ0 0x03 //
 #define READ1 0x0b //
 #define WRITE0 0x02 //
 #define WRITE1 0x0a //
 #define uchar unsigned char
 uchar ReadByte() //read a byte from device
 {
 bit bData;
 uchar ucLoop;
 uchar ucData;
 for(ucLoop=0;ucLoop<8;ucLoop++)
 {
 SCK=1;
 SCK=0;
 bData=SO;
 ucData<<=1;
 if(bData)
 { ucData =0x01; }
 }
 return ucData;
 }
 void WriteByte(uchar ucData)//write a byte to device
 {
 uchar ucLoop;
 for(ucLoop=0;ucLoop<8;ucLoop++)
 {
 if((ucData&0x80)==0) //the MSB send first
 {SI=0;}
 else
 {SI=1;}
 SCK=0;
 SCK=1;
 ucData<<=1;
 }
 }
 uchar ReadReg() //read register
 {
 uchar ucData;
 CS=0;
 WriteByte(RDSR);
 ucData=ReadByte();
 CS=1;
 return ucData;
 }
 uchar WriteReg(uchar ucData) //write register
 {
 uchar ucTemp;
 ucTemp=ReadReg();
 if((ucTemp&0x01)==1) //the device is busy
 return 0;
 CS=0;
 WriteByte(WREN);//when write the WREN, the cs must have a high level
 CS=1;
 CS=0;
 WriteByte(WRSR);
 WriteByte(ucData);
 CS=1;
 return 1;
 }
 void WriteEpm(uchar cData,uchar cAddress,bit bRegion)
 /* 写入一个字节,cData为写入的数,cAddress为写入地址,bRegion为页 */
 {
 while((ReadReg()&0x01)==1); //the device is busy
 CS=0;
 WriteByte(WREN); //when write the wren , the cs must have a high level
 CS=1;
 CS=0;
 if(bRegion==0)
 { WriteByte(WRITE0);} //write the page addr
 else
 {WriteByte(WRITE1);} 
 WriteByte(cAddress);
 WriteByte(cData);
 SCK=0; //
 CS=1;
 }
 uchar ReadEpm(uchar cAddress,bit bRegion)
 /* 读入一个字节,cAddress为读入地址,bRegion为页 */
 {
 uchar cData;
 while((ReadReg()&0x01)==1);//the device is busy
 CS=0;
 if(bRegion==0)
 {WriteByte(READ0); }
 else
 {WriteByte(READ1);}
 WriteByte(cAddress);
 cData=ReadByte();
 CS=1;
 return cData;
 }
main()
{
WriteReg(0x00);//set the watchdog time as 1.4s
CS=1;
CS=0; //reset the watchdog
}