读写93C66A问题
时间:10-02
整理:3721RD
点击:
C51单片机读写93C66A不正常,程序如下,那位大侠用过的指点一下.
//-----------------------------------------------------
//Enable Write 写使能
//-----------------------------------------------------
void EnWr(void)
{
uint8 i;
uint16 comm;
//启动总线
ioEeCs=0;
nop;
nop;
ioClk=0;
nop;
nop;
ioEeCs=1;
nop;
nop;
//发送指令
comm = 0x9800;
for(i=0;i<12;i++)
{
ioClk=0;
nop;
nop;
comm<<=1;
ioSdo=CY;
nop;
nop;
ioClk=1;
nop;
nop;
}
//停止总线
ioEeCs=0;
}
//-----------------------------------------------------
//Disable Write 写保护
//-----------------------------------------------------
void DisWr(void)
{
uint8 i;
uint16 comm;
//启动总线
ioEeCs=0;
nop;
nop;
ioClk=0;
nop;
nop;
ioEeCs=1;
nop;
nop;
//发送指令
comm = 0x8000;
for(i=0; i<12; i++)
{
ioClk=0;
nop;
nop;
comm<<=1;
ioSdo=CY;
nop;
nop;
ioClk=1;
nop;
nop;
}
ioEeCs=0;
}
//-----------------------------------------------------
//写数据
//-----------------------------------------------------
void WriteEe1Bey(uint8 Addr,uint8 InData)
{
uint8 i;
uint16 comm;
uint16 Delays;
//启动总线
ioEeCs=0;
nop;
nop;
ioClk=0;
nop;
nop;
ioEeCs=1;
nop;
nop;
//发送指令
comm = 0x0A00 + (uint16)(Addr);
comm <<= 4;
for(i = 0; i < 12; i++)
{
ioClk = 0;
nop;
nop;
comm <<= 1;
ioSdo = CY;
nop;
nop;
ioClk = 1;
nop;
nop;
}
//发送数据
for(i = 0;i < 8; i++)
{
ioClk=0;
nop;
nop;
InData <<= 1;
ioSdo=CY;
nop;
nop;
ioClk=1;
nop;
nop;
}
ioEeCs=0;
nop;
nop;
ioEeCs=1;
nop;
nop;
Delays = 0;
while(!ioSdi)
{
Delays++;
if(Delays>30000)
{
break;
}
}
ioEeCs=0;
}
void WriteEe(uint8 Addr,uint16 InData)
{
uint8 dataH;
uint8 dataL;
dataL = InData & 0xFF;
InData = InData >> 8;
dataH = InData & 0xFF;
Addr = Addr & 0x3f;
Addr = Addr * 2;
EnWr();
WriteEe1Bey(Addr, dataH);
Addr ++;
WriteEe1Bey(Addr, dataL);
DisWr();
}
//-----------------------------------------------------
//读数据
//-----------------------------------------------------
uint16 ReadEe(uint8 Addr)
{
uint8 i;
uint16 comm;
uint16 EeValue;
Addr = Addr & 0x3f;
Addr = Addr * 2;
//启动总线
ioEeCs=0;
nop;
nop;
ioClk=0;
nop;
nop;
ioEeCs=1;
nop;
nop;
//发送指令
comm = 0x0C00 + (uint16)(Addr);
comm <<= 4;
for(i=0;i<12;i++)
{
ioClk=0;
nop;
nop;
comm<<=1;
ioSdo=CY;
nop;
nop;
ioClk=1;
nop;
nop;
}
EeValue=0;
for(i=0;i<16;i++)
{
ioClk=0;
EeValue<<=1;
ioClk=1;
nop;
nop;
if(ioSdi == 1)
{
EeValue|=1;
}
}
ioEeCs=0;
return EeValue;
}
//-----------------------------------------------------
//Enable Write 写使能
//-----------------------------------------------------
void EnWr(void)
{
uint8 i;
uint16 comm;
//启动总线
ioEeCs=0;
nop;
nop;
ioClk=0;
nop;
nop;
ioEeCs=1;
nop;
nop;
//发送指令
comm = 0x9800;
for(i=0;i<12;i++)
{
ioClk=0;
nop;
nop;
comm<<=1;
ioSdo=CY;
nop;
nop;
ioClk=1;
nop;
nop;
}
//停止总线
ioEeCs=0;
}
//-----------------------------------------------------
//Disable Write 写保护
//-----------------------------------------------------
void DisWr(void)
{
uint8 i;
uint16 comm;
//启动总线
ioEeCs=0;
nop;
nop;
ioClk=0;
nop;
nop;
ioEeCs=1;
nop;
nop;
//发送指令
comm = 0x8000;
for(i=0; i<12; i++)
{
ioClk=0;
nop;
nop;
comm<<=1;
ioSdo=CY;
nop;
nop;
ioClk=1;
nop;
nop;
}
ioEeCs=0;
}
//-----------------------------------------------------
//写数据
//-----------------------------------------------------
void WriteEe1Bey(uint8 Addr,uint8 InData)
{
uint8 i;
uint16 comm;
uint16 Delays;
//启动总线
ioEeCs=0;
nop;
nop;
ioClk=0;
nop;
nop;
ioEeCs=1;
nop;
nop;
//发送指令
comm = 0x0A00 + (uint16)(Addr);
comm <<= 4;
for(i = 0; i < 12; i++)
{
ioClk = 0;
nop;
nop;
comm <<= 1;
ioSdo = CY;
nop;
nop;
ioClk = 1;
nop;
nop;
}
//发送数据
for(i = 0;i < 8; i++)
{
ioClk=0;
nop;
nop;
InData <<= 1;
ioSdo=CY;
nop;
nop;
ioClk=1;
nop;
nop;
}
ioEeCs=0;
nop;
nop;
ioEeCs=1;
nop;
nop;
Delays = 0;
while(!ioSdi)
{
Delays++;
if(Delays>30000)
{
break;
}
}
ioEeCs=0;
}
void WriteEe(uint8 Addr,uint16 InData)
{
uint8 dataH;
uint8 dataL;
dataL = InData & 0xFF;
InData = InData >> 8;
dataH = InData & 0xFF;
Addr = Addr & 0x3f;
Addr = Addr * 2;
EnWr();
WriteEe1Bey(Addr, dataH);
Addr ++;
WriteEe1Bey(Addr, dataL);
DisWr();
}
//-----------------------------------------------------
//读数据
//-----------------------------------------------------
uint16 ReadEe(uint8 Addr)
{
uint8 i;
uint16 comm;
uint16 EeValue;
Addr = Addr & 0x3f;
Addr = Addr * 2;
//启动总线
ioEeCs=0;
nop;
nop;
ioClk=0;
nop;
nop;
ioEeCs=1;
nop;
nop;
//发送指令
comm = 0x0C00 + (uint16)(Addr);
comm <<= 4;
for(i=0;i<12;i++)
{
ioClk=0;
nop;
nop;
comm<<=1;
ioSdo=CY;
nop;
nop;
ioClk=1;
nop;
nop;
}
EeValue=0;
for(i=0;i<16;i++)
{
ioClk=0;
EeValue<<=1;
ioClk=1;
nop;
nop;
if(ioSdi == 1)
{
EeValue|=1;
}
}
ioEeCs=0;
return EeValue;
}
keil4 编写的93C66的51程序,可在89C51,89C52,89C58,89C516上直接移植。:
http://download.csdn.net/detail/wxjcan/4088803
93C66我也没用过,发个驱动程序你参考下;
- /*93c66 操作子程序 */
- /* 注意:这里使用的93c66 为8 位结构的EEROM*/
- void delay1(unsigned int num)
- {
- while(num!=0){num=num-1;}
- }
- /***********************************************************************/
- /*名称: START_93c66() */
- /*说明: 用于93c66 的启动,防止由于CS_93c66 的改动而引起数据时序混乱 */
- /***********************************************************************/
- void START_93c66()
- {
- DO_93c66=1; /*防止DO 由于是低电平而无法输入*/
- CS_93c66=1;
- /*开启93c66*/
- CS_93c66=0;
- DI_93c66=0;
- SK_93c66=0;
- CS_93c66=1;
- delay1(1000);
- }
- /***************************************************************************/
- /*名称:END_93c66() */
- /*说明:用于93c66 的结束,防止由于CS_93c66 的改动而引起数据线为0 而无法输入*/
- /***************************************************************************/
- void END_93c66()
- {
- CS_93c66=0;
- DI_93c66=1;
- SK_93c66=1;
- }
- /***********************************************************************/
- /*名称:SEND_DATA_93c66() */
- /*说明:在93c66 启动下,送入指定位数的数据 */
- /*输入: op_data 要输入的数据 */
- /* num 输入的位数 */
- /**********************************************************************/
- void SEND_DATA_93c66(unsigned int op_data,unsigned char num)
- {
- unsigned char temp1;
- op_data=op_data<<(16-num); /*左移去掉无用位*/
- for(temp1=0;temp1<num;temp1++)
- {
- if( (op_data&0X8000)==00 )
- {DI_93c66=0;}
- else
- {DI_93c66=1;}
- SK_93c66=1;//SK_93c66=1;SK_93c66=1;SK_93c66=1;
- SK_93c66=0;
- op_data=op_data<<1;
- }
- }
- /***********************************************************************/
- /*名称: EWEN_93c66() */
- /*说明: 93c66 的编程启动.操作码(100 11XXXXXXX) */
- /***********************************************************************/
- void EWEN_93c66()
- {
- START_93c66();
- SEND_DATA_93c66(0X0013,0X05); /*送入3 位操作码+11*/
- SEND_DATA_93c66(0X0000,Addr_bit-2); /*送入9 位地址*/
- END_93c66();
- }
- /***********************************************************************/
- /*名称: EWDS_93c66() */
- /*说明: 93c66 的编程关闭.操作码(100 00XXXXXXX) */
- /**********************************************************************/
- void EWDS_93c66()
- {
- START_93c66();
- SEND_DATA_93c66(0X0004,0X03);
- SEND_DATA_93c66(0X0000,Addr_bit);
- END_93c66();
- }
- /***********************************************************************/ /*名称:READ() */
- /*说明:93c66 的字读取程序 */
- /*输入:要读取的字节地址(9 位) */
- /*输出:读取的字数值 */
- /**********************************************************************/
- unsigned char READ(unsigned int address)
- {
- unsigned char temp1;
- unsigned char temp2;
- START_93c66();
- SEND_DATA_93c66(0X0006,0X03);
- SEND_DATA_93c66(address,Addr_bit);
- temp2=0; /*存放返回数据的缓冲先清零*/
- for(temp1=0;temp1<8;temp1++) /*循环读出8 个数据*/
- {
- temp2=temp2<<1;
- SK_93c66=1;SK_93c66=0;
- if(DO_93c66==1)
- {temp2=temp2|0X01;}
- }
- END_93c66();
- return temp2;
- }
- /**********************************************************************/
- /*名称:WRITE() */
- /*说明:93c66 的字写入程序 */
- /*输入: address 要写入的字节地址(9 位) */
- /* op_data 要写入的数据(8 位) */
- /*输出: 读取的字数值 */
- /**********************************************************************/
- unsigned char WRITE(unsigned int address,unsigned int op_data)
- {
- unsigned char temp1;
- unsigned int temp2;
- EWEN_93c66();
- START_93c66();
- SEND_DATA_93c66(0X0005,0X03);
- SEND_DATA_93c66(address,Addr_bit);
- SEND_DATA_93c66(op_data,0X08);
- CS_93c66=0;
- CS_93c66=1;
- temp1=1;
- temp2=50000; /*设置一个最大延时等待数值.注意在不同的晶振下延时是不同的*/
- while(!DO_93c66)
- {
- temp2=temp2-1;
- if(temp2==0)
- {
- temp1=0;//temp1=0则写入失败
- CD_3=0;
- P0=0X08;
- delay1(60000);
- P0=0;
- CD_3=1;
- //break; /*最大等待延时后说明擦除失败*/
- }
- }
- END_93c66();
- EWDS_93c66();
- return temp1;
- }
- /***********************************************************************/
- /*名称:ERASE() */
- /*说明:93c66 的字擦除程序 */
- /*输入: address 要擦除的字地址(9 位) */
- /**********************************************************************/
- unsigned char ERASE(unsigned char address)
- {data unsigned char temp1;
- data unsigned int temp2;
- EWEN_93c66();
- START_93c66();
- SEND_DATA_93c66(0X07,0X03);
- SEND_DATA_93c66(address,0X06);
- CS_93c66=0;
- CS_93c66=1;
- temp1=1;
- temp2=50000;
- while(!DO_93c66)
- {temp2=temp2-1;
- if(temp2==0)
- {temp1=0;
- break;
- }
- }
- END_93c66();
- EWDS_93c66(); //返回表示擦除状态的特征
- return temp1;
- }
- /**********************************************************************/
- /*名称:ERAL() */
- /*说明:93c66 的全部擦除程序 */
- /**********************************************************************/
- unsigned char ERAL()
- {data unsigned char temp1;
- data unsigned int temp2;
- EWEN_93c66();
- START_93c66();
- SEND_DATA_93c66(0X04,0X03);
- SEND_DATA_93c66(0X20,0X06);
- CS_93c66=0;
- CS_93c66=1;
- temp1=1;
- temp2=50000;
- while(!DO_93c66)
- {temp2=temp2-1;
- if(temp2==0)
- {temp1=0;
- break;
- }
- }
- END_93c66();
- EWDS_93c66(); //返回表示擦除状态的特征
- return temp1;
- }
- /***********************************************************************/
- /*名称:WRAL() */
- /*说明:93c66 的写全部程序 */
- /*输入: op_data 要写入的数据(16 位) */
- /*输出: 读取的字数值 */
- /***********************************************************************/
- unsigned char WRAL(unsigned int op_data)
- {data unsigned char temp1;
- data unsigned int temp2;
- EWEN_93c66();
- START_93c66();
- SEND_DATA_93c66(0X04,0X03);
- SEND_DATA_93c66(0X10,0X06);
- SEND_DATA_93c66(op_data,0X10);
- CS_93c66=0;
- CS_93c66=1;
- temp1=1;
- temp2=50000; //设置一个最大延时等待数值.注意在不同的晶振下延时是不同的
- while(!DO_93c66)
- {temp2=temp2-1;
- if(temp2==0)
- {temp1=0;
- break;
- }
- }
- END_93c66();
- EWDS_93c66();
- return op_data;
- }
感谢你,我参考了你的程序。