微波EDA网,见证研发工程师的成长!
首页 > 研发问答 > 嵌入式设计讨论 > MCU和单片机设计讨论 > 有哪位大神用过MAX31785/PMBus命令,求助

有哪位大神用过MAX31785/PMBus命令,求助

时间:10-02 整理:3721RD 点击:

我对PMBus命令 中 PAGE  的概念不是很理解,写的通讯格式应该有问题,实测读写数据没有得到预期的结果。求大神相助,附代码:

  1. #define MAX31785_ADDRESS     0XA4     
  2. #define MAX31785_RST         PORTD.6

  3. ////M16
  4. //#define I2C_SCL               PORTD.2
  5. //#define I2C_SDA_O             PORTD.3
  6. //#define I2C_SDA_I             PIND.3
  7. //#define I2C_SDA_SET_IN()      DDRD.3 = 0
  8. //#define I2C_SDA_SET_OUT()     DDRD.3 = 1
  9. //#define I2C_SCL_SET_OUT()     DDRD.2 = 1

  10. //M128
  11. #define I2C_SCL               PORTD.0
  12. #define I2C_SDA_O             PORTD.1
  13. #define I2C_SDA_I             PIND.1
  14. #define I2C_SDA_SET_IN()      DDRD.1 = 0
  15. #define I2C_SDA_SET_OUT()     DDRD.1 = 1
  16. #define I2C_SCL_SET_OUT()     DDRD.0 = 1

  17. #define I2CDLYTIME            5   

  18. void I2C_INIT(void)
  19. {
  20.    I2C_SDA_SET_OUT();
  21.    I2C_SCL_SET_OUT();
  22.    I2C_SCL = 1;
  23.    I2C_SDA_O = 1;
  24. }

  25. void CALL_I2C_DLY(unsigned char i)
  26. {
  27.   while(i--);
  28. }

  29. void I2C_START(void)
  30. {
  31.   I2C_SDA_SET_OUT();
  32.   I2C_SDA_O = 1;
  33.   CALL_I2C_DLY(I2CDLYTIME);
  34.   I2C_SCL = 1;
  35.   CALL_I2C_DLY(I2CDLYTIME);
  36.   I2C_SDA_O = 0;
  37.   CALL_I2C_DLY(I2CDLYTIME);
  38.   I2C_SCL = 0;
  39. }

  40. void I2C_STOP(void)
  41. {
  42.   I2C_SDA_SET_OUT();
  43.   I2C_SDA_O = 0;
  44.   CALL_I2C_DLY(I2CDLYTIME);
  45.   I2C_SCL = 1;
  46.   CALL_I2C_DLY(I2CDLYTIME);
  47.   I2C_SDA_O = 1;
  48.   CALL_I2C_DLY(I2CDLYTIME);
  49. }

  50. char I2C_READ_ACK(void)
  51. {
  52.   char i = 0;
  53.   I2C_SDA_SET_IN();
  54.   I2C_SCL = 1;
  55.   CALL_I2C_DLY(I2CDLYTIME);
  56.   if(!I2C_SDA_I){ i++; }
  57.   CALL_I2C_DLY(I2CDLYTIME);
  58.   I2C_SCL = 0;
  59.   CALL_I2C_DLY(I2CDLYTIME/2);
  60.   return i;
  61. }

  62. void I2C_SEND_ACK(char i)
  63. {
  64.   I2C_SDA_SET_OUT();
  65.   if(i) { I2C_SDA_O = 0;}
  66.   else  { I2C_SDA_O = 1;}
  67.   CALL_I2C_DLY(I2CDLYTIME);
  68.   I2C_SCL = 1;
  69.   CALL_I2C_DLY(I2CDLYTIME);
  70.   I2C_SCL = 0;
  71.   CALL_I2C_DLY(I2CDLYTIME/2);
  72. }

  73. byte Send_I2C_Data(char Data)
  74. {
  75.   char j;

  76.   I2C_SDA_SET_OUT();
  77.   I2C_SCL    = 0;
  78.   CALL_I2C_DLY(I2CDLYTIME);
  79.   for(j=0;j<8;j++)
  80.   {
  81.         if(Data & 0x80) I2C_SDA_O = 1;
  82.         else         I2C_SDA_O = 0;
  83.          CALL_I2C_DLY(I2CDLYTIME);
  84.          I2C_SCL    = 1;
  85.     CALL_I2C_DLY(I2CDLYTIME);
  86.          I2C_SCL    = 0;
  87.     CALL_I2C_DLY(I2CDLYTIME);
  88.          Data = (Data<<1);
  89.   }
  90.   return(I2C_READ_ACK());
  91. }

  92. char Read_I2C_Data(char ACK)
  93. {
  94.   char Data = 0;
  95.   char j;

  96.   I2C_SDA_SET_IN();
  97.   for(j=0;j<8;j++)
  98.   {
  99.     Data = Data << 1;
  100.     I2C_SCL    = 1;
  101.     CALL_I2C_DLY(I2CDLYTIME);
  102.         if(I2C_SDA_I) Data |= 1;
  103.          CALL_I2C_DLY(I2CDLYTIME);
  104.          I2C_SCL    = 0;
  105.     CALL_I2C_DLY(I2CDLYTIME);
  106.   }
  107.   I2C_SEND_ACK(ACK);
  108.   return Data;
  109. }

  110. /******************** I2C Write/Read Data ***********************************
  111.   buff[0]=0X90;    //hard Address
  112.   buff[1]=0X02;    //cmd len
  113.   buff[2]=0X10;    //Read len
  114.   buff[3]=0X06;    //read Hi address
  115.   buff[4]=0X81;    //read lo address
  116.   ..
  117. *****************************************************************************/
  118. byte I2C_Device_RW_Data(byte *P)
  119. {
  120.   byte i;
  121.   byte result = 0;
  122.   byte RDLen = P[2];

  123.   I2C_START();
  124.   if(!Send_I2C_Data(P[0]))
  125.   {
  126.      result = I2C_ADDR_ERR;
  127.      _put_sf0("\r\nI2C E1\r\n");
  128.   }
  129.   else
  130.   {
  131.      if(P[1]>0) //如果写命令长度大于0
  132.      {
  133.          for(i=1;i<=P[1];i++)
  134.          {
  135.            if(!Send_I2C_Data(P[i+2]))
  136.              {
  137.                 result = I2C_W_CMD_ERR;
  138.                 _put_sf0("\r\nI2C E2\r\n");
  139.                 break;
  140.              }
  141.          }
  142.      }

  143.      if( (result==0) && (RDLen>0) ) //如果没有出错及需要读数据则
  144.      {
  145.         if(P[1])
  146.         {
  147.             I2C_START();
  148.             if(!Send_I2C_Data(P[0] | 0x01))
  149.             {
  150.                result = I2C_ADDR_ERR;
  151.                _put_sf0("\r\nI2C E3\r\n");
  152.             }
  153.             else
  154.             {
  155.                for(i=1;i<RDLen;i++)  //所读数据保存于P[0]开始的寄存器中
  156.                {
  157.                   P[i-1] = Read_I2C_Data(1);
  158.                }
  159.                P[i-1] = Read_I2C_Data(0); //
  160.             }
  161.         }  
  162.      }
  163.   }
  164.   I2C_STOP();
  165.   return result;   
  166. }
  167.    
  168. void Call_MAX31785_Init(void)
  169. {
  170.   char i;
  171.   
  172.   MAX31785_RST = 0;
  173.   delay_ms(5);
  174.   MAX31785_RST = 1;
  175.   delay_ms(10);
  176.    
  177.   //配置PAGE (00h)
  178.   DataBuffer[0] = MAX31785_ADDRESS;
  179.   DataBuffer[1] = 0X02; //wt Len
  180.   DataBuffer[2] = 0X00; //RD Len
  181.   DataBuffer[3] = 0X00; //PAGE
  182.   DataBuffer[4] = 0xff; //
  183.   i = I2C_Device_RW_Data(DataBuffer);
  184.   if(i != 0)
  185.   {
  186.     if(bitDBGFlag)
  187.     {      
  188.         _put_sf0("\r\nMAX31785_Init E1\r\n");
  189.     }     
  190.   }
  191.   
  192.   //配置FAN_CONFIG_1_2(3Ah)
  193.   DataBuffer[0] = MAX31785_ADDRESS;
  194.   DataBuffer[1] = 0X02; //wt Len
  195.   DataBuffer[2] = 0X00; //RD Len
  196.   DataBuffer[3] = 0X3A; //FAN_CONFIG_1_2  
  197.   DataBuffer[4] = 0x90; //Fan enabled,PWM                                                                                                
  198.   i = I2C_Device_RW_Data(DataBuffer);
  199.   if(i != 0)
  200.   {
  201.     if(bitDBGFlag)
  202.     {      
  203.         _put_sf0("\r\nMAX31785_Init E2\r\n");
  204.     }     
  205.   }

  206.   //配置MFR_FAN_CONFIG (F1h)
  207.   DataBuffer[0] = MAX31785_ADDRESS;
  208.   DataBuffer[1] = 0X03; //wt Len
  209.   DataBuffer[2] = 0X00; //RD Len
  210.   DataBuffer[3] = 0XF1; //MFR_FAN_CONFIG
  211.   DataBuffer[4] = 0xC0; //low
  212.   DataBuffer[5] = 0x23; //high 50Hz,
  213.   i = I2C_Device_RW_Data(DataBuffer);
  214.   if(i != 0)
  215.   {        
  216.     if(bitDBGFlag)
  217.     {         
  218.        _put_sf0("\r\nMAX31785_Init E3\r\n");
  219.     }      
  220.   }   
  221. }      

  222. U16 MAX31785_RPM_Buffer[4];

  223. void Call_MAX31785_RPM_Control(byte SP)
  224. {
  225.   char i;  
  226.   
  227.   //配置PAGE (00h)
  228.   DataBuffer[0] = MAX31785_ADDRESS;
  229.   DataBuffer[1] = 0X02; //wt Len
  230.   DataBuffer[2] = 0X00; //RD Len
  231.   DataBuffer[3] = 0X00; //PAGE
  232.   DataBuffer[4] = SP; //SP: 0~5
  233.   i = I2C_Device_RW_Data(DataBuffer);
  234.   if(i != 0)
  235.   {
  236.     if(bitDBGFlag)
  237.     {      
  238.         _put_sf0("\r\nMAX31785_RPM_Control E1\r\n");
  239.     }     
  240.   }
  241.   
  242.   //配置FAN_COMMAND_1 (3Bh)
  243.   DataBuffer[0] = MAX31785_ADDRESS;
  244.   DataBuffer[1] = 0X03; //wt Len
  245.   DataBuffer[2] = 0X00; //RD Len
  246.   DataBuffer[3] = 0X3B; //FAN_COMMAND_1 (3Bh)
  247.   DataBuffer[4] = (unsigned char)(MAX31785_RPM_Buffer[SP]%256);   //low RPM
  248.   DataBuffer[5] = (unsigned char)(MAX31785_RPM_Buffer[SP]/256);   //high RPM
  249.   i = I2C_Device_RW_Data(DataBuffer);
  250.   if(i!= 0)
  251.   {      
  252.     if(bitDBGFlag)
  253.     {            
  254.        _put_sf0("\r\nMAX31785_RPM_Control E2\r\n");
  255.     }
  256.   }  
  257. }

  258. U16 iFanRPM[4]={0};

  259. void Call_MAX31785_SPEED_Read(byte SP)
  260. {
  261.   U16 Tmp;
  262.   char i;
  263.    
  264.   //配置PAGE (00h)
  265.   DataBuffer[0] = MAX31785_ADDRESS;
  266.   DataBuffer[1] = 0X02; //wt Len
  267.   DataBuffer[2] = 0X00; //RD Len
  268.   DataBuffer[3] = 0X00; //PAGE
  269.   DataBuffer[4] = SP; //SP: 0~5
  270.   i = I2C_Device_RW_Data(DataBuffer);
  271.   if(i != 0)
  272.   {
  273.     if(bitDBGFlag)
  274.     {      
  275.         _put_sf0("\r\nMAX31785_SPEED_Read E1\r\n");
  276.     }
  277.   }
  278.   
  279.   //配置READ_FAN_SPEED_1 (90h)
  280.   DataBuffer[0] = MAX31785_ADDRESS;
  281.   DataBuffer[1] = 0X01; //wt Len
  282.   DataBuffer[2] = 0X02; //RD Len
  283.   DataBuffer[3] = 0X90; //READ_FAN_SPEED_1
  284.   i = I2C_Device_RW_Data(DataBuffer);
  285.   if(i!= 0)
  286.   {         
  287.     if(bitDBGFlag)
  288.     {         
  289.         _put_sf0("\r\nMAX31785_SPEED_Read E2\r\n");
  290.     }
  291.   }
  292.    
  293.   Tmp = DataBuffer[0];
  294.   Tmp |= (DataBuffer[1]<<8);      
  295.   
  296.   iFanRPM[SP] = Tmp;         
  297. }

复制代码




Copyright © 2017-2020 微波EDA网 版权所有

网站地图

Top