#include <c8051f020.h>
#include "24cxx.h"
#include "define.h"
/******************************************************************************************
* 全局变量定义
******************************************************************************************/
uchar FRAM_Update_Buffer[2]={0,0}; //更新铁电缓冲区
uchar FRAM_Read_Buffer[2]={0,0}; //读缓铁电冲区
char COMMAND; // Holds the slave address + R/W bit for
// use in the SMBus ISR.
char WORD; // Holds data to be transmitted by the SMBus
// OR data that has just been received.
char BYTE_NUMBER; // Used by ISR to check what data has just been
// sent - High address byte, Low byte, or data
// byte
unsigned char HIGH_ADD, LOW_ADD; // High & Low byte for EEPROM memory address
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.
/******************************************************************************************
*函数名: SM_Init
*参数: 无
*返回值: 无
*描述: SMBus初始化
*编写: 罗维平
*版本信息: V1.0 2005年11月29日
******************************************************************************************/
void SM_Init(void)
{
SMB0CN = 0x44; // Enable SMBus with ACKs on acknowledge
// cycle
SMB0CR = -80; // SMBus clock rate = 100kHz.
EIE1 |= 2; // SMBus interrupt enable
SM_BUSY = 0; // Free SMBus for first transfer.
}
/******************************************************************************************
*函数名: SM_Send
*参数: char chip_select ,要发送器件(EEPROM 芯片)的地址
* unsigned int byte_address,要存储的位置地址(2个字节)
* char out_byte ,要写入的内容
*返回值: 无
*描述: SMBus向存储器写单个字节
*编写: 罗维平
*版本信息: V1.0 2005年11月29日
******************************************************************************************/
void SM_Send (char chip_select, unsigned int byte_address, 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
BYTE_NUMBER = 2; // 2 address bytes.
COMMAND = (chip_select | WRITE); // Chip select + WRITE
HIGH_ADD = ((byte_address >> 8) & 0x00FF);// Upper 8 address bits
LOW_ADD = (byte_address & 0x00FF); // Lower 8 address bits
WORD = out_byte; // Data to be writen
STO = 0;
STA = 1; // Start transfer
}
/******************************************************************************************
*函数名: SM_Receive
*参数: char chip_select ,要读入器件(EEPROM 芯片)的地址
* unsigned int byte_address,要读字节的存储的位置地址(2个字节)
*返回值: char ,读出的内容,1个字节
*描述: SMBus从存储器读单个字节
*编写: 罗维平
*版本信息: V1.0 2005年11月29日
******************************************************************************************/
char SM_Receive (char chip_select, unsigned int byte_address)
{
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
BYTE_NUMBER = 2; // 2 address bytes
COMMAND = (chip_select | READ); // Chip select + READ
HIGH_ADD = ((byte_address >> 8) & 0x00FF);// Upper 8 address bits
LOW_ADD = (byte_address & 0x00FF); // Lower 8 address bits
STO = 0;
STA = 1; // Start transfer
while (SM_BUSY); // Wait for transfer to finish
return WORD;
}
/******************************************************************************************
*函数名: FRAM_Update
*参数: unsigned int byte_address,要更新存储的位置地址(2个字节)
*返回值: 无
*描述: 更新铁电存储器相应地址的信息,2个字节
*编写: 罗维平
*版本信息: V1.0 2005年11月29日
******************************************************************************************/
void FRAM_Update(uint address)
{
SM_Send(CHIP_A, address, FRAM_Update_Buffer[0]);
SM_Send(CHIP_A, address+1, FRAM_Update_Buffer[1]);
}
/******************************************************************************************
*函数名: FRAM_Read
*参数: unsigned int byte_address,要更新存储的位置地址(2个字节)
*返回值: 无
*描述: 从铁电存储器相应地址读取信息,2个字节
*编写: 罗维平
*版本信息: V1.0 2005年11月29日
******************************************************************************************/
void FRAM_Read(uint address)
{
FRAM_Read_Buffer[0] = SM_Receive(CHIP_A, address);
FRAM_Read_Buffer[1] = SM_Receive(CHIP_A, address+1);
}
/******************************************************************************************
*函数名: SMBUS_ISR
*参数: 无
*返回值: 无
*描述: SMBus 中断服务子程序
*编写: 罗维平
*版本信息: V1.0 2005年11月29日
******************************************************************************************/
// 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.
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:
SMB0DAT = HIGH_ADD; // Load high byte of memory address
// to be written.
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.
// This state is used in both READ and WRITE operations. Check BYTE_NUMBER
// for memory address status - if only HIGH_ADD has been sent, load LOW_ADD.
// If LOW_ADD has been sent, check COMMAND for R/W value to determine
// next state.
case SMB_MTDBACK:
switch (BYTE_NUMBER){
case 2: // If BYTE_NUMBER=2, only HIGH_ADD
SMB0DAT = LOW_ADD; // has been sent.
BYTE_NUMBER--; // Decrement for next time around.
break;
case