📄 smb.c
字号:
//-----------------------------------------------------------------------------
#include <c8051f020.h> // SFR declarations
#include <display.h>
#include <struck.h>
//------------------------------------------------------------------------------------
// Global CONSTANTS
//------------------------------------------------------------------------------------
#define SMB_BUS_ERROR 0x00 // (all modes) BUS ERROR
#define SMB_START 0x08 // (MT & MR) START transmitted
#define SMB_RP_START 0x10 // (MT & MR) repeated START
#define SMB_MTADDACK 0x18 // (MT) Slave address + W transmitted;
// ACK received
#define SMB_MTADDNACK 0x20 // (MT) Slave address + W transmitted;
// NACK received
#define SMB_MTDBACK 0x28 // (MT) data byte transmitted; ACK rec'vd
#define SMB_MTDBNACK 0x30 // (MT) data byte transmitted; NACK rec'vd
#define SMB_MTARBLOST 0x38 // (MT) arbitration lost
#define SMB_MRADDACK 0x40 // (MR) Slave address + R transmitted;
// ACK received
#define SMB_MRADDNACK 0x48 // (MR) Slave address + R transmitted;
// NACK received
#define SMB_MRDBACK 0x50 // (MR) data byte rec'vd; ACK transmitted
#define SMB_MRDBNACK 0x58 // (MR) data byte rec'vd; NACK transmitted
#define SMB_SROADACK 0x60 // (SR) SMB's own slave address + W rec'vd;
// ACK transmitted
#define SMB_SROARBLOST 0x68 // (SR) SMB's own slave address + W rec'vd;
// arbitration lost
#define SMB_SRGADACK 0x70 // (SR) general call address rec'vd;
// ACK transmitted
#define SMB_SRGARBLOST 0x78 // (SR) arbitration lost when transmitting
// slave addr + R/W as master; general
// call address rec'vd; ACK transmitted
#define SMB_SRODBACK 0x80 // (SR) data byte received under own slave
// address; ACK returned
#define SMB_SRODBNACK 0x88 // (SR) data byte received under own slave
// address; NACK returned
#define SMB_SRGDBACK 0x90 // (SR) data byte received under general
// call address; ACK returned
#define SMB_SRGDBNACK 0x98 // (SR) data byte received under general
// call address; NACK returned
#define SMB_SRSTOP 0xa0 // (SR) STOP or repeated START received
// while addressed as a slave
#define SMB_STOADACK 0xa8 // (ST) SMB's own slave address + R rec'vd;
// ACK transmitted
#define SMB_STOARBLOST 0xb0 // (ST) arbitration lost in transmitting
// slave address + R/W as master; own
// slave address rec'vd; ACK transmitted
#define SMB_STDBACK 0xb8 // (ST) data byte transmitted; ACK rec'ed
#define SMB_STDBNACK 0xc0 // (ST) data byte transmitted; NACK rec'ed
#define SMB_STDBLAST 0xc8 // (ST) last data byte transmitted (AA=0);
// ACK received
#define SMB_SCLHIGHTO 0xd0 // (ST & SR) SCL clock high timer per
// SMB0CR timed out (FTE=1)
#define SMB_IDLE 0xf8 // (all modes) Idle
//-----------------------------------------------------------------------------------
//Global VARIABLES
//-----------------------------------------------------------------------------------
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.
//------------------------------------------------------------------------------------
// Function PROTOTYPES
//------------------------------------------------------------------------------------
void SYSCLK_Init (void);
void SMBUS_ISR (void);
char SLA_READ(char chip_select, char out_op);
void SLA_SEND(char chip_select, char out_op, char out_data);
void OP_CODE_HANDLER(void);
//------------------------------------------------------------------------------------
// MAIN Routine
//------------------------------------------------------------------------------------
char xdata * SmbSendDptr, * SmbReceiveDptr, *SmbReceiveBuf;
char xdata SmbSendBuf[100];
uchar DataLen;
void SMB_Write(unsigned char data_len)
{
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
SmbSendDptr = SmbSendBuf;
DataLen = data_len;
STO=0;
STA=1;
}
void SMB_Read(unsigned char data_len)
{
while(SM_BUSY);
SM_BUSY=1;
SMB0CN=0x44;
SmbReceiveDptr=SmbReceiveBuf;
SmbSendDptr=SmbSendBuf;
DataLen=data_len;
STO=0;
STA=1;
}
//------------------------------------------------------------------------------------
// SMBus Interrupt Service Routine
//------------------------------------------------------------------------------------
void SMBUS_ISR (void) interrupt 7
{
switch (SMB0STA)
{
case 0x08:
if(DataLen)
{
SMB0DAT =* SmbSendDptr++;
DataLen--;
}
else
{
STO=1;
SM_BUSY=0;
}
STA=0;
break;
case 0x18:
if(DataLen)
{
SMB0DAT=* SmbSendDptr++;
DataLen--;
}
else
{
STO=1;
SM_BUSY=0;
}
break;
case 0x20:
SmbSendDptr=SmbSendBuf;
STO = 1;
STA = 1;
break;
case 0x28:
if(DataLen)
{
SMB0DAT=* SmbSendDptr++;
DataLen--;
}
else
{
STO=1;
SM_BUSY=0;
}
break;
case 0x30:
SmbSendDptr=SmbSendBuf;
STO=1;
STA=1;
break;
case 0x38:
SmbSendDptr=SmbSendBuf;
STO=1;
STA=1;
break;
case 0x40:
break;
case 0x48:
SmbReceiveDptr=SmbReceiveBuf;
STO = 0;
STA = 1;
break;
case 0x50:
if(DataLen>0x02)
{
* SmbReceiveDptr++=SMB0DAT;
DataLen--;
}
else if(DataLen==0x02)
{
* SmbReceiveDptr++=SMB0DAT;
DataLen--;
AA=0;
}
else if(DataLen<0x02)
{
* SmbReceiveDptr++=SMB0DAT;
STO=1;
SM_BUSY=0;
}
break;
case 0x58:
* SmbReceiveDptr++=SMB0DAT;
DataLen--;
STO=1;
SM_BUSY=0; // Free SMBus
break;
default:
STO=1; // Reset communication.
SM_BUSY=0;
break;
}
SI=0; // clear interrupt flag
}
sbit WP = P3^1;
extern Delay(uint tt);
void EepromWrite(uint addr, uchar *p, uchar len)
{
unsigned char i;
WP = 0;
SmbSendBuf[0]=0xa0;
SmbSendBuf[1]=addr>>8;
SmbSendBuf[2]=addr & 0xff;
for(i=0;i<len;i++)
SmbSendBuf[i+3] = *p++;
SMB_Write(len+3);
while(SM_BUSY);
Delay(10);
WP = 0;
}
void EepromRead(uint addr, uchar *p, uchar len)
{
SmbSendBuf[0]=0xa0;
SmbSendBuf[1]=addr>>8;
SmbSendBuf[2]=addr & 0xff;
SMB_Write(3);
while(SM_BUSY);
SmbSendBuf[0]=0xa1;
SmbReceiveBuf = p;
SMB_Read(len+1);
while(SM_BUSY);
}
/*
void erase(void)
{
int i;
for(i=0;i<300;i++)
{
//EepromWrite(Drecord+(64*i),(char *)&REC,sizeof(REC));
}
/////////// EepromWrite(Dparameter,(char *)&CurtPara,sizeof(CurtPara));
for(i=0;i<200;i++)
{
EepromWrite ( Dcompare+64*i,
(char *)CurtPara.cmpOhm,
sizeof(CurtPara.cmpOhm)
);
EepromWrite ( Dcompare+64*i+sizeof(CurtPara.cmpOhm),
(char *)CurtPara.cmpVolt,
sizeof(CurtPara.cmpVolt)
);
}
}
*/
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -