  | 
      
        
          1樓
          巨大八爪鱼
          2017-2-22 08:12
          
          
           
         
        /* 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(); }
  
       | 
    
    
        | 
      
        
          2樓
          巨大八爪鱼
          2017-2-22 08:45
          
          
           
         
        【一次性讀多個存儲單元】 /* 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(); }
  
       | 
    
    
        | 
      
        
          3樓
          巨大八爪鱼
          2017-2-22 13:45
          
          
           
         
        void _93C46_EnableWrite(unsigned char enabled) 這裡enabled參數用bit類型更好一點。
  
       | 
    
    
        | 
      
        
          4樓
          巨大八爪鱼
          2017-2-23 18:44
          
          
           
         
        【全部存儲單元測試】 /* 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;     } }
  
       |