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

📄 spi_x25.c

📁 调度器与SPI接口完美的结合,一种崭新的编程思路
💻 C
字号:
/*------------------------------------------------------------------*-

   SPI_X25.C (v1.00)

  ------------------------------------------------------------------

   Simple SPI library for Atmel AT89S53
   - allows data storage on Xicor X25138 EEPROM (or similar)


   COPYRIGHT
   ---------

   This code is from the book:

   PATTERNS FOR TIME-TRIGGERED EMBEDDED SYSTEMS by Michael J. Pont 
   [Pearson Education, 2001; ISBN: 0-201-33138-1].

   This code is copyright (c) 2001 by Michael J. Pont.
 
   See book for copyright details and other information.

-*------------------------------------------------------------------*/

#include "Main.H"
#include "Port.h"

#include "SPI_Core.h"
#include "SPI_X25.h"
#include "TimeoutH.h"

// ------ Public variable declarations -----------------------------

// Used to display the error code
// See Main.H for details of error codes
// See Port.H for details of the error port
extern tByte Error_code_G;

// ------ Private function prototypes ------------------------------

void SPI_Delay_T0(void);
void SPI_X25_Read_Status_Register(void);

/*------------------------------------------------------------------*-

  SPI_X25_Write_Byte()

  Store a byte of data on the EEPROM.

-*------------------------------------------------------------------*/
void SPI_X25_Write_Byte(const tWord ADDRESS, const tByte DATA)
   {
   // 0. We check the status register
   SPI_X25_Read_Status_Register();  
   
   // 1. Pin /CS is pulled low to select the device
   SPI_CS = 0;
  
   // 2. The 'Write Enable' instruction is sent (0x06)
   SPI_Exchange_Bytes(0x06);

   // 3. The /CS must now be pulled high
   SPI_CS = 1;

   // 4. Wait (briefly)
   SPI_Delay_T0();

   // 5. Pin /CS is pulled low to select the device
   SPI_CS = 0;
  
   // 6. The 'Write' instruction is sent (0x02)
   SPI_Exchange_Bytes(0x02);

   // 7. The address we wish to read from is sent.  
   //    NOTE: we send a 16-bit address: 
   //    - depending on the size of the device, some bits may be ignored.
   SPI_Exchange_Bytes((ADDRESS >> 8) & 0x00FF);  // Send MSB
   SPI_Exchange_Bytes(ADDRESS & 0x00FF);         // Send LSB

   // 8. The data to be written is shifted out on MOSI
   SPI_Exchange_Bytes(DATA);

   // 9. Pull the /CS pin high to complete the operation
   SPI_CS = 1;
   }


/*------------------------------------------------------------------*-

  SPI_X25_Read_Byte()

  Read a byte of data from the EEPROM.

-*------------------------------------------------------------------*/
tByte SPI_X25_Read_Byte(const tWord ADDRESS)
   {
   tByte Data;

   // 0. We check the status register
   SPI_X25_Read_Status_Register();  
   
   // 1. Pin /CS is pulled low to select the device
   SPI_CS = 0;
  
   // 2. The 'Read' instruction is sent (0x03)
   SPI_Exchange_Bytes(0x03);

   // 3. The address we wish to read from is sent.  
   // NOTE: we send a 16-bit address: 
   // depending on the size of the device, some bits may be ignored.
   SPI_Exchange_Bytes((ADDRESS >> 8) & 0x00FF);
   SPI_Exchange_Bytes(ADDRESS & 0x00FF);

   // 4. The data requested is shifted out on SO by sending a dummy byte
   Data = SPI_Exchange_Bytes(0x00);

   // 5. We pull the /CS pin high to complete the operation
   SPI_CS = 1;

   return Data; // Return SPI data byte
   }

/*------------------------------------------------------------------*-

  SPI_X25_Read_Status_Register()

  We read the status register only to make sure that previous
  'Write' operations (if any) are now complete.

  To do this, we check the WIP ('Write In Progress') flag.

  *** NB: THE INTERNAL EEPROM WRITE OPERATION TAKES UP 10ms ***
  *** Schedule writes (and reads after writes) at sensible ***
  *** intervals - or you will get task jitter ***

  We timeout after ~15ms.

  Uses T0 for (hardware) timeout - see Chapter 15.

-*------------------------------------------------------------------*/
void SPI_X25_Read_Status_Register()
   {
   tByte Data;
   bit Wip;

   // Configure Timer 0 as a 16-bit timer 
   TMOD &= 0xF0; // Clear all T0 bits (T1 left unchanged)
   TMOD |= 0x01; // Set required T0 bits (T1 left unchanged) 

   ET0 = 0;  // No interrupts

   // Simple timeout feature - approx 15ms
   TH0 = T_15ms_H; // See TimeoutH.H for T_ details
   TL0 = T_15ms_L;
   TF0 = 0; // Clear flag
   TR0 = 1; // Start timer

   do {
      // 0. Pin /CS is pulled low to select the device
      SPI_CS = 0;

      // 1. The 'RDSR' instruction is sent (0x05)
      SPI_Exchange_Bytes(0x05);

      // 2. The contents of the ROM status register are read
      Data = SPI_Exchange_Bytes(0x00);

      // 3. Pull the /CS pin high to complete the operation
      SPI_CS = 1;

      // Check the WIP flag
      Wip = (Data & 0x01);
      } while ((Wip != 0) && (TF0 != 1));

   TR0 = 0;  

   if (TF0 == 1)
      {
      // ROM timed out
      Error_code_G = ERROR_SPI_X25_TIMEOUT;
      }
   } 

/*------------------------------------------------------------------*-

  SPI_Delay_T0()

  A delay of approx 50 祍 using 'timeout' code.

-*------------------------------------------------------------------*/
void SPI_Delay_T0(void)
   {
   // Configure Timer 0 as a 16-bit timer 
   TMOD &= 0xF0; // Clear all T0 bits (T1 left unchanged)
   TMOD |= 0x01; // Set required T0 bits (T1 left unchanged) 

   ET0 = 0;  // No interrupts

   // Simple timeout feature - approx 50 祍
   TH0 = T_50micros_H; // See TimeoutH.H for T_ details
   TL0 = T_50micros_L;
   TF0 = 0; // Clear flag
   TR0 = 1; // Start timer

   while (!TF0);

   TR0 = 0;  
   }
  
/*------------------------------------------------------------------*-
  ---- END OF FILE -------------------------------------------------
-*------------------------------------------------------------------*/ 

⌨️ 快捷键说明

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