SMBUS的SLAVE地址

wankong 2007-02-07 08:53:13
最近需要写个读写SMBUS设备的寄存器的程序,好象挂在SMBUS上的各类设备都有自己固定的SLAVE ADDRESS,所以想问下是否有相关的资料记录了各类设备预先分配好的地址,如果有相关资料的话,是否可以提供下哪里下载?比如SPD的SLAVE ADDRESS为A0,A2,A4等;好象BATTERY为0AH。类似这样的资料有吗?
...全文
3382 8 打赏 收藏 转发到动态 举报
写回复
用AI写文章
8 条回复
切换为时间正序
请发表友善的回复…
发表回复
zyzhang365 2009-01-20
  • 打赏
  • 举报
回复
其实SMBUS在某种程度上和I2C类似。首先要弄清楚slave地址是丛设备的slave地址,遵从SMBUS协议的丛设备地址是可配置的,丛设备自己决定是否响应某个地址寻址,这点与标准的I2C不同。

对于器件来讲,除开使用MCU作为从设备外,slave地址一般是硬件化了的,所以说从slave设备的手册上就能找到这个地址。

需要注意的一点是,有的芯片在描述slave地址字节时是不包括最后读写位的。
id0084 2009-01-20
  • 打赏
  • 举报
回复
看spec.都是厂家自定义的!
zltension1 2008-10-16
  • 打赏
  • 举报
回复
这个要看主板厂商的hardware spec了,例如DIMM、温度监控器、时钟发生器等SMBUS device的address会列出来。
海天 2008-01-22
  • 打赏
  • 举报
回复
上面的参数是怎么传的??
langzijo 2007-11-26
  • 打赏
  • 举报
回复
#include <windows.h>
#include <stdio.h>
#include "winio.h"

#pragma comment(lib,"WinIo.lib")

#define IO_SC 0x0cf8 //config space control address
#define IO_DA 0x0cfc //config space data address
#define BASEADDRESS 0x80000000 //PCI-SMBus init address
#define DIMM0 0x0a0 //memory device ID
#define DIMM1 0x0a2
#define DIMM2 0x0a4

/*
1s=1000(ms)
1s=1,000,000(μs)
1s=1,000,000,000(ns)
1s=1,000,000,000,000(ps)
*/
//高精度延时
void DelayUs(__int64 Us)
{
LARGE_INTEGER CurrTicks,TicksCount;
QueryPerformanceFrequency(&TicksCount);
QueryPerformanceCounter(&CurrTicks);

TicksCount.QuadPart=TicksCount.QuadPart*Us/1000000i64;
TicksCount.QuadPart+=CurrTicks.QuadPart;

while(CurrTicks.QuadPart<TicksCount.QuadPart)
QueryPerformanceCounter(&CurrTicks);
}

bool WaitReady(DWORD base)
{
DWORD STATUS;
do{
GetPortVal(base, &STATUS,1);
}while((STATUS&0x01)!=0);
return TRUE;
}

void ChkSMbus()
{
DWORD base=BASEADDRESS+(0<<16)+(0x1f<<11)+(0<<8);
DWORD RetVal=0;
SetPortVal(IO_SC,base+0x0f2,4);
GetPortVal(IO_DA,&RetVal,1);
printf("LPC(%08X) FUN_DIS: %02X\n",base,RetVal);
}

BYTE ReadSPD(DWORD base,BYTE offset,BYTE DEVID)
{
DWORD RetVal=0;
SetPortVal(base,0x0fe,1);
//output Base+04, (DeviceID+1)
SetPortVal(base+0x04,DEVID+1,1);
//out Base+03, offset
SetPortVal(base+0x03,offset,1);
//out Base+02, 48H
SetPortVal(base+0x02,0x48,1);
//wait 200ms
DelayUs(200*1000);
//wait smbus ready
if(WaitReady(base))
{//input base+05
GetPortVal(base+0x05,&RetVal,1);
}
return (BYTE)RetVal;
}

//byte0: the size of SPD used
bool SPD_BYTE0(DWORD base,BYTE DEVID)
{
DWORD RetVal=0;
RetVal=ReadSPD(base,0,DEVID);
if(RetVal>=128)
{
printf("The size of SPD used: %dbytes\n",RetVal);
return TRUE;
}
else
return FALSE;
}

//byte1: total size of SPD
void SPD_BYTE1(DWORD base,BYTE DEVID)
{
DWORD RetVal=0;
RetVal=ReadSPD(base,1,DEVID);
printf("Total size of SPD: %dbytes\n",(1<<RetVal));
}

//byte2: Memory Type
void SPD_BYTE2(DWORD base,BYTE DEVID)
{
DWORD RetVal=0;
RetVal=ReadSPD(base,2,DEVID);
//printf("TYPE Value: %d\n",RetVal);
switch(RetVal)
{
case 0x04:
printf("Memory Type is: SDRAM\n");
break;
case 0x07:
printf("Memory Type is: SDRAM DDR\n");
break;
default:
printf("Memory Type is: Other\n");
break;
}
}

//byte9: Cycle time
void SPD_BYTE9(DWORD base,BYTE DEVID)
{
DWORD RetVal=0;
float CylTime=0;
int temp;
RetVal=ReadSPD(base,9,DEVID);
//printf("Cycle time value: %dbytes\n",RetVal);
temp=(int)RetVal&0x0F;
if(temp<=9)
CylTime=(RetVal&0x0F)/10;
else
printf("Read Cycle time error!\n");

temp=(int)((RetVal&0x0F0)/16);
if(temp!=0)
CylTime=CylTime+temp;
else
printf("Read Cycle time error!\n");

//printf("Cyle Time is: %fns\n",CylTime);
temp=(int)2000/CylTime;
printf("RAM FSB=%dMHz\n",temp);
}

//byte31: Memory size
int SPD_BYTE1F(DWORD base,BYTE DEVID)
{
DWORD RetVal=0;
int RAMSZ=0;
RetVal=ReadSPD(base,0x1f,DEVID);
//printf("TYPE Value: %d\n",RetVal);
switch(RetVal)
{
case 0x04:RAMSZ=16;break;
case 0x08:RAMSZ=32;break;
case 0x10:RAMSZ=64;break;
case 0x20:RAMSZ=128;break;
case 0x40:RAMSZ=256;break;
case 0x80:RAMSZ=512;break;
case 0x01:RAMSZ=1024;break;
case 0x02:RAMSZ=2048;break;
default:RAMSZ=0;
}
return RAMSZ;
}

int main(int argc, char* argv[])
{
DWORD dataddr;
DWORD baseddr;
DWORD dwPortVal;
bool bResult;
int busID=0;
int deviceID=0;
int funID=0;
BYTE offset=0;

busID=strtoul(argv[1],NULL,16);
deviceID=strtoul(argv[2],NULL,16);
funID=strtoul(argv[3],NULL,16);
//ChkSMbus();
// get SMbus base address
dataddr=BASEADDRESS+(busID<<16)+(deviceID<<11)+(funID<<8);

// Call InitializeWinIo to initialize the WinIo library.
bResult = InitializeWinIo();

if(bResult)
{
//Get SMBus base address
SetPortVal(IO_SC,dataddr+0x20,4);
GetPortVal(IO_DA,&dwPortVal,4);
baseddr=dwPortVal&0x0FFFFFFF0;
printf("SMBus base address=%08X\n",baseddr);
if(WaitReady(baseddr))
{//read SPD info
//read Slot0 memory info
if(SPD_BYTE0(baseddr,DIMM0)==TRUE)
{
//SPD_BYTE1(baseddr,DIMM0);
SPD_BYTE2(baseddr,DIMM0);
SPD_BYTE9(baseddr,DIMM0);
printf("RAMSZ=%dMB\n",SPD_BYTE1F(baseddr,DIMM0));
}
else
{
printf("DIMM0: Read error!\n");
}

//read Slot1 memory info
if(SPD_BYTE0(baseddr,DIMM1)==TRUE)
{
//SPD_BYTE1(baseddr,DIMM0);
SPD_BYTE2(baseddr,DIMM1);
SPD_BYTE9(baseddr,DIMM1);
printf("RAMSZ=%dMB\n",SPD_BYTE1F(baseddr,DIMM1));
}
else
{
printf("DIMM1: Read error!\n");
}
}
}
else
{
printf("Error during initialization of WinIo.\n");
exit(1);
}
// When you're done using WinIo, call ShutdownWinIo
ShutdownWinIo();
return 0;
}

不支持ICH7以上chip
wankong 2007-02-08
  • 打赏
  • 举报
回复
我参考了SMBUS2.0的SPEC,里面只有一些保留的SLAVE ADDRESS,还说其他的地址由SMBUS WORKING GROUP来进行分配,通过地址来标志不同类别的设备,可是我不知道去哪里能找到这些标记设备类别的地址,所以哪位有这样的资料,麻烦给我份,或者下载地址。
看到有说SMBUS2.0的设备可以numeric,那是什么意思,如何做啊?
lbing7 2007-02-07
  • 打赏
  • 举报
回复
可以去搜一下SMBUS的标准协议文档

27,374

社区成员

发帖
与我相关
我的任务
社区描述
硬件/嵌入开发 单片机/工控
社区管理员
  • 单片机/工控社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧