⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 sle4428.c

📁 该程序用来测试89C51与IDE硬盘的接口
💻 C
字号:
/*------------------------------------------------------------------------*/
/*==========sle4428 card==========*/
/* 1024x8 bit EEPROM              */
/* 1024x1 bit protection memory   */
/* sle4428卡复位与响应复位函数    */ 
void sle4428_reset(void)
{
   uchar i=31;
   SLECLK=0;
   SLERST=0;
   delay_12us();            // tPOR  
   delay_12us();            // tPOR  
   SLERST=1;
   delay_4us();
   SLECLK=1;
   delay_12us();
   SLECLK=0;
   delay_4us();
   SLERST=0;
   delay_4us();
   while(i--)
   {
      SLECLK=1;
      delay_12us();
      SLECLK=0;
      delay_12us();
   }
   SLEIO=1;
}

/*------------------------------------------------------------------------*/
/* sle4428卡串行输入一个字节函数,或说CPU向卡写一个字节 */ 
void sle4428_si(char dat)       // IC input a byte
{
   uchar j=8;
   do {
      SLEIO=(bit)(dat&0x01);
      SLECLK=1;
      delay_12us();
      SLECLK=0;
      dat>>=1;
   }  while(--j);
}

/*------------------------------------------------------------------------*/
/* sle4428卡串行输出一个字节函数,或说CPU从卡读一个字节 */ 
char sle4428_so(void)           // IC output a byte
{
   uchar rbyte,i=8;
   P1|=0x02;                    //  SLEIO=P1.1
   while(i--)
   { 
      rbyte>>=1;
      SLECLK=1;
      if (SLEIO) rbyte|=0x80;    // 先送低位
      delay_4us();
      SLECLK=0;
      delay_4us();
   }
   return(rbyte);
}

/*-------------------------------------------------------------------------*/
/* sle4428卡命令模式函数 */ 
void sle4428_command(uchar control,uint address,uchar dat)
{
   union aa                   // 联合体
   {
     char a[2];
     unsigned int b;
   } c;
   c.b=address;                //  
   c.a[0]<<=6;
   control|=c.a[0];
   SLERST=1;
   delay_12us();               // tRE
   SLECLK=0;
   sle4428_si(control);
   sle4428_si(c.a[1]);
   sle4428_si(dat);
   SLEIO=1;
   delay_4us();
   SLERST=0;
   delay_4us();
   SLECLK=1;
   delay_12us();
   SLECLK=0;
   delay_4us();
}

/*-------------------------------------------------------------------------*/
/* sle4428卡输出模式函数 */ 
uint sle4428_outgoing(char *rdbuf,uint size,uint n)
{
   uint i,j=0;
   while(n--)
   {
      i=size;
      while(i--)
      {
         if (ATIN) return(j);              // 若抽卡,返回
         *rdbuf++=sle4442_so();
      }
      j++;
   }
   SLERST=1;
   return(j);
}

/*-------------------------------------------------------------------------*/
/* sle4428卡比较模式函数 */ 
void sle4428_comp(void)
{
   P1|=0x02;
   do {
      delay_4us();
      SLECLK=1;
      delay_12us();
      SLECLK=0;
      delay_4us();
   }  while(!ATIN&&SLEIO);
}

/*-------------------------------------------------------------------------*/
/* sle4428卡编程模式函数 */ 
void sle4428_programming(uchar n)     // waiting program
{
   while(n--)
   {
      SLECLK=1;
      delay_12us();
      SLECLK=0;
      delay_4us();
   }
   P1|=0x02;
   while(!ATIN&&SLEIO);
}

/*--------------------------------------------------------------------------*/
/* 读sle4428卡错误计数器函数 */ 
char sle4428_rdEC(void)                     // read EC
{
   sle4428_reset();
   sle4428_command(0x0e,1021,0xff);
   return(sle4428_so());
}

/*--------------------------------------------------------------------------*/
/* 校验sle4428卡密码函数 */ 
/* 输入形参: Compare verification data */
char sle4428_vPSC(char *vdbuf)
{ 
   uchar wcounter,i=0;
   wcounter=sle4428_rdEC();                 // 读错误计数器
   if (wcounter&0x01) wcounter&=0xfe;
   else 
      if (wcounter&0x02) wcounter&=0xfc;
      else 
         if (wcounter&0x04) wcounter&=0xf8;
         else 
            if (wcounter&0x08) wcounter&=0xf0;
            else 
               if (wcounter&0x10) wcounter&=0xe0;
               else 
                  if (wcounter&0x20) wcounter&=0xc0;
                  else 
                     if (wcounter&0x40) wcounter&=0x80;
                     else 
                        wcounter=0;
   sle4428_reset();
   sle4428_command(0x32,1021,wcounter);     // 写错误计数器
   sle4428_programming(102);
   sle4428_command(0x0d,1022,vdbuf[0]);     // 比较 PSC byte 1
   sle4428_comp();
   sle4428_command(0x0d,1023,vdbuf[1]);     // 比较 PSC bye 2
   sle4428_comp();
   sle4428_command(0x33,1021,0xff);         // 擦错误计数器
   sle4428_programming(102);
   wcounter=sle4428_rdEC();                 // 再读错误计数器
   while(wcounter)
   {
     if (wcounter&0x80) i++;   // 把错误计数器的'bit mask'值转换为十进制数 
     wcounter<<=1; 
   }
   return(i);                  // 返回计数(=8,正确,否则错)
}

/*-------------------------------------------------------------------------*/
/* 修改sle4428卡密码函数, 输入形参为存放密码数的指针 */ 
uint sle4428_uPSC(char *scbuf)
{                                          // Update security memory
   uchar i;
   sle4428_reset();
   sle4428_command(0x33,1022,scbuf[0]);
   sle4428_programming(203);
   sle4428_command(0x33,1023,scbuf[1]);
   sle4428_programming(203);
   if (sle4428_vPSC(scbuf)==8) return 0;
   else return 1;
}  

/*-----------------------------------------------------------------------*/
/* 读sle4428卡一个字节函数 */ 
/* 输入形参: addr=0-1020   */
char sle4428_rb(uint addr)
{
   sle4428_reset();
   sle4428_command(0x0e,addr,0xff);
   return(sle4428_so());
}

/*------------------------------------------------------------------------*/
/* 向sle4428卡写一个字节函数          */ 
/* 输入形参: addr=0-1020, dat=写数据  */
char sle4428_wb(uint addr,uchar dat) 
{  
   sle4428_reset();
   sle4428_command(0x33,addr,dat);
   sle4428_programming(203);
   return(sle4428_rb(addr));
}

/*-----------------------------------------------------------------------*/
/* 连带保护位读sle4428卡一个字节函数 */ 
/* 输入形参: 单元地址(addr=0-127)    */
int sle4428_rPB(uint addr)              // read a byte with protect bit
{ 
   int dat;
   sle4428_reset();
   sle4428_command(0x0c,addr,0xff);     // 带保护位读命令
   dat=sle4428_so();
   if (SLEIO) dat|=0x8000;              // 把保护位内容赋予数据符号位
   else dat&=0x00ff;
   return(dat);
}

/*-----------------------------------------------------------------------*/
/* 连带保护位向sle4428卡写一个字节函数 */ 
/* 保护位单元0-127 */
int sle4428_wPB(uint addr,uchar dat) 
{
   sle4428_reset();
   sle4428_command(0x30,addr,dat);      // 比较命令:正确则写,否则不写
   sle4428_comp();
   return(sle4428_rPB(addr));
}

/*-------------------------------------------------------------------------*/
/* 从sle4428卡主存贮器读一个数据块函数               */
/* 输入形参:存数据块指针,块大小,块个数和卡的起始地址 */ 
uint sle4428_rd(void *rdbuf,uint size,uint n,uint addr) 
{ 
   uchar *dp;
   dp=rdbuf;
   if (!check_card(60)) return 0;
   sle4428_reset();
   sle4428_command(0x0e,addr,0xff);
   return(sle4428_outgoing(dp,size,n));
}

/*-------------------------------------------------------------------------*/
/* 向sle4428卡主存贮器写一个数据块函数               */
/* 输入形参:存数据块指针,块大小,块个数和卡的起始地址 */ 
uint sle4428_wr(void *wrbuf,uint size,uint n,uint addr)
{ 
   uchar *dp;
   uint i,j=0;
   if (!check_card(60)) return 0;                  // 无卡返回0 
   dp=wrbuf;
   sle4428_reset();
   while(n--)
   {
      i=size;
      while(i--)
      {
         if (sle4428_wb(addr,*dp)!=*dp) return(j);  // 写不确返回
         addr++;
         dp++; 
      }
      j++;
   }
   return(j);                                      // j=n,正确,否则错
}

/*=======================================================================*/
/*-------------------------------------------------------------------------*/

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -