⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 smb.c

📁 C8051F020 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 + -