有哪位大神用过MAX31785/PMBus命令,求助
时间:10-02
整理:3721RD
点击:
我对PMBus命令 中 PAGE 的概念不是很理解,写的通讯格式应该有问题,实测读写数据没有得到预期的结果。求大神相助,附代码:
- #define MAX31785_ADDRESS 0XA4
- #define MAX31785_RST PORTD.6
- ////M16
- //#define I2C_SCL PORTD.2
- //#define I2C_SDA_O PORTD.3
- //#define I2C_SDA_I PIND.3
- //#define I2C_SDA_SET_IN() DDRD.3 = 0
- //#define I2C_SDA_SET_OUT() DDRD.3 = 1
- //#define I2C_SCL_SET_OUT() DDRD.2 = 1
- //M128
- #define I2C_SCL PORTD.0
- #define I2C_SDA_O PORTD.1
- #define I2C_SDA_I PIND.1
- #define I2C_SDA_SET_IN() DDRD.1 = 0
- #define I2C_SDA_SET_OUT() DDRD.1 = 1
- #define I2C_SCL_SET_OUT() DDRD.0 = 1
- #define I2CDLYTIME 5
- void I2C_INIT(void)
- {
- I2C_SDA_SET_OUT();
- I2C_SCL_SET_OUT();
- I2C_SCL = 1;
- I2C_SDA_O = 1;
- }
- void CALL_I2C_DLY(unsigned char i)
- {
- while(i--);
- }
- void I2C_START(void)
- {
- I2C_SDA_SET_OUT();
- I2C_SDA_O = 1;
- CALL_I2C_DLY(I2CDLYTIME);
- I2C_SCL = 1;
- CALL_I2C_DLY(I2CDLYTIME);
- I2C_SDA_O = 0;
- CALL_I2C_DLY(I2CDLYTIME);
- I2C_SCL = 0;
- }
- void I2C_STOP(void)
- {
- I2C_SDA_SET_OUT();
- I2C_SDA_O = 0;
- CALL_I2C_DLY(I2CDLYTIME);
- I2C_SCL = 1;
- CALL_I2C_DLY(I2CDLYTIME);
- I2C_SDA_O = 1;
- CALL_I2C_DLY(I2CDLYTIME);
- }
- char I2C_READ_ACK(void)
- {
- char i = 0;
- I2C_SDA_SET_IN();
- I2C_SCL = 1;
- CALL_I2C_DLY(I2CDLYTIME);
- if(!I2C_SDA_I){ i++; }
- CALL_I2C_DLY(I2CDLYTIME);
- I2C_SCL = 0;
- CALL_I2C_DLY(I2CDLYTIME/2);
- return i;
- }
- void I2C_SEND_ACK(char i)
- {
- I2C_SDA_SET_OUT();
- if(i) { I2C_SDA_O = 0;}
- else { I2C_SDA_O = 1;}
- CALL_I2C_DLY(I2CDLYTIME);
- I2C_SCL = 1;
- CALL_I2C_DLY(I2CDLYTIME);
- I2C_SCL = 0;
- CALL_I2C_DLY(I2CDLYTIME/2);
- }
- byte Send_I2C_Data(char Data)
- {
- char j;
- I2C_SDA_SET_OUT();
- I2C_SCL = 0;
- CALL_I2C_DLY(I2CDLYTIME);
- for(j=0;j<8;j++)
- {
- if(Data & 0x80) I2C_SDA_O = 1;
- else I2C_SDA_O = 0;
- CALL_I2C_DLY(I2CDLYTIME);
- I2C_SCL = 1;
- CALL_I2C_DLY(I2CDLYTIME);
- I2C_SCL = 0;
- CALL_I2C_DLY(I2CDLYTIME);
- Data = (Data<<1);
- }
- return(I2C_READ_ACK());
- }
- char Read_I2C_Data(char ACK)
- {
- char Data = 0;
- char j;
- I2C_SDA_SET_IN();
- for(j=0;j<8;j++)
- {
- Data = Data << 1;
- I2C_SCL = 1;
- CALL_I2C_DLY(I2CDLYTIME);
- if(I2C_SDA_I) Data |= 1;
- CALL_I2C_DLY(I2CDLYTIME);
- I2C_SCL = 0;
- CALL_I2C_DLY(I2CDLYTIME);
- }
- I2C_SEND_ACK(ACK);
- return Data;
- }
- /******************** I2C Write/Read Data ***********************************
- buff[0]=0X90; //hard Address
- buff[1]=0X02; //cmd len
- buff[2]=0X10; //Read len
- buff[3]=0X06; //read Hi address
- buff[4]=0X81; //read lo address
- ..
- *****************************************************************************/
- byte I2C_Device_RW_Data(byte *P)
- {
- byte i;
- byte result = 0;
- byte RDLen = P[2];
- I2C_START();
- if(!Send_I2C_Data(P[0]))
- {
- result = I2C_ADDR_ERR;
- _put_sf0("\r\nI2C E1\r\n");
- }
- else
- {
- if(P[1]>0) //如果写命令长度大于0
- {
- for(i=1;i<=P[1];i++)
- {
- if(!Send_I2C_Data(P[i+2]))
- {
- result = I2C_W_CMD_ERR;
- _put_sf0("\r\nI2C E2\r\n");
- break;
- }
- }
- }
- if( (result==0) && (RDLen>0) ) //如果没有出错及需要读数据则
- {
- if(P[1])
- {
- I2C_START();
- if(!Send_I2C_Data(P[0] | 0x01))
- {
- result = I2C_ADDR_ERR;
- _put_sf0("\r\nI2C E3\r\n");
- }
- else
- {
- for(i=1;i<RDLen;i++) //所读数据保存于P[0]开始的寄存器中
- {
- P[i-1] = Read_I2C_Data(1);
- }
- P[i-1] = Read_I2C_Data(0); //
- }
- }
- }
- }
- I2C_STOP();
- return result;
- }
-
- void Call_MAX31785_Init(void)
- {
- char i;
-
- MAX31785_RST = 0;
- delay_ms(5);
- MAX31785_RST = 1;
- delay_ms(10);
-
- //配置PAGE (00h)
- DataBuffer[0] = MAX31785_ADDRESS;
- DataBuffer[1] = 0X02; //wt Len
- DataBuffer[2] = 0X00; //RD Len
- DataBuffer[3] = 0X00; //PAGE
- DataBuffer[4] = 0xff; //
- i = I2C_Device_RW_Data(DataBuffer);
- if(i != 0)
- {
- if(bitDBGFlag)
- {
- _put_sf0("\r\nMAX31785_Init E1\r\n");
- }
- }
-
- //配置FAN_CONFIG_1_2(3Ah)
- DataBuffer[0] = MAX31785_ADDRESS;
- DataBuffer[1] = 0X02; //wt Len
- DataBuffer[2] = 0X00; //RD Len
- DataBuffer[3] = 0X3A; //FAN_CONFIG_1_2
- DataBuffer[4] = 0x90; //Fan enabled,PWM
- i = I2C_Device_RW_Data(DataBuffer);
- if(i != 0)
- {
- if(bitDBGFlag)
- {
- _put_sf0("\r\nMAX31785_Init E2\r\n");
- }
- }
- //配置MFR_FAN_CONFIG (F1h)
- DataBuffer[0] = MAX31785_ADDRESS;
- DataBuffer[1] = 0X03; //wt Len
- DataBuffer[2] = 0X00; //RD Len
- DataBuffer[3] = 0XF1; //MFR_FAN_CONFIG
- DataBuffer[4] = 0xC0; //low
- DataBuffer[5] = 0x23; //high 50Hz,
- i = I2C_Device_RW_Data(DataBuffer);
- if(i != 0)
- {
- if(bitDBGFlag)
- {
- _put_sf0("\r\nMAX31785_Init E3\r\n");
- }
- }
- }
- U16 MAX31785_RPM_Buffer[4];
- void Call_MAX31785_RPM_Control(byte SP)
- {
- char i;
-
- //配置PAGE (00h)
- DataBuffer[0] = MAX31785_ADDRESS;
- DataBuffer[1] = 0X02; //wt Len
- DataBuffer[2] = 0X00; //RD Len
- DataBuffer[3] = 0X00; //PAGE
- DataBuffer[4] = SP; //SP: 0~5
- i = I2C_Device_RW_Data(DataBuffer);
- if(i != 0)
- {
- if(bitDBGFlag)
- {
- _put_sf0("\r\nMAX31785_RPM_Control E1\r\n");
- }
- }
-
- //配置FAN_COMMAND_1 (3Bh)
- DataBuffer[0] = MAX31785_ADDRESS;
- DataBuffer[1] = 0X03; //wt Len
- DataBuffer[2] = 0X00; //RD Len
- DataBuffer[3] = 0X3B; //FAN_COMMAND_1 (3Bh)
- DataBuffer[4] = (unsigned char)(MAX31785_RPM_Buffer[SP]%256); //low RPM
- DataBuffer[5] = (unsigned char)(MAX31785_RPM_Buffer[SP]/256); //high RPM
- i = I2C_Device_RW_Data(DataBuffer);
- if(i!= 0)
- {
- if(bitDBGFlag)
- {
- _put_sf0("\r\nMAX31785_RPM_Control E2\r\n");
- }
- }
- }
- U16 iFanRPM[4]={0};
- void Call_MAX31785_SPEED_Read(byte SP)
- {
- U16 Tmp;
- char i;
-
- //配置PAGE (00h)
- DataBuffer[0] = MAX31785_ADDRESS;
- DataBuffer[1] = 0X02; //wt Len
- DataBuffer[2] = 0X00; //RD Len
- DataBuffer[3] = 0X00; //PAGE
- DataBuffer[4] = SP; //SP: 0~5
- i = I2C_Device_RW_Data(DataBuffer);
- if(i != 0)
- {
- if(bitDBGFlag)
- {
- _put_sf0("\r\nMAX31785_SPEED_Read E1\r\n");
- }
- }
-
- //配置READ_FAN_SPEED_1 (90h)
- DataBuffer[0] = MAX31785_ADDRESS;
- DataBuffer[1] = 0X01; //wt Len
- DataBuffer[2] = 0X02; //RD Len
- DataBuffer[3] = 0X90; //READ_FAN_SPEED_1
- i = I2C_Device_RW_Data(DataBuffer);
- if(i!= 0)
- {
- if(bitDBGFlag)
- {
- _put_sf0("\r\nMAX31785_SPEED_Read E2\r\n");
- }
- }
-
- Tmp = DataBuffer[0];
- Tmp |= (DataBuffer[1]<<8);
-
- iFanRPM[SP] = Tmp;
- }