C8051F310 SMBus 调试OK

合集下载
  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

用了半个月才调通的,希望大家收藏,下载,交流
//SMBus.c文件
/*************************************************************/
/* 例程是新华龙官网的原来用的是A T24C256现在用A T24C08 */
/* 地址原来用高位和地位现在把它改成只是一个读写地址*/
/*************************************************************/
#define INT_ISR_C
#include <c8051f310.h>
#include <intrins.h>
#include "smbus.h"
#include "uart0.h"
#include "delay.h"
unsigned char i=0; // Used by the ISR to count the
unsigned char temp;
/************************************************************/
/* STA:SMBus 起始标志ARBLOST :SMBus 竞争失败标志
/* STO :SMBus 停止标志ACK :SMBus 确认标志
/* ACKRQ :SMBus 确认请求SI :SMBus 中断标志
/***********************************************************/
void I2C_Init(void)
{
TMOD |= 0x02; //自动重装载的8 位计数器/定时器
CKCON |= 0x04; //定时器0 使用系统时钟
TH0 = 0xEC; //400k/s 400kHZ
EIE1 = 0x01; //Enable SMBus interrupt 允许SMB0 的中断请求
SMB0CF |= 0xD0; //Enable SMBus and 允许SDA建立和保持时间扩展禁止从方式
SMB0CN |= 0x80; //SMBus 工作在主方式
TR0 = 1; //Enable timer1
}
void Timer3_Init(void)
{
TMR3RLL = 0x9F; //Timer3 will overflow at 25ms
TMR3RLH = 0x38;
EIE1 |= 0x80; //Enable timer3 interrupt 允许TF3L 或TF3H 标志的中断请求TMR3CN = 0x04; //使能定时器3
}
//------------------------------------------------------------------------------------
// Timer3 Interrupt Service Routine (ISR)
//------------------------------------------------------------------------------------
//
// A Timer3 interrupt indicates an SMBus SCL low timeout.
// The SMBus is disabled and re-enabled here
//
void Timer3_ISR (void) interrupt 14
{
SMB0CF &= ~0x80; // 禁止SMBus
SMB0CF |= 0x80; // 重新启动SMBus
TMR3CN &= ~0x80; // 中断标志清零
}
//------------------------------------------------------------------------------------
// SMBus Interrupt Service Routine (ISR) SMB0DA T存放地址的
//------------------------------------------------------------------------------------
//
// SMBus ISR state machine
// - Master only implementation - no slave or arbitration states defined
// - All incoming data is written starting at the global pointer <pSMB_DA TA_IN>
// - All outgoing data is read from the global pointer <pSMB_DA TA_OUT>
//
void SMBus_ISR (void) interrupt 7
{
bit FAIL = 0; // Used by the ISR to flag failed
// transfers
// number of data bytes sent or
// received
static bit SEND_START = 0; // Send a start
switch (SMB0CN & 0xF0) // Status vector 高四位&上不变低四位都为零
{
// Master Transmitter/Receiver: START condition transmitted.
case SMB_MTSTA://【送器件地址】//开始传送case 是0xE0 SMB0DA T = (TARGET|SMB_RW); // Load address of the target slave
//0XA1
// SMB0DA T |= SMB_RW // Load R/W bit
STA = 0; // Manually clear START bit STA:SMBus 起始标志
i = 0;
// reset data byte counter
break;
/*为什么一开始第一步EEPROM_ByteRead()就要返回值?结果到最后temp里有值却不返回*/
/*按照每个地址存一个一不应该下下移啊找的原因了*/
// Master Transmitter: Data byte (or Slave Address) transmitted
case SMB_MTDB://case 是0xC0 // (MT) 数据字节传送SMB0CN :SMBus 控制寄存器
if (ACK) /*时序上是低电平这个也可能是原因*/// Slave Address or Data Byte 接收到“确认”
{ // Acknowledged?
if (SEND_START) //
{ /*按照时序应答之后开始根据程序的话会先进入判断之后再开始*/
STA = 1; //SMBus开始
SEND_START = 0;
break;
}
if(SMB_SENDWORDADDR) // Are we sending the w ord address? 高八位
{
SMB_SENDWORDADDR = 0; // Clear flag 高八标志位
SMB0DA T = WORD_ADDR; /*因为是A T24C08这只送一位地址*/
//【送高位地址】end word's high 8bits address
if (SMB_RANDOMREAD)
{
SEND_START = 1; // send a START after the next ACK cycle
SMB_RW = READ;
}
break;
}
// else if(SMB_SENDWORDADDR1) // Are we sending the word address? 低八位
// {
// SMB_SENDWORDADDR1 = 0; // Clear flag
// SMB0DA T = WORD_ADDR1;//【送低位地址】send word's low 8bits address // /*一下注销部分移到上面因为只传一位地址*/
//// if (SMB_RANDOMREAD)
//// {
//// SEND_START = 1; // send a START after the next ACK cycle
//// SMB_RW = READ;
//// }
//
// break;
// }
if (SMB_RW==WRITE) // Is this transfer a WRITE?
{
if (i < SMB_DA TA_LEN) // Is there data to send? SMB_DA TA_LEN = 1;
{ //【写数据】
SMB0DA T = *pSMB_DA TA_OUT; // send data byte *pSMB_DA TA_OUT是指针指的是地址
pSMB_DA TA_OUT++; // increment data out pointer数据++是加地址指向例如从0x00>>0x01
i++;
}
else
{
STO = 1; // set STO to terminte transfer 传送接收
SMBUS_WRITE_FLAG=1; //加标志位
i = 0; //i 清零
}
}
else {} // If this transfer is a READ,
// then take no action. Slave
// address was transmitted. A
// separate 'case' is defined
// for data byte recieved.
}
else // If slave NACK,
{
if(SMB_ACKPOLL)
{
STA = 1; // Restart transfer
}
else
{
FAIL = 1; // Indicate failed transfer
} // and handle at end of ISR
}
break;
// Master Receiver: byte received
case SMB_MRDB: //0x80 //(MR) 数据字节接收P0:端口0 寄存器
if(ACK)
{
if(SMB_RW==READ)
{
i++;
temp = SMB0DA T;
if (i == SMB_DA TA_LEN) // This is the last byte
{
ACK = 0; // Send NACK to indicate last byte
SMBUS_RECV_FLAG=1; // of this transfer
STO = 1;
i = 0; // Send STOP to terminate transfer
}
}
}
break;
default: //所以的case事件都不成立的执行的事件
FAIL = 1; // Indicate failed transfer
// and handle at end of ISR
break;
}
if (FAIL) // If the transfer failed,
{
SMB0CN &= ~0x40; // Reset communication
SMB0CN |= 0x40; //先清零再发送模式}
SI=0; // clear interrupt flag 清中断
}
//------------------------------------------------------------------------------------
// Functions
//------------------------------------------------------------------------------------
//------------------------------------------------------------------------------------
// EEPROM_ByteWrite ()
//------------------------------------------------------------------------------------
//
// This function writes the value in <dat> to location <addr> in the EEPROM then
// polls the EEPROM until the write is complete.
/*addr原为int型unsigned int addr 现改成unsigned char addr */
void EEPROM_ByteWrite( unsigned char addr, unsigned char dat ) //地址数据
{
// Set SMBus ISR parameters
TARGET = EEPROM_ADDR; // Set target slave address
SMB_RW = WRITE; // Mark next transfer as a write
SMB_SENDWORDADDR = 1; // Send high 8bits Word Address after Slave Address
// SMB_SENDWORDADDR1 = 1; /*原来为256两位地址现注销掉*/ Send low 8bits 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
// acknoledge its address.
// Specify the Outgoing Data
WORD_ADDR = addr; /*A T24C08 一位地址修改*/
// WORD_ADDR = addr/256; /*原来为256两位地址现注销掉*/Set the target address in the
// EEPROM's internal memory space
// WORD_ADDR1 = addr%256; /*原来为256两位地址现注销掉*/Set the target address in the
// EEPROM's internal memory space
SMB_SINGLEBYTE_OUT = dat; // store dat (local variable) in a global
// variable so the ISR can read it after
// this function exits
pSMB_DA TA_OUT = &SMB_SINGLEBYTE_OUT; // The outgoing data pointer points to
SMB_DA TA_LEN = 1; // Specify to ISR that the next transfer
// will contain one data byte
// Initiate SMBus Transfer
STA = 1;
}
//------------------------------------------------------------------------------------
// 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 addr) //读的时候只能读一个字节,其他的是没有存,存不住的
{ //即使放到了temp_char[8]中,但是在上电时就会失去了
// 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 high 8bits Word Address after Slave Address
// SMB_SENDWORDADDR1 = 1;/*原为256两位地址现注销掉*/ // Send low 8bits Word Address after Slave Address
SMB_RANDOMREAD = 1; //SMB_RW = READ; // Send a START after the w ord address
SMB_ACKPOLL = 1; // Enable Acknowledge Polling
// Specify the Incoming Data
WORD_ADDR = addr; /*A T24C08 一位地址修改*/
// WORD_ADDR = addr/256;/*原来为256两位地址现注销掉*/Set the target address in the
// EEPROM's internal memory space
// WORD_ADDR1 = addr%256;/*原来为256两位地址现注销掉*/Set the target address in the
// EEPROM's internal memory space
SMB_DA TA_LEN = 1; // Specify to ISR that the next transfer
// will contain one data byte
// Initiate SMBus Transfer
STA = 1;
while(SMBUS_RECV_FLAG==0); /*原两句注销到了,所以每次STA = 1之后就开始返回*/
SMBUS_RECV_FLAG=0; /*加上之后是等STO = 1也就是结束之后再返回这个值*/
//有return retval 就相当于A=retval return temp;
}
//SMBus.h文件
////////////////////////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////////////////////
extern void I2C_Init(void);
extern void Timer3_Init(void);
extern unsigned char temp_char[12];
extern bit SMBUS_RECV_FLAG;
extern bit SMBUS_WRITE_FLAG;
sfr16 DP = 0x82;
sfr16 ADC0 = 0xbd;
sfr16 ADC0GT = 0xc3;
sfr16 ADC0LT = 0xc5;
sfr16 RCAP2 = 0xeb;
sfr16 TMR2 = 0xcc;
sfr16 TMR3 = 0x94;
#ifdef INT_ISR_C
#define WRITE 0x00 // SMBus WRITE command
#define READ 0x01 // SMBus READ command
// Device addresses (7 bits, lsb is a don't care)
#define Write_EE_Addr 0xA0 //器件写地址+写命令
#define Read_EE_Addr 0xa1 //器件写地址+读命令
#define EEPROM_ADDR 0xA0 // 铁电存储器的地址
// Note: This address is specified
// in the Microchip 24C256
// 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_MTSTA0xE0 // (MT) 开始传送ACC:累加器
#define SMB_MTDB 0xC0 // (MT) 数据字节传送SMB0CN :SMBus 控制寄存器
#define SMB_MRDB 0x80 // (MR) 数据字节接收P0:端口0 寄存器
// End status vector definition
//------------------------------------------------------------------------------------
// Global V ARIABLES
//------------------------------------------------------------------------------------
unsigned char* pSMB_DA TA_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_DA TA_OUT; // Global pointer for SMBus data.
// All transmit data is read from here
unsigned char SMB_DA TA_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
// high 8bits address that will be accessed in
// the next transfer
unsigned char WORD_ADDR1; // Global holder for the EEPROM word
// low 8bits address that will be accessed in
// the next transfer
unsigned char TARGET; // Target SMBus slave address
// 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 high 8-bit <WORD_ADDR>
// after sending the slave address.
bit SMB_SENDWORDADDR1; // When set, this flag causes the ISR
// to send the low 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
#endif
void EEPROM_ByteWrite(unsigned char addr, unsigned char dat); /*A T24C08一位地址修改成char原int型*/
unsigned char EEPROM_ByteRead(unsigned char addr); /*A T24C08一位地址修改成char原int型*/
void Port_IO_Init(void);
void Oscillator_Init(void);
void UART_Init(void);
void UART_Isr(void);
void I2C_Init(void);
void Timer3_Init(void);
void Timer3_ISR (void);
void SMBus_ISR (void);。

相关文档
最新文档