访问SMBus设备

使用SMBus访问温度传感器,并控制smart Fan

首先聊聊SMBus的访问方法
硬件上:两条线SMBus Clock和Data信号
在这里插入图片描述
当clock信号为高时data信号才有效,data信号下降,意味着Start。data信号上升,意味着Stop。开始后会发送九位,包括八位数据,一个应答位,如下图,
在这里插入图片描述
从示波器上可以看到(蓝为clock,黄为data),可以看到发送的为01011100,第9为应答位为高,即NACK,设备无响应。最后为stop。
在这里插入图片描述
这样就可以通过示波器知道SMBus设备是否响应。
软件上:在SMBus基地址后续寄存器有状态、访问方式、命令、从地址、数据等寄存器,这些寄存器都可查看datasheet。访问方式即为:
1、清状态(清完后为0x40)
2、写从地址(从地址最后一位1为读,0为写)
3、写数据(读不用)
4、设置访问方式(字节、字、双字访问)
5、等待应答(ACK状态寄存器变0x42,NACK则为0x44)
6、读数据(写不用)
举个栗子:下面代码为SMBus访问内存SPD信息

#include <stdio.h>
#include <conio.h>
#include <dos.h>

/*register add*/
#define SMB_Base_Add 0xf000

/*read SPD by byte*/
#define HST_STS 0x00
#define HST_CNT 0x02
#define HST_CMD 0x03
#define XMIT_SLVA 0x04
#define HST_D0 0x05

void D_delay();
int SMB_ACK();
int Register_Configuration(int SPD_add);

void main()
{
   int data,k;
   printf("  ");
   for(k=0x0;k<=0xf;k++)
   {
       printf("  %02x",k);
   }
   printf("\n");
    for(k=0x0;k<=0xff;k++)
    {
       if(k%16==0)
       {
          printf("\n");
          printf("%02x",k);
        }
        data = Register_Configuration(k);/*read data*/
        printf("  %02x",data);
   }
   getch();
}
int Register_Configuration(int SPD_add)
{
   int state,data;
   outportb(SMB_Base_Add|HST_STS,0xFE);/*clear */
   outportb(SMB_Base_Add|XMIT_SLVA,0xA1);/*slave/SPD base address *///1 is read,0 is write/* last bit is w/r,must be 1 */
   outportb(SMB_Base_Add|HST_CMD,SPD_add);/*offset*/
   outportb(SMB_Base_Add|HST_CNT,0x48);/*byte read*/
   D_delay();	·

   state = SMB_ACK();
   if(state!=0)
    {
       return 0xff;
    }
    data = inportb(SMB_Base_Add|HST_D0);
    D_delay();
    return data;

}
void D_delay()
{
   int i;
   for(i=100;i>0;i--);
}
int SMB_ACK()                     /*check smbus ready*/
{
   int state_A,state_B,i,s=0;

   for(i=0;i<0x80;i++)               /*circle until ACK = 0*/
   {
      state_A = inportb(SMB_Base_Add|HST_STS);
      D_delay();
      outportb(SMB_Base_Add|HST_STS,state_A);
      D_delay();
      state_B = state_A;
      state_B = state_A&0x02;
      if(state_B!=0)          /*   INTR = 1 BIT1    */
     {
      goto ret;
     }
     state_B = state_A;
     state_B = state_B&0xbf;     /*  INUSE_STS = 0   BIT6   */
      if(state_B==0)
     {
      goto ret;
     }
     state_B = state_A;
     state_B = state_B&0x04;      /*  DEV_ERR = 1(Invalid Command/Time-out/Unclaimed Cycle)    BIT2    */
       if(state_B)
     {
     break;
     }
   }
   s = 1;
   ret:
   return s;

}

下面为温度传感器并能智能控制风扇的芯片EMC2103-1,该芯片slave address为0x5c
在这里插入图片描述
DP、DN接thermal,TRIP_SET引脚由硬件接多大电阻决定shutdown的温度,使用smbus访问
有四种方式控制(查看datasheet)
1、PWM直接控制风扇,不根据温度,EN_ALGO、LUT_LOCK写0,无需配置Look Up Table,直接写Fan Driver Setting
2、FSC:Fan Speed Control Mode, EN_ALGO写1、LUT_LOCK写0,
3、PWM Setting w/LUT Mode
首先配置LUT,八个温度设置和八个改温度下对应风扇PWM设置,然后LUT_LOCK写1,RPM/PWM写1。注:LUT_LOCK置1时无法改写LUT
在这里插入图片描述
代码如下,注:如果无法连续写,应该是状态没清掉

void Smbus_delay()
{
 int i,j;
 for(i=0;i<256;i++)
   for(j=0;j<256;j++)
   	IoWrite8(0x400+0x00,0xdf);
}
void Smbus_Write(UINT8 address,UINT8 value)
{
    IoWrite8(0x400+0x00,0xdf);
   IoWrite8(0x400+0x00,0xdf);
	IoWrite8(0x400+0x00,0xdf);
	IoWrite8(0x400+0x00,0xdf);
	IoWrite8(0x400+0x04,0x5c);
	IoWrite8(0x400+0x03,address);
	IoWrite8(0x400+0x05,value);
	IoWrite8(0x400+0x02,0x48);
   IoWrite8(0x400+0x00,0xdf);
   IoWrite8(0x400+0x00,0xdf);
   IoWrite8(0x400+0x00,0xdf);
   IoWrite8(0x400+0x00,0xdf);
}
void main()
{
 Smbus_Write(0x50,0x00);
   Smbus_delay();
    Smbus_Write(0x51,0x44);
    Smbus_delay();
    Smbus_Write(0x52,0x30);
   Smbus_delay();
   Smbus_Write(0x56,0x66);
    Smbus_delay();
    Smbus_Write(0x57,0x35);
   Smbus_delay();
   Smbus_Write(0x5b,0x88);
    Smbus_delay();
    Smbus_Write(0x5c,0x3e);
   Smbus_delay();
   Smbus_Write(0x60,0xaa);
    Smbus_delay();
    Smbus_Write(0x61,0x42);
   Smbus_delay();
   Smbus_Write(0x65,0xbb);
    Smbus_delay();
    Smbus_Write(0x66,0x48);
   Smbus_delay();
   Smbus_Write(0x6a,0xdd);
    Smbus_delay();
    Smbus_Write(0x6b,0x4e);
   Smbus_delay();
   Smbus_Write(0x6f,0xee);
    Smbus_delay();
    Smbus_Write(0x70,0x50);
   Smbus_delay();
   Smbus_Write(0x74,0xff);
    Smbus_delay();
    Smbus_Write(0x75,0x55);
   Smbus_delay();
 
    Smbus_Write(0x50,0x30);
   Smbus_delay();
}
  • 2
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 4
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值