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

📄 smb_tsl2550_driver.c

📁 TSL_2550_Driver using I2C
💻 C
字号:
//------------------------------------------------------------------------------------
//
//
// FILE NAME      : SMB_TSL2550_DRIVER.c
// TARGET DEVICE  : C8051F020
// CREATED ON     : 24/MAR/2009
// CREATED BY     : PPD
//
//
// Example code for interfacing a C8051F020 to the TSL2550
// (Ambient Light Sensor) via the SMBus.
// Code assumes that device is connected
// on the SCL  and SDA lines, and configured so that the
// slave address is as follows:
// CHIP_A = 0111 001[]	  = 72 hex
// the lsb determines the read/write operation
// Slave and arbitration states are not defined.  Assume the F020 is the only
// master in the system.
// Functions: SM_Send performs a 1-byte write to the device
// SM_Receive performs a 1-byte read from the device
//
//------------------------------------------------------------------------------------
// Includes
//------------------------------------------------------------------------------------
#include "C8051F020.h"              // SFR declarations
#include "MySystem.h"               // my declarations
#include "UART0.h"                  // UART0 declarations
#include "SMB_DRIVER.h"

#include <stdio.h>

//-----------------------------------------------------------------------------------
//Global VARIABLES
//-----------------------------------------------------------------------------------
char COMMAND;                       // Holds the slave address + R/W bit for
                                    // use in the SMBus ISR.
char DATABUF;                       // Holds data to be transmitted by the SMBus
                                    // OR data that has just been received.
bit SM_BUSY;                        // This bit is set when a send or receive
                                    // is started. It is cleared by the
                                    // ISR when the operation is finished.

//-----------------------------------------------------------------------------------
//-----------------------------------------------------------------------------------

//-----------------------------------------------------------------------------
// SMBUS_Init
//-----------------------------------------------------------------------------
//
// Initialise the SMbus
//
void SMBUS_Init (void)
{
   SMB0CN = 0x44;                   // Enable SMBus with ACKs on acknowledge 
                                    // cycle
   SMB0CR = -110;                   // SMBus clock rate = 100kHz. (- 22118400/(2*100000))

   EIE1 |= 2;                       // SMBus interrupt enable
}


// SMBus byte write function-----------------------------------------------------
// Writes a single byte at the specified memory location.
//
// out_byte = data byte to be written
// chip_select = device address of sensor chip to be written to
void SM_Send (char chip_select, char out_byte)
{
   while (SM_BUSY);                          // Wait for SMBus to be free.
   SM_BUSY = 1;                              // Occupy SMBus (set to busy)
   SMB0CN = 0x44;                            // SMBus enabled,
                                             // ACK on acknowledge cycle

   COMMAND = (chip_select | WRITE);          // Chip select + WRITE

   DATABUF = out_byte;                       // Data to be written
   
   STO = 0;
   STA = 1;                                  // Start transfer

}

// SMBus random read function------------------------------------------------------
// Reads 1 byte from the specified memory location.
//
// chip_select = device address of sensor to be read from
char SM_Receive (char chip_select)
{
   while (SM_BUSY);                          // Wait for bus to be free.
   SM_BUSY = 1;                              // Occupy SMBus (set to busy)
   SMB0CN = 0x44;                            // SMBus enabled, ACK on acknowledge cycle

   COMMAND = (chip_select | READ);           // Chip select + READ
   
   STO = 0;
   STA = 1;                                  // Start transfer
   while (SM_BUSY);                          // Wait for transfer to finish

   return DATABUF;
}


//------------------------------------------------------------------------------------
// Interrupt Service Routine
//------------------------------------------------------------------------------------


// SMBus interrupt service routine:

void SMBUS_ISR (void) interrupt 7
{
   switch (SMB0STA){                   // Status code for the SMBus (SMB0STA register)

      // Master Transmitter/Receiver: START condition transmitted.
      // The R/W bit of the COMMAND word sent after this state will
      // always be a zero (W) because for both read and write,
      // the memory address must be written first.
      case SMB_START:
         SMB0DAT = (COMMAND & 0xFE);   // Load address of the slave to be accessed.
         STA = 0;                      // Manually clear START bit
         break;

      // Master Transmitter/Receiver: Repeated START condition transmitted.
      // This state should only occur during a read, after the memory address has been
      // sent and acknowledged.	(Used in case of EEPROMs)
      case SMB_RP_START:
         SMB0DAT = COMMAND;            // COMMAND should hold slave address + R.
         STA = 0;
         break;

      // Master Transmitter: Slave address + WRITE transmitted.  ACK received.
      case SMB_MTADDACK:
               if (COMMAND & 0x01){    // If R/W=READ, send repeated START.
                  STO = 0;
                  STA = 1;

               } else { 
                  SMB0DAT = DATABUF;   // If R/W=WRITE, load byte to write.
               }
               break;

      // Master Transmitter: Slave address + WRITE transmitted.  NACK received.
      // The slave is not responding.  Send a STOP followed by a START to try again.
      case SMB_MTADDNACK:
         STO = 1;
         STA = 1;
         break;

      // Master Transmitter: Data byte transmitted.  ACK received.
	  // Transfer ready
      case SMB_MTDBACK:
         STO = 1;
         SM_BUSY = 0;            // Free SMBus
         break;


      // Master Transmitter: Data byte transmitted.  NACK received.
      // Slave not responding.  Send STOP followed by START to try again.
      case SMB_MTDBNACK:
         STO = 1;
         STA = 1;
         break;

      // Master Transmitter: Arbitration lost.
      // Should not occur.  If so, restart transfer.
      case SMB_MTARBLOST:
         STO = 1;
         STA = 1;
         break;

      // Master Receiver: Slave address + READ transmitted.  ACK received.
      // Set to transmit NACK after next transfer since it will be the last (only)
      // byte.
      case SMB_MRADDACK:
         AA = 0;                       // NACK sent on acknowledge cycle.
         break;

      // Master Receiver: Slave address + READ transmitted.  NACK received.
      // Slave not responding.  Send repeated start to try again.
      case SMB_MRADDNACK:
         STO = 0;
         STA = 1;
         break;

      // Data byte received.  ACK transmitted.
      // State should not occur because AA is set to zero in previous state.
      // Send STOP if state does occur.
      case SMB_MRDBACK:
         STO = 1;
         SM_BUSY = 0;
         break;

      // Data byte received.  NACK transmitted.
      // Read operation has completed.  Read data register and send STOP.
      case SMB_MRDBNACK:
         DATABUF = SMB0DAT;
         STO = 1;
         SM_BUSY = 0;                  // Free SMBus
         break;

      // All other status codes are meaningless in this application. Reset communication.
      default:
         STO = 1;                      // Reset communication.
         SM_BUSY = 0;
         break;
      }

   SI=0;                               // clear interrupt flag
}

⌨️ 快捷键说明

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