
SMBus最初的目的是为智能电池,充电电池和与其他系统通信的微桐大伍控制器之间的通信链路而定义的。SMBus也被用来连接各种设备,包括电源相关设备,系统传感器,EEPROM通讯设备等等。 SMBus 最适用于笔记本电脑上,检测各元件状态并更新硬件设置引脚 (pull-high 或 pull-low)。例如,将不存在的 DIMM 时钟关闭,或检测电池低电压状态。 SMBus 的数据传输率只有 100Kbit/s;这允许单一主机与 CPU 和多个主从硬盘通讯并收发数据。SMBus 也可用于免跳线设计的主板上。
系统管理总线(SMBus)是一个两线接口。通过它,各设备之间以及设备与系统的其他部分之间可以互相通信。它基于I2C *** 作原理。SMBus为系统和电源管理相关的任务提供一条控制总线。一个系统利用SMBus可以和多个设备互传信息,而不需使用独立的控制线路。
系统管理总线(SMBus)标准涉及三类设备。从设备,接收或响应命令的设备。主设备,用来发布命令,产生时钟和终止发送的设备。主机,是一种专用仿谨的主设备,它提供与系统CPU的主接口。主机必须具有主-从局或机功能,并且必须支持SMBus通报协议。在一个系统里只允许有一个主机。
我来说两句吧 ,希望你能采纳,首先工控机系统中的通信协议是什么 这个问法不妥,因为这个跟你工控机的硬件支持有关, 但是你这么问 似乎也对,因为工控机 支持的其实也就那么几种,比如说PCI 总线 PC104 总线 ISA 总线,但是具体到你要控制的东西可能携带的不同的通信接口 比如UART SPI CAN LIN IIC SMbus 等等 这时候你需要一块总线适配卡并且有相应的驱动程序。具体到通信协议 可以是标准的 也就是别人定义好的 也可以是你自己定义的 这样可以很简洁 但是通用性不好,具仿燃运体的实现也就是你说的一段程序。当然一般情况下我们买的别人的卡 这些协议是做好的 在你安装驱动的时候就给你 装上了 但是你自己设计卡的时候 就需要 自己写通信备梁协议了 ,也就是那段程序 希望对你有用 如果说的好 记段扒得采纳哦~SMBus的中断源比较多,我们一般在中断服务函数里面去判断,然后做出相应的响应,你去看看PDF,就会比较清楚我前段时间调试了这种总线,与时钟芯片PCF8563通讯就是这个
下面给你看看我写的服务程序
由于SMBus的特殊性,它要个超时检测,所以我把超时检测的服务程序也一共给你看看,这个是我调试成功的
如果还有什么建议,希望指正
QQ 247519442
/*************用于时钟芯片 *** 作的函数集****************/
//void write_pcf8563(void)写蠢握渣时钟芯片
//void read_pcf8563(void)读时钟芯片
/*****************************************************/
void write_pcf8563(uchar ADDseg)
{ TR0=0
SPI0CN &=~0x01 //暂时关闭带悄SPI传送,防止产生不必要的干扰
SMBus_ReadControl=0//控制本次 *** 作是读(1)、还是写(0)寄存器
SMBus_Send_Seg_ADDR=1//是否要传送寄存器的地址(1为传送)
TARGET = pcf8563 //送子器件地址
Seg_ADDR = ADDseg //送要 *** 作的子器件寄存器地址
while(BUSY) //等待总线皮腔空闲
BUSY=1//占据数据总线
SMB_RW=0 //发送数据
STA=1//开始传送
while(BUSY)
SPI0CN |=0x01 //重新开启SPI
TR0=1
}
void read_pcf8563(uchar ADDseg) //读当时的时间
{
SPI0CN &=~0x01 //暂时关闭SPI传送,防止产生不必要的干扰
SMBus_ReadControl=1//控制本次 *** 作是读(1)、还是写(0)寄存器
SMBus_Send_Seg_ADDR=1//是否要传送寄存器的地址(1为传送)
TARGET = pcf8563 //送子器件地址
Seg_ADDR = ADDseg //送要 *** 作的子器件寄存器地址
while(BUSY) //等待总线空闲
BUSY=1
SMB_RW=0 //发送数据
STA=1
while(BUSY) //等待总线空闲(即等到传送数据结束)
SPI0CN |=0x01 //重新开启SPI
}
void SMBus_ISR (void) interrupt 7
{
bit FAIL = 0
bit SEND_START
if (ARBLOST == 0) //如果赢得总线
{
switch (SMB0CN &0xF0) //确定中断来源
{
case 0xe0://主发送方式下产生开始条件
SMB0DAT = TARGET
SMB0DAT &= 0xFE
SMB0DAT |= SMB_RW //对发送的数据进行处理
STA = 0
break
case 0xc0://主方式下发送
if (ACK)
{
if (SEND_START) //写完寄存器后控制再次发送
{
STA = 1
SEND_START = 0
break
}
if(SMBus_Send_Seg_ADDR) //是否要传送寄存器的地址
{
SMBus_Send_Seg_ADDR = 0
SMB0DAT = Seg_ADDR
if (SMBus_ReadControl) //控制本次 *** 作是读、还是写寄存器
{
SEND_START = 1
SMB_RW = 1
}
break
}
if (SMB_RW == 0)
{
if(send_receive_i<Send_Number)
{
SMB0DAT = send[send_receive_i]
send_receive_i++
}
else
{
send_receive_i=0
STO = 1
BUSY = 0
}
}
else {}
}
else //收到NACK信号的处理
{
STO = 1
STA = 1
}
break
case 0x80: //主方式下接收
if (send_receive_i<Receive_Number-1) //控制接收Receive_Number个数据就结束
{
receive[send_receive_i] = SMB0DAT
ACK = 1
send_receive_i++
}
else
{
receive[send_receive_i] = SMB0DAT
send_receive_i=0
BUSY = 0
ACK = 0
STO = 1
}
break
default:
FAIL = 1
break
}
}
else //输掉总线
{
FAIL = 1
}
if (FAIL) //SMBUS通讯失败后的处理
{
SMB0CF &= ~0x80
SMB0CF |= 0x80
STA = 0
STO = 0
ACK = 0
BUSY = 0
FAIL = 0
}
SI = 0
}
void T3_ISR() interrupt 14 //定时器3中断服务程序 用于检测SMBus是否超时
{
SMB0CF &= ~0x80
SMB0CF |= 0x80
TMR3CN &=~0x80
STA = 0
BUSY = 0
pcf8563_scl=1
}
欢迎分享,转载请注明来源:内存溢出
微信扫一扫
支付宝扫一扫
评论列表(0条)