📄 smb_tsl2550_driver.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 + -