[讨论]
请教高手93C46的8位、16位读写程序怎么区分
请教高手93C46的8位、16位读写程序怎么区分
SB+OP1=10B,OP0+写允许=01100000B
比如93C46的写允许8位是 1001100000既 00000010,01100000(0X02,0X60)
但写允许16位是 10011 0000(空了一位)既 00000010,?(0X02,?)
16位是写允许命令怎么写
[ 本帖最后由 simonprince 于 2010-2-4 15:33 编辑 ]
呼唤高手
不会是在那空的一位填0吧,那就和其他指令重复了啊
就是空了一位,空了一位怎么了???? 就是 10011 0000
10011是允许写使能操作码,
XXXX表示任意值,0和1都可以.
回复 7楼 jxb01033016 的帖子
那对于16位指令WriCmd (,);括号里面的应该怎么表达?空的那位填0吗?谢谢
WriCmd(0x02,0x60); //SB+OP1=10B,OP0+写允许=01100000B
//****写指定地址*****************************************************
// 使用8位操作,PRG=0
// 93C46读写指令+地址格式:
// | SB | OP1 | OP0 | A6 | A5 | A4 | A3 | A2 | A1 | A0 |
// SB=起始位,恒=1;OP=操作命令;Add地址
//写 OP1=0;OP0=1; 01B
//-------------------------------------------------------------------
Writ9346(unsigned char add,Dat)
{ //写允许
din=dout=0;cs=0;
WriCmd(0x02,0x60); //SB+OP1=10B,OP0+写允许=01100000B
//写数据
WriData(0x02,(add|0x80),Dat);//SB+OP1+OP0+地址
WriCmd(0x02,0x00); //SB+OP1=10B,OP0+写禁止=00000000B
}
[ 本帖最后由 simonprince 于 2010-2-5 12:40 编辑 ]
不是填0,你只要串行移位9次,因为每个命令的长度不一样,所以你的底层驱动要重写.
做好人做到底,我发个样板给你看下,你自己参考下
//====================EEPROM====================================================
//==============================================================================
//Subroutine: READ
//Function: Read one byte command
//==============================================================================
UC READ(UC EEADDR)
{
UC EEDATA;
//EWDS(); //08.12.05,add write disable.
_nop();
_nop();
_nop();
_nop();
_cs = 1;
_nop();
_nop();
_nop();
_nop();
Shift(cREAD,3); //OP Code
_rl(&EEADDR);
Shift(EEADDR,7); //Address
EEDATA = Shift(0x00,8);
_nop();
_nop();
_cs = 0;
_nop();
_nop();
_nop();
_nop();
return EEDATA;
}
//==============================================================================
//Subroutine: ERASE
//Function: Erase one byte command
//==============================================================================
void ERASE(UC EEADDR)
{
_nop();
_nop();
_nop();
_nop();
//EWEN(); //08.12.05,add write enable.
_cs = 1;
_nop();
_nop();
_nop();
_nop();
Shift(cERASE,3); //OP Code
_rl(&EEADDR);
Shift(EEADDR,7); //Address
_nop();
_nop();
_nop();
_nop();
_cs = 0;
_nop();
_nop();
_nop();
_nop();
ChkBusy();
//EWDS(); //08.12.05,add write disable.
}
//==============================================================================
//Subroutine: WRITE
//Function: Write one byte command
//==============================================================================
void WRITE(UC EEADDR, UC EEDATA)
{
_nop();
_nop();
_nop();
_nop();
//EWEN(); //08.12.05,add write enable.
_cs = 1;
_nop();
_nop();
_nop();
_nop();
Shift(cWRITE,3); //OP Code
_rl(&EEADDR);
Shift(EEADDR,7); //Address
Shift(EEDATA,8); //Address
_nop();
_nop();
_nop();
_nop();
_cs = 0;
_nop();
_nop();
_nop();
_nop();
ChkBusy();
//EWDS(); //08.12.05,add write disable.
}
//==============================================================================
//Subroutine: EWEN
//Function: Erase/Write Enable Command
//==============================================================================
void EWEN(void)
{
_nop();
_nop();
_nop();
_nop();
_cs = 1;
_nop();
_nop();
_nop();
_nop();
Shift(cEWEN,3); //OP Code
Shift(0xc0,7);
_nop();
_nop();
_nop();
_nop();
_cs = 0;
_nop();
_nop();
_nop();
_nop();
}
//==============================================================================
//Subroutine: EWDS
//Function: Erase/Write Disable Command
//==============================================================================
void EWDS(void)
{
_nop();
_nop();
_nop();
_nop();
_cs = 1;
_nop();
_nop();
_nop();
_nop();
Shift(cEWDS,3); //OP Code
Shift(0x00,7);
_nop();
_nop();
_nop();
_nop();
_cs = 0;
_nop();
_nop();
_nop();
_nop();
}
//==============================================================================
//Subroutine: ERAL
//Function: Erase all command
//==============================================================================
void ERAL(void)
{
_nop();
_nop();
_nop();
_nop();
_cs = 1;
_nop();
_nop();
_nop();
_nop();
Shift(cERAL,3); //OP Code
Shift(0x80,7); //Address
_nop();
_nop();
_nop();
_nop();
_cs = 0;
_nop();
_nop();
_nop();
_nop();
ChkBusy();
}
//==============================================================================
//Subroutine: WRITE
//Function: Write one byte command
//==============================================================================
void WRAL(UC EEDATA)
{
_nop();
_nop();
_nop();
_nop();
_nop();
_cs = 1;
_nop();
_nop();
_nop();
_nop();
_nop();
Shift(cWRAL,3); //OP Code
Shift(0x40,7);
Shift(EEDATA,8); //Address
_cs = 0;
_nop();
_nop();
_nop();
_nop();
_nop();
ChkBusy();
}
//==============================================================================
//Subroutine: Shift
//Function:
//==============================================================================
UC Shift(UC buf, UC cnt)
{
do
{
_nop();
_nop();
_nop();
_nop();
_nop();
_sk=0;
_nop();
_nop();
_nop();
_nop();
_nop();
if(buf & cTestb7)
_di = 1;
else
_di = 0;
_nop();
_nop();
_nop();
_nop();
_nop();
_nop();
_nop();
_nop();
_nop();
_nop();
_nop();
_nop();
_nop();
_nop();
_nop();
_nop();
_nop();
_nop();
_nop();
_nop();
_nop();
_nop();
_nop();
_nop();
_sk = 1;
_nop();
_nop();
_nop();
_nop();
_nop();
_nop();
_nop();
_nop();
_nop();
_nop();
_nop();
_nop();
_nop();
_nop();
_nop();
_nop();
_nop();
_nop();
_nop();
_rl(&buf);
if(_do)
buf |= cSetb0;
else
buf &= cClrb0;
_nop();
_nop();
_nop();
_nop();
_nop();
_nop();
}while(--cnt);
_sk = 0;
_nop();
_nop();
_nop();
_nop();
_nop();
return buf;
}
//==============================================================================
//Subroutine: ChkBusy
//Function:
//==============================================================================
void ChkBusy(void)
{
_nop();
_nop();
_nop();
_nop();
_nop();
_cs = 1;
_nop();
_nop();
_nop();
_nop();
_nop();
while(1)
{
_nop();
_nop();
// _sk = 1; //delete this line for no need clock by Andy Jiang 09-08-05
_nop();
_nop();
_nop();
_nop();
_nop();
_nop();
if(_do)
break;
_nop();
_nop();
_nop();
_nop();
_nop();
_nop();
// _sk = 0; //delete this line for no need clock by Andy Jiang 09-08-05
_nop();
_nop();
_nop();
_nop();
_nop();
}
_sk = 0;
_cs = 0;
_nop();
_nop();
_nop();
_nop();
_nop();
[ 本帖最后由 jxb01033016 于 2010-2-5 13:52 编辑 ]
因为每次访问EEPROM,命令的长度都不一样,你没法只用一个函数去实现. 建议你的程序,最好把操作码和操作数分开,
回复 10楼 jxb01033016 的帖子
恩,好东西,谢谢谢谢~~~~
#define cREAD 0xc0
#define cERASE 0xe0
#define cWRITE 0xa0
#define cEWEN 0x80
#define cEWDS 0x80
#define cERAL 0x80
#define cWRAL 0x80
这个是宏定义,我用8位的读写,已经成功了的代码 .
******************************************************************************/
#include
sbit cs = P2^0; //片选
sbit sck= P2^1;
sbit din= P2^2; //串行数据入
sbit dout=P2^3; //串行数据出
sbit GND= P2^4;
sbit prg= P2^5; //结构选择,0=8bit;1=16bit
sbit dc= P2^6; //无效脚
sbit VCC= P2^7; //电源
sbit ls0=P0^1; //LED公共极
//******延时子程序************************************************
Delay()
{
unsigned char t=1;//根据上拉电阻决定,经验值在20-100@12M
while(--t);
}
//******* 写指令************************************
//OpAddH=操作指令高位,OpAddL=操作指令低位
WriCmd(unsigned OpAddH,OpAddL)//0x02,0x60
{
unsigned char i,m;
cs=1;Delay();
m=OpAddH;
for(i=0;i<8;i++)
{
din=m & 0x80;//
Delay();sck=1;
Delay();sck=0;
m=m<<1;
}
m=OpAddL;
for(i=0;i<8;i++)
{
din=m & 0x80;
Delay();sck=1;
Delay();sck=0;
m=m<<1;
}
cs=0;
}
//******* 写数据************************************
//OpAddH=操作指令高位,OpAddL=操作指令低位,dat=写入的数据
WriData(unsigned char OpAddH,OpAddL,dat)
{
unsigned char i,m;
cs=1;Delay();
m=OpAddH;
for(i=0;i<8;i++) //送出指令字
{
din=m & 0x80; //移出到C并送DIO端
Delay();sck=1;
Delay();sck=0;
m=m<<1;
}
m=OpAddL;
for(i=0;i<8;i++) //送出地址
{
din=m & 0x80; //移出到C并送DIO端
Delay();sck=1;
Delay();sck=0;
m=m<<1;
}
m=dat;
for(i=0;i<8;i++) //送出数据
{
din=m & 0x80; //移出到C并送DIO端
Delay();sck=1;
Delay();sck=0;
m=m<<1;
}
dout=1;
while(dout==0); //等待写完
}
//******* 读数据************************************
//OpAddH=操作指令高位,OpAddL=操作指令低位
unsigned char ReadData(unsigned char OpAddH,OpAddL)
{
unsigned char i,m;
cs=1;Delay();
m=OpAddH;
for(i=0;i<8;i++) //送出高位
{
din=m & 0x80; //移出到C并送DIO端
Delay();sck=1;
Delay();sck=0;
m=m<<1;
}
m=OpAddL;
for(i=0;i<8;i++) //送出低位
{
din=m & 0x80; //移出到C并送DIO端
Delay();sck=1;
Delay();sck=0;
m=m<<1;
}
dout=1;
for(i=0;i<8;i++) //送出低位
{
m=m<<1;
Delay();sck=1;
Delay();sck=0;
Delay();
m|=(bit)dout; //读DIO端
}
dout=0;
cs=0;
return(m);
}
//****读指定地址数据*************************************************
// 使用8位操作,PRG=0
// 93C46读写指令+地址格式:
// | SB | OP1 | OP0 | A6 | A5 | A4 | A3 | A2 | A1 | A0 |
// SB=起始位,恒=1;OP=操作命令;Add地址
// 读 OP1=1,OP0=0; 10B
//-------------------------------------------------------------------
unsigned char Read9346(unsigned char add)
{ //93C46的地址最大为127,不会干扰OP0位
din=dout=0;cs=0; //片选
return(ReadData(0x03,add)); //SB+OP1=11,OP0+ADD=传送指令和地址.返回数据
}
//****写指定地址*****************************************************
// 使用8位操作,PRG=0
// 93C46读写指令+地址格式:
// | SB | OP1 | OP0 | A6 | A5 | A4 | A3 | A2 | A1 | A0 |
// SB=起始位,恒=1;OP=操作命令;Add地址
//写 OP1=0;OP0=1; 01B
//-------------------------------------------------------------------
Writ9346(unsigned char add,Dat)
{ //写允许
din=dout=0;cs=0;
WriCmd(0x02,0x60); //SB+OP1=10B,OP0+写允许=01100000B
//写数据
WriData(0x02,(add|0x80),Dat);//SB+OP1+OP0+地址
WriCmd(0x02,0x00); //SB+OP1=10B,OP0+写禁止=00000000B
}
//******读写实例***************************************************
main()
{
unsigned char i;
din=dout=0;
cs=0;
sck=0;
prg=0; //8bit结构读写
GND=0; //地=0
VCC=1; //加电
Writ9346(0x00,0x55); //写0x55到0x00
i=Read9346(0x00); //读0x00数据并显示到 P1
while(1);
}