📄 24c04.c
字号:
//------------------------------------------------------------------------------------
// FILE NAME : SMBus_EEPROM_F31x.c
// TARGET DEVICE : C8051F310
// Revision 1.0
//
// This example demonstrates how the C8051F31x SMBus interface can communicate
// with a 256 byte I2C Serial FRAM(FM24C04A) .
// - Interrupt-driven SMBus implementation
// - Only master states defined (no slave or arbitration)
// - Timer1 used as SMBus clock source
// - Timer2 used by SMBus for SCL low timeout detection
// - SCL frequency defined by <SMB_FREQUENCY> constant
// - Pinout:
// P0.6 -> SDA (SMBus)
// P0.7 -> SCL (SMBus)
//
//------------------------------------------------------------------------------------
// Includes
//------------------------------------------------------------------------------------
#include <c8051f310.h> // SFR declarations
#include <intrins.h>
//------------------------------------------------------------------------------------
// Global CONSTANTS
//------------------------------------------------------------------------------------
#define SYSCLK 24500000 // System clock frequency
#define SMB_FREQUENCY 50000 // Target SCL clock rate
#define WRITE 0x00 // SMBus WRITE command
#define READ 0x01 // SMBus READ command
// Device addresses (7 bits, lsb is a don't care)
#define EEPROM_ADDR 0xA0 // Device address for slave target
// Note: This address is specified
// in the Microchip 24LC02B
// datasheet.
// SMBus Buffer Size
#define SMB_BUFF_SIZE 0x08 // Defines the maximum number of bytes
// that can be sent or received in a
// single transfer
// Status vector - top 4 bits only
#define SMB_MTSTA 0xE0 // (MT) start transmitted
#define SMB_MTDB 0xC0 // (MT) data byte transmitted
#define SMB_MRDB 0x80 // (MR) data byte received
// End status vector definition
sbit LED=P1^7;
//------------------------------------------------------------------------------------
// Global VARIABLES
//------------------------------------------------------------------------------------
unsigned char* pSMB_DATA_IN; // Global pointer for SMBus data
// All receive data is written here
unsigned char SMB_SINGLEBYTE_OUT; // Global holder for single byte writes
unsigned char* pSMB_DATA_OUT; // Global pointer for SMBus data.
// All transmit data is read from here
unsigned char SMB_DATA_LEN; // Global holder for number of bytes
// to send or receive in the current
// SMBus transfer
unsigned char WORD_ADDR; // Global holder for the EEPROM word
// address that will be accessed in
// the next transfer
unsigned char TARGET; // Target SMBus slave address
unsigned char temp_char;
unsigned char retval;
bit SMB_BUSY = 0; // Software flag to indicate when the
// EEPROM_ByteRead() or
// EEPROM_ByteWrite()
// functions have claimed the SMBus
bit SMB_RW; // Software flag to indicate the
// direction of the current transfer
bit SMB_SENDWORDADDR; // When set, this flag causes the ISR
// to send the 8-bit <WORD_ADDR>
// after sending the slave address
bit SMB_RANDOMREAD; // When set, this flag causes the ISR
// to send a START signal after
// sending the word address
bit SMB_ACKPOLL; // When set, this flag causes the ISR
// to send a repeated START until the
// slave has acknowledged its address
// 16-bit SFR declarations
sfr16 TMR2RL = 0xca; // Timer2 reload registers
sfr16 TMR2 = 0xcc; // Timer2 counter registers
sfr16 TMR3RL = 0x92; // Timer2 reload registers
sfr16 TMR3 = 0x94; // Timer3 counter registers
//------------------------------------------------------------------------------------
// Function PROTOTYPES
//------------------------------------------------------------------------------------
void SMBus_Init (void);
void Timer1_Init (void);
void Timer3_Init (void);
void Port_Init (void);
void SMBus_ISR (void);
void Timer3_ISR (void);
void EEPROM_ByteWrite(unsigned char addr, unsigned char dat);
void EEPROM_WriteArray (unsigned char dest_addr, unsigned char *src_addr,
unsigned char len);
unsigned char EEPROM_ByteRead(unsigned char addr);
void EEPROM_ReadArray (unsigned char *dest_addr, unsigned char src_addr,
unsigned char len);
//------------------------------------------------------------------------------------
// MAIN Routine
//------------------------------------------------------------------------------------
//
// Main routine performs all configuration tasks, then loops forever sending and
// receiving SMBus data to the slave F300_SLAVE
void main (void)
{
int iNum = 0;
// int ii;
char in_buff[8] = {0}; // incoming data buffer
char out_buff[8] = "ABCDEFG"; // outgoing data buffer
PCA0MD &= ~0x40; // WDTE = 0 (disable watchdog timer)
OSCICN |= 0x03; // Set internal oscillator to highest
// setting (24500000)
Port_Init (); // Initialize Crossbar and GPIO
Timer1_Init (); // Configure Timer1 for use as SMBus
// clock source
Timer3_Init (); // Configure Timer2 for use with SMBus
// low timeout detect
SMBus_Init (); // Configure and enable SMBus
EIE1 = 0x81; // SMBus interrupt enable
// IE = 0x80; // Timer2 interrupt enable
EA = 1; // Global interrupt enable
while(1){
// Write the value 0xAA to location 0x25 in the EEPROM
EEPROM_ByteWrite(0x26, 0xaa);
// Read the value at location 0x25 in the EEPROM
temp_char = EEPROM_ByteRead(0x26);
// Write the value 0xBB to location 0x25 in the EEPROM
EEPROM_ByteWrite(0x25, 0xDD);
// Write the value 0xCC to location 0x38 in the EEPROM
EEPROM_ByteWrite(0x38, 0xCC);
// Read the value at location 0x25 in the EEPROM
temp_char = EEPROM_ByteRead(0x25);
// Read the value at location 0x38 in the EEPROM
temp_char = EEPROM_ByteRead(0x38);
// Store the outgoing data buffer at EEPROM address 0x50
EEPROM_WriteArray(0x50, out_buff, sizeof(out_buff));
// Fill the incoming data buffer with data starting at EEPROM address 0x50
EEPROM_ReadArray(in_buff, 0x50, sizeof(in_buff));}
// while(1);
}
//------------------------------------------------------------------------------------
// Functions
//------------------------------------------------------------------------------------
//------------------------------------------------------------------------------------
// EEPROM_Write ()
//------------------------------------------------------------------------------------
//
// This function writes the value in <dat> to location <addr> in the EEPROM then polls
// the EEPROM until the write is complete.
//
void EEPROM_ByteWrite( unsigned char eaddr, unsigned char edat )
{
while (SMB_BUSY); // Wait for SMBus to be free.
SMB_BUSY = 1; // Claim SMBus (set to busy)
// Set SMBus ISR parameters
TARGET = EEPROM_ADDR; // Set target slave address
SMB_RW = WRITE; // Mark next transfer as a write
SMB_SENDWORDADDR = 1; // Send Word Address after Slave Address
SMB_RANDOMREAD = 0; // Do not send a START signal after
// the word address
SMB_ACKPOLL = 1; // Enable Acknowledge Polling (The ISR
// will automatically restart the
// transfer if the slave does not
// acknowledge its address.
// Specify the Outgoing Data
WORD_ADDR = eaddr; // Set the target address in the EEPROM's
// internal memory space
SMB_SINGLEBYTE_OUT = edat; // store dat (local variable) in a global
// variable so the ISR can read it after
// this function exits
pSMB_DATA_OUT = &SMB_SINGLEBYTE_OUT; // The outgoing data pointer points to
// the <dat> variable.
SMB_DATA_LEN = 1; // Specify to ISR that the next transfer
// will contain one data byte
// Initiate SMBus Transfer
STA = 1;
}
//------------------------------------------------------------------------------------
// EEPROM_WriteArray ()
//------------------------------------------------------------------------------------
// Writes <len> data bytes to the EEPROM slave specified by the <EEPROM_ADDR>
// constant.
//
void EEPROM_WriteArray (unsigned char dest_addr, unsigned char* src_addr,
unsigned char len)
{
unsigned char i;
unsigned char* pData = (unsigned char*) src_addr;
for( i = 0; i < len; i++ ){
EEPROM_ByteWrite(dest_addr++, *pData++);
}
}
//------------------------------------------------------------------------------------
// EEPROM_ByteRead ()
//------------------------------------------------------------------------------------
//
// This function returns a single byte from location <addr> in the EEPROM then
// polls the <SMB_BUSY> flag until the read is complete.
//
unsigned char EEPROM_ByteRead( unsigned char daddr)
{
// unsigned char retval; // Holds the return value
while (SMB_BUSY); // Wait for SMBus to be free.
SMB_BUSY = 1; // Claim SMBus (set to busy)
// Set SMBus ISR parameters
TARGET = EEPROM_ADDR; // Set target slave address
SMB_RW = WRITE; // A random read starts as a write
// then changes to a read after
// the repeated start is sent. The
// ISR handles this switchover if
// the <SMB_RANDOMREAD> bit is set.
SMB_SENDWORDADDR = 1; // Send Word Address after Slave Address
SMB_RANDOMREAD = 1; // Send a START after the word address
SMB_ACKPOLL = 1; // Enable Acknowledge Polling
// Specify the Incoming Data
WORD_ADDR = daddr; // Set the target address in the EEPROM's
// internal memory space
pSMB_DATA_IN = &retval; // The incoming data pointer points to
// the <retval> variable.
SMB_DATA_LEN = 1; // Specify to ISR that the next transfer
// will contain one data byte
// Initiate SMBus Transfer
STA = 1;
while(SMB_BUSY); // Wait until data is read
return retval;
}
///////////////
//-------------------------------------------------------------------
/*
unsigned char EEPROM_ByteRead( unsigned char addr)
{
// unsigned char retval; // Holds the return value
int iLim1 = 100;
int iLim2 = 25000;
int iNum1 = 0;
int iNum2 = 0;
while (SMB_BUSY && iNum1 <iLim1 )
{
while(SMB_BUSY && iNum2 < iLim2)
{
iNum2++;
}
iNum2 = 0;
iNum1++;
} // Wait for SMBus to be free.
if( iNum1 >= iLim1)
{
return 0xcb;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -