| 
          【程序】51单片机操作93C46存储器 | 
        
                
          
            
                         一派护法 十九级              | 
          
            
            
             
              /* ORG悬空,选16位模式 */ #include <at89x52.h>
  #define _BV(n) (1 << (n))
  sbit CS = P1^0; sbit SK = P1^1; sbit DI = P1^2; sbit DO = P1^3;
  unsigned char code seg8[] = {0xc0, 0xf9, 0xa4, 0xb0, 0x99, 0x92, 0x82, 0xf8, 0x80, 0x90}; unsigned int num = 0;
  void delay(unsigned int n) {     unsigned char i;     while (n--)         for (i = 0; i < 115; i++); }
  // 在数码管上显示num的值 void seg_scan(void) {     char i;     unsigned int n = num;     for (i = 7; i >= 3; i--) // 从低位扫描到高位     {         P2 = 0xff;         P0 = seg8[n % 10];         P2 = ~_BV(i);         delay(3);         n /= 10;     } }
  void _93C46_WriteOP(unsigned char op) {     // 初态     CS = 0;     SK = 0;     DI = 1;          // 开始位     CS = 1;     SK = 1;     SK = 0;          // OP位     if ((op & 2) == 0)         DI = 0;     SK = 1;     SK = 0;     if (op & 1)         DI = 1;     else         DI = 0;     SK = 1;     SK = 0; }
  void _93C46_WriteAddress(unsigned char addr) {     unsigned char i;     for (i = 0; i < 6; i++)     {         if (addr & 0x20)             DI = 1;         else             DI = 0;         SK = 1;         SK = 0;         addr <<= 1;     }     DI = 0; }
  unsigned int _93C46_ReadWord(void) {     unsigned char i;     unsigned int dat = 0;     DO = 1;     for (i = 0; i < 16; i++)     {         SK = 1;         dat <<= 1;         if (DO)             dat |= 1;         SK = 0;     }     return dat; }
  unsigned int _93C46_Read(unsigned char addr) {     unsigned int dat;     _93C46_WriteOP(2);     _93C46_WriteAddress(addr);     dat = _93C46_ReadWord();     CS = 0;     return dat; }
  void _93C46_WriteWord(unsigned int dat) {     unsigned char i;     for (i = 0; i < 16; i++)     {         if (dat & 0x8000)             DI = 1;         else             DI = 0;         SK = 1;         SK = 0;         dat <<= 1;     }     DI = 0; }
  // 等待操作完毕 void _93C46_Wait(void) {     CS = 0;     CS = 1;     DO = 1; // tSV<=250ns     while (!DO);     CS = 0; }
  // 允许/禁止擦写 void _93C46_EnableWrite(unsigned char enabled) {     _93C46_WriteOP(0);     _93C46_WriteAddress((enabled) ? 0x30 : 0x00);     CS = 0; }
  // 写入单个存储单元 void _93C46_Write(unsigned char addr, unsigned int dat) {     _93C46_WriteOP(1);     _93C46_WriteAddress(addr);     _93C46_WriteWord(dat);     _93C46_Wait(); }
  // 擦除单个存储单元 void _93C46_Erase(unsigned char addr) {     _93C46_WriteOP(3);     _93C46_WriteAddress(addr);     _93C46_Wait(); }
  // 擦除所有存储单元(设为0xffff) void _93C46_EraseAll(void) {     _93C46_WriteOP(0);     _93C46_WriteAddress(0x20);     _93C46_Wait(); }
  // 将所有的存储单元设为指定值 void _93C46_WriteAll(unsigned int dat) {     _93C46_WriteOP(0);     _93C46_WriteAddress(0x10);     _93C46_WriteWord(dat);     _93C46_Wait(); }
  int main(void) {     _93C46_EnableWrite(1); // 允许写入     num = _93C46_Read(10);     _93C46_Write(10, num + 1);          _93C46_EnableWrite(0); // 禁止写入     _93C46_WriteAll(78);     _93C46_Erase(10);     _93C46_EraseAll();          while (1)         seg_scan(); }              
                       | 
        
                
          
            
                         一派护法 十九级              | 
          
            
            
             
              【一次性读多个存储单元】 /* ORG悬空,选16位模式 */ #include <at89x52.h>
  #define _BV(n) (1 << (n))
  sbit CS = P1^0; sbit SK = P1^1; sbit DI = P1^2; sbit DO = P1^3;
  unsigned char code seg8[] = {0xc0, 0xf9, 0xa4, 0xb0, 0x99, 0x92, 0x82, 0xf8, 0x80, 0x90, 0x88, 0x83, 0xa7, 0xa1, 0x86, 0x8e}; struct datablock {     unsigned int id;     unsigned int num; } db;
  void delay(unsigned int n) {     unsigned char i;     while (n--)         for (i = 0; i < 115; i++); }
  void seg_scan(void) {     char i;     unsigned int n = db.id;     for (i = 3; i >= 0; i--)     {         P2 = 0xff;         P0 = seg8[n & 0x0f];         P2 = ~_BV(i);         delay(2);         n >>= 4;     }          n = db.num;     for (i = 7; i >= 4; i--)     {         P2 = 0xff;         P0 = seg8[n & 0x0f];         P2 = ~_BV(i);         delay(2);         n >>= 4;     } }
  void _93C46_WriteOP(unsigned char op) {     // 初态     CS = 0;     SK = 0;     DI = 1;          // 开始位     CS = 1;     SK = 1;     SK = 0;          // OP位     if ((op & 2) == 0)         DI = 0;     SK = 1;     SK = 0;     if (op & 1)         DI = 1;     else         DI = 0;     SK = 1;     SK = 0; }
  void _93C46_WriteAddress(unsigned char addr) {     unsigned char i;     for (i = 0; i < 6; i++)     {         if (addr & 0x20)             DI = 1;         else             DI = 0;         SK = 1;         SK = 0;         addr <<= 1;     }     DI = 0; }
  unsigned int _93C46_ReadWord(void) {     unsigned char i;     unsigned int dat = 0;     DO = 1;     for (i = 0; i < 16; i++)     {         SK = 1;         dat <<= 1;         if (DO)             dat |= 1;         SK = 0;     }     return dat; }
  // 读入多个存储单元 void _93C46_ReadBlock(unsigned char addr, unsigned int *dat, unsigned char count) {     _93C46_WriteOP(2);     _93C46_WriteAddress(addr);     while (count > 0)     {         *dat++ = _93C46_ReadWord();         count -= 2;     }     CS = 0; }
  int main(void) {     _93C46_ReadBlock(0, (unsigned int *)&db, sizeof(db));     while (1)         seg_scan(); }              
                       | 
        
                
          
            
                         一派护法 十九级              | 
          
            
            
             
              void _93C46_EnableWrite(unsigned char enabled) 这里enabled参数用bit类型更好一点。              
                       | 
        
                
          
            
                         一派护法 十九级              | 
          
            
            
             
              【全部存储单元测试】 /* ORG悬空,选16位模式 */ #include <at89x52.h>
  #define _BV(n) (1 << (n))
  sbit CS = P1^0; sbit SK = P1^1; sbit DI = P1^2; sbit DO = P1^3;
  unsigned char code seg8[] = {0xc0, 0xf9, 0xa4, 0xb0, 0x99, 0x92, 0x82, 0xf8, 0x80, 0x90, 0x88, 0x83, 0xa7, 0xa1, 0x86, 0x8e}; unsigned char id; unsigned int num;
  void delay(unsigned int n) {     unsigned char i;     while (n--)         for (i = 0; i < 115; i++); }
  void seg_scan(void) {     char i;     unsigned int n = id;     for (i = 1; i >= 0; i--)     {         P2 = 0xff;         P0 = seg8[n % 10];         P2 = ~_BV(i);         delay(2);         n /= 10;     }          n = num;     for (i = 7; i >= 3; i--)     {         P2 = 0xff;         P0 = seg8[n % 10];         P2 = ~_BV(i);         delay(2);         n /= 10;     } }
  void _93C46_WriteOP(unsigned char op) {     // 初态     CS = 0;     SK = 0;     DI = 1;          // 开始位     CS = 1;     SK = 1;     SK = 0;          // OP位     if ((op & 2) == 0)         DI = 0;     SK = 1;     SK = 0;     if (op & 1)         DI = 1;     else         DI = 0;     SK = 1;     SK = 0; }
  void _93C46_WriteAddress(unsigned char addr) {     unsigned char i;     for (i = 0; i < 6; i++)     {         if (addr & 0x20)             DI = 1;         else             DI = 0;         SK = 1;         SK = 0;         addr <<= 1;     }     DI = 0; }
  unsigned int _93C46_ReadWord(void) {     unsigned char i;     unsigned int dat = 0;     DO = 1;     for (i = 0; i < 16; i++)     {         SK = 1;         dat <<= 1;         if (DO)             dat |= 1;         SK = 0;     }     return dat; }
  unsigned int _93C46_Read(unsigned char addr) {     unsigned int dat;     _93C46_WriteOP(2);     _93C46_WriteAddress(addr);     dat = _93C46_ReadWord();     CS = 0;     return dat; }
  void _93C46_WriteWord(unsigned int dat) {     unsigned char i;     for (i = 0; i < 16; i++)     {         if (dat & 0x8000)             DI = 1;         else             DI = 0;         SK = 1;         SK = 0;         dat <<= 1;     }     DI = 0; }
  // 等待操作完毕 void _93C46_Wait(void) {     CS = 0;     CS = 1;     DO = 1; // tSV<=250ns     while (!DO);     CS = 0; }
  // 允许/禁止擦写 void _93C46_EnableWrite(unsigned char enabled) {     _93C46_WriteOP(0);     _93C46_WriteAddress((enabled) ? 0x30 : 0x00);     CS = 0; }
  // 写入单个存储单元 void _93C46_Write(unsigned char addr, unsigned int dat) {     _93C46_WriteOP(1);     _93C46_WriteAddress(addr);     _93C46_WriteWord(dat);     _93C46_Wait(); }
  int main(void) {     unsigned char i;          _93C46_EnableWrite(1);     for (i = 0; i < 64; i++)         _93C46_Write(i, 10000 + i * 100 + i);     _93C46_EnableWrite(0);          while (1)     {         num = _93C46_Read(id);         for (i = 0; i < 50; i++)             seg_scan();                  id++;         if (id > 63)             id = 0;     } }              
                       |