ENGLISH 简体中文 日本語 한국어  


应用笔记126

用软件实现1-Wire通信

摘要:在没有专用总线主机(如DS2480B、DS2490)的情况下,微处理器可以轻松地产生1-Wire®时序信号。本应用笔记给出了一个采用‘C’语言编写、支持标准速率的1-Wire主机通信基本子程序实例。1-Wire总线的四个基本操作是:复位、写“1”、写“0”和读数据位。字节操作可以通过反复调用位操作实现,本文提供了通过各种传输线与1-Wire器件进行可靠通信的时间参数。

引言

在没有专用总线主机的情况下,微处理器可以轻松地产生1-Wire时序信号。本应用笔记给出了一个采用‘C’语言编写、支持标准速率的1-Wire主机通信基本子程序实例。此外,本文也讨论了高速通信模式。要使该实例中的代码正常运行,系统必须满足以下几点要求:

  1. 微处理器的通信端口必须是双向的,其输出为漏极开路,且线上具有弱上拉。这也是所有1-Wire总线的基本要求。关于简单的1-Wire主机微处理器电路实例,请参见1-Wire网络可靠设计指南(应用笔记148)的附录A。
  2. 微处理器必须能产生标准速度1-Wire通信所需的精确1µs延时和高速通信所需要的0.25µs延时。
  3. 通信过程不能被中断。
1-Wire总线有四种基本操作:复位、写1位、写0位和读位操作。在产品资料中,将完成一位传输的时间称为一个时隙。于是字节传输可以通过多次调用位操作来实现,下表1是各个位操作的简要说明以及实现这些操作所必须的步骤列表。图1为其时序波形图。表2给出了通常线路条件下1-Wire主机与1-Wire器件通信的最短、最长和推荐时间。如果与1-Wire主机相连的器件比较特殊或者线路条件比较特殊,则可以采用最小值或最大值。

表1. 1-Wire操作
Operation Description Implementation
Write 1 bit Send a '1' bit to the 1-Wire slaves (Write 1 time slot) Drive bus low, delay A
Release bus, delay B
Write 0 bit send a '0' bit to the 1-Wire slaves (Write 0 time slot) Drive bus low, delay C
Release bus, delay D
Read bit Read a bit from the 1-Wire slaves (Read time slot) Drive bus low, delay A
Release bus, delay E
Sample bus to read bit from slave
Delay F
Reset Reset the 1-Wire bus slave devices and ready them for a command Delay G
Drive bus low, delay H
Release bus, delay I
Sample bus, 0 = device(s) present, 1 = no device present
Delay J


图1. 1-Wire时序图
图1. 1-Wire时序图

表2. 1-Wire主机时序
Parameter Speed Min (µs) Recommended (µs) Max (µs) Notes
A Standard 5 6 15 1, 2
Overdrive 1 1.5 1.85 1, 3
B Standard 59 64 N/A 2, 4
Overdrive 7.5 7.5 N/A 3, 4
C Standard 60 60 120 2, 5
Overdrive 7 7.5 14 3, 5
D Standard 8 10 N/A 2, 6
Overdrive 2.5 2.5 N/A 3, 6
E Standard 5 9 12 2, 7, 8
Overdrive 0.5 0.75 0.85 3, 7, 8
F Standard 50 55 N/A 2, 9
Overdrive 6.75 7 N/A 3, 9
G Standard 0 0 0  
Overdrive 2.5 2.5 N/A 3, 14
H Standard 480 480 640 2, 10, 15
Overdrive 68 70 80 3, 10
I Standard 63 70 78 2, 11
Overdrive 7.2 8.5 8.8 3, 11
J Standard 410 410 N/A 2, 12, 13
Overdrive 39.5 40 N/A 3, 12

有关表中这些值的详细计算,可参考:http://files.dalsemi.com/auto_id/public/an126.zip

注释:
  1. 在产品数据资料中,表示为tW1L (写1低)减去ε (上升至VTH的时间)加上tF (下降至VTL的时间)。
  2. 假定网络为标准速度的中等距离网络,且上升和下降时间不超过3µs。
  3. 假定网络为高速的小型网络,且上升和下降时间不超过0.5µs。
  4. 数据资料中,表示为tSLOT (时隙时间)减去‘A’所代表的时间。
  5. 数据资料中,表示为tW0L (写0低)减去δ (上升至VIHMASTER的时间)加上tF (下降至VTL的时间)。
  6. 数据资料中,表示为tREC (恢复时间)加上δ (上升至VIHMASTER的时间)。
  7. 数据资料中,表示为tMSR (主机采样读时间)加上tF (下降至VTL的时间),再减去‘A’。
  8. 在该范围内,采样要尽可能晚,以便获得最长的恢复时间。
  9. 数据资料中,表示为tSLOT (时隙时间)减去‘A’,再减去‘E’。
  10. 数据资料中,表示为tRSTL (复位为低的时间)减去ε (上升至VTH的时间)加上tF (下降至VTL的时间)。
  11. 数据资料中,表示为tMSP (主机采样应答时间)加上ε (上升至VTH的时间)。
  12. 数据资料中,其最小值表示为tRSTL (复位低电平时间)减去‘I’所用的时间。
  13. 这里所提到的1-Wire复位操作没有把DS2404和DS1994使用的扩展应答(报警)脉冲序列考虑进去,关于这种特殊情况,请查看产品的数据资料。在1-Wire复位序列的未尾进行采样,可以验证1-Wire总线是否已返回到上拉电平。如果电平仍为0,则可能是1-Wire总线与地之间短路,或DS2404/DS1994发出了报警信号。
  14. 表示为tREC (恢复时间)减去‘D’所用的时间。在高速应用时,一些器件在tRSTL (低电平复位时间)之前要求额外的延时,以保证器件的寄生电源被完全充满。
  15. 对于低电压工作方式,有些器件可能需要更长的延时。关于合适的参数值,请参阅器件数据资料。

代码实例

下面代码实例都依赖于两个通用的‘C’函数outp和inp,从IO端口读写字节数据。他们通常位于标准库中。当应用于其它平台时,可以采用合适的函数来替代它们。

// send 'databyte' to 'port'
int outp(unsigned port, int databyte);

// read byte from 'port'
int inp(unsigned port);
代码中的常量PORTADDRESS (图3)用来定义通信端口的地址。这里我们假定使用通信端口的第0位控制1-Wire总线。设定该位为1,将使1-Wire总线变为低电平;设定该位为0,1-Wire总线将被释放,此时1-Wire总线被电阻上拉,或被1-Wire从器件下拉。

代码中的tickDelay函数是一个用户编制的子程序,此函数用于产生一个1/4µs整数倍的延时。在不同的平台下,该函数的实现也是不同的,故在此不做具体描述。以下是tickDelay函数声明代码,以及一个SetSpeed函数,用于设定标准速度和高速模式的延时时间。

实例1. 1-Wire时序的生成

// Pause for exactly 'tick' number of ticks = 0.25us
void tickDelay(int tick); // Implementation is platform specific

// 'tick' values
int A,B,C,D,E,F,G,H,I,J;

//-----------------------------------------------------------------------------
// Set the 1-Wire timing to 'standard' (standard=1) or 'overdrive' (standard=0).
//
void SetSpeed(int standard)
{
	// Adjust tick values depending on speed
	if (standard)
	{
		// Standard Speed
		A = 6 * 4;
		B = 64 * 4;
		C = 60 * 4;
		D = 10 * 4;
		E = 9 * 4;
		F = 55 * 4;
		G = 0;
		H = 480 * 4;
		I = 70 * 4;
		J = 410 * 4;
	}
	else
	{
		// Overdrive Speed
		A = 1.5 * 4;
		B = 7.5 * 4;
		C = 7.5 * 4;
		D = 2.5 * 4;
		E = 0.75 * 4;
		F = 7 * 4;
		G = 2.5 * 4;
		H = 70 * 4;
		I = 8.5 * 4;
		J = 40 * 4;
	}
}
1-Wire基本操作的代码程序如实例2所示。

实例2. 基本的1-Wire函数

//-----------------------------------------------------------------------------
// Generate a 1-Wire reset, return 1 if no presence detect was found,
// return 0 otherwise.
// (NOTE: Does not handle alarm presence from DS2404/DS1994)
//
int OWTouchReset(void)
{
	int result;

	tickDelay(G);
	outp(PORTADDRESS,0x00); // Drives DQ low
	tickDelay(H);
	outp(PORTADDRESS,0x01); // Releases the bus
	tickDelay(I);
	result = inp(PORTADDRESS) & 0x01; // Sample for presence pulse from slave
	tickDelay(J); // Complete the reset sequence recovery
	return result; // Return sample presence pulse result
}

//-----------------------------------------------------------------------------
// Send a 1-Wire write bit. Provide 10us recovery time.
//
void OWWriteBit(int bit)
{
	if (bit)
	{
		// Write '1' bit
		outp(PORTADDRESS,0x00); // Drives DQ low
		tickDelay(A);
		outp(PORTADDRESS,0x01); // Releases the bus
		tickDelay(B); // Complete the time slot and 10us recovery
	}
	else
	{
		// Write '0' bit
		outp(PORTADDRESS,0x00); // Drives DQ low
		tickDelay(C);
		outp(PORTADDRESS,0x01); // Releases the bus
		tickDelay(D);
	}
}

//-----------------------------------------------------------------------------
// Read a bit from the 1-Wire bus and return it. Provide 10us recovery time.
//
int OWReadBit(void)
{
	int result;

	outp(PORTADDRESS,0x00); // Drives DQ low
	tickDelay(A);
	outp(PORTADDRESS,0x01); // Releases the bus
	tickDelay(E);
	result = inp(PORTADDRESS) & 0x01; // Sample the bit value from the slave
	tickDelay(F); // Complete the time slot and 10us recovery

	return result;
}
该程序包括了1-Wire总线的所有位操作,通过调用该程序可以构成以字节为处理对象的函数,见实例3。

实例3. 派生的1-Wire函数

//-----------------------------------------------------------------------------
// Write 1-Wire data byte
//
void OWWriteByte(int data)
{
	int loop;

	// Loop to write each bit in the byte, LS-bit first
	for (loop = 0; loop < 8; loop++)
	{
		OWWriteBit(data & 0x01);

		// shift the data byte for the next bit
		data >>= 1;
	}
}

//-----------------------------------------------------------------------------
// Read 1-Wire data byte and return it
//
int OWReadByte(void)
{
	int loop, result=0;

	for (loop = 0; loop < 8; loop++)
	{
		// shift the result to get it ready for the next bit
		result >>= 1;

		// if result is one, then set MS bit
		if (OWReadBit())
			result |= 0x80;
	}
	return result;
}

//-----------------------------------------------------------------------------
// Write a 1-Wire data byte and return the sampled result.
//
int OWTouchByte(int data)
{
	int loop, result=0;

	for (loop = 0; loop < 8; loop++)
	{
		// shift the result to get it ready for the next bit
		result >>= 1;

		// If sending a '1' then read a bit else write a '0'
		if (data & 0x01)
		{
			if (OWReadBit())
				result |= 0x80;
		}
		else
			OWWriteBit(0);

		// shift the data byte for the next bit
		data >>= 1;
	}
	return result;
}

//-----------------------------------------------------------------------------
// Write a block 1-Wire data bytes and return the sampled result in the same
// buffer.
//
void OWBlock(unsigned char *data, int data_len)
{
	int loop;

	for (loop = 0; loop < data_len; loop++)
	{
		data[loop] = OWTouchByte(data[loop]);
	}
}

//-----------------------------------------------------------------------------
// Set all devices on 1-Wire to overdrive speed. Return '1' if at least one
// overdrive capable device is detected.
//
int OWOverdriveSkip(unsigned char *data, int data_len)
{
	// set the speed to 'standard'
	SetSpeed(1);

	// reset all devices
	if (OWTouchReset()) // Reset the 1-Wire bus
		return 0; // Return if no devices found

	// overdrive skip command
	OWWriteByte(0x3C);

	// set the speed to 'overdrive'
	SetSpeed(0);

	// do a 1-Wire reset in 'overdrive' and return presence result
	return OWTouchReset();
}
OWTouchByte函数可以同时完成读写1-Wire总线数据,通过该函数可以实现数据块的读写。在一些平台上执行效率更高, Dallas Semiconductor提供的API就采用了这种函数。通过OWTouchByte函数,OWBlock函数简化了1-Wire总线的数据块发送和接收。注意:OWTouchByte(0xFF)OWReadByte()等效,OWTouchByte(data)OWWriteByte(data)等效。

这些函数和tickDelay函数一起构成了1-Wire总线进行位、字节和块操作时所必需的全部函数。实例4给出了利用这些函数读取DS2432的SHA-1认证页的实例。

实例4. 读DS2432实例

//-----------------------------------------------------------------------------
// Read and return the page data and SHA-1 message authentication code (MAC)
// from a DS2432.
//
int ReadPageMAC(int page, unsigned char *page_data, unsigned char *mac)
{
	int i;
	unsigned short data_crc16, mac_crc16;

	// set the speed to 'standard'
	SetSpeed(1);

	// select the device
	if (OWTouchReset()) // Reset the 1-Wire bus
		return 0; // Return if no devices found

	OWWriteByte(0xCC); // Send Skip ROM command to select single device

	// read the page
	OWWriteByte(0xA5); // Read Authentication command
	OWWriteByte((page << 5) & 0xFF); // TA1
	OWWriteByte(0); // TA2 (always zero for DS2432)

	// read the page data
	for (i = 0; i < 32; i++)
		page_data[i] = OWReadByte();
	OWWriteByte(0xFF);

	// read the CRC16 of command, address, and data
	data_crc16 = OWReadByte();
	data_crc16 |= (OWReadByte() << 8);

	// delay 2ms for the device MAC computation
	// read the MAC
	for (i = 0; i < 20; i++)
		mac[i] = OWReadByte();

	// read CRC16 of the MAC
	mac_crc16 = OWReadByte();
	mac_crc16 |= (OWReadByte() << 8);

	// check CRC16...
	return 1;
}

附加软件

本应用笔记给出了1-Wire总线操作的基本函数,这些基本函数都是构建复杂的1-Wire应用的基础。本文忽略的一个重要操作是1-Wire搜索。通过1-Wire搜索可以搜索到挂接在总线上的多个1-Wire从机器件的唯一ID号。在应用笔记187:1-Wire搜索算法一文中详细介绍了这种搜索方法,同时也给出了实现这些1-Wire基本函数的C程序代码。

1-Wire公共开发包中含有大量针对特定器件编写的代码,由下列链接提供:
http://www.ibutton.com/software/1wire/wirekit.html

其它更详细的资料请参阅应用笔记155:1-Wire软件资源指南

替换方案

如果对于某一特定应用,通过软件实现1-Wire主机方案不可行,则作为替换方案,可以采用1-Wire主机芯片或合成的1-Wire主机单元。

Dallas Semiconductor提供了采用Verilog和VHDL编写的1-Wire主机。
DS1WM

通过下面的链接可下载1-Wire主机的代码定义。 (ZIP文件)

合成的1-Wire主机工作方式在应用笔记120:利用1-Wire控制器通讯应用笔记119:嵌入1-Wire主机中进行了说明。

有多种1-Wire主机芯片可以作为微处理器的外设。串行、1-Wire线驱动器DS2480B能够很容易地与标准串行口连接。

关于DS2480B的操作,详见应用笔记192::DS2480B串行接口1-Wire线驱动器的使用)。

这是为远距离1-Wire传输线专门设计的先进的1-Wire线驱动器,在应用笔记244:性能优异的1-Wire网络驱动器中,描述了专门为长线设计、更为精细的1-Wire线驱动器。

修订历史记录
07/06/00:1.0版—最初版本。
05/28/02:2.0版—纠正了1-Wire复位采样时间。增加了波形图、链接和更多的代码实例。
02/02/04:2.1版—增加了对高速模式的支持,给出了时序的最小值、最大值,更新了代码实例。
09/06/05:2.2版—修正代码例程说明中的PIO极性。

1-Wire是Maxim Integrated Products, Inc.的注册商标。


我们期待您的反馈!
喜欢?不喜欢?有待改善?或为我们提供建议?请与我们联系 — 我们将根据您的意见或建议改善我们的工作。 网页评价或提供建议


自动更新
需要自动接收最新发布的应用笔记吗?请订阅EE-Mail™ (English only)。



更多信息  APP 126: Sep 16, 2004
DS18B20 分辨率可编程设置的1-Wire数字温度计 完整的数据资料
(PDF, 188kB)
DS18S20 1-Wire寄生供电数字温度计 完整的数据资料
(PDF, 188kB)
DS1904 RTC iButton 完整的数据资料
(PDF, 216kB)
DS1920 温度检测iButton® 完整的数据资料
(PDF, 560kB)
DS1921G Thermochron iButton 完整的数据资料
(PDF, 504kB)
DS1922L 温度记录器iButton,带有8KB数据记录存储器 完整的数据资料
(PDF, 508kB)
DS1922T 温度记录器iButton,带有8KB数据记录存储器 完整的数据资料
(PDF, 508kB)
DS1923 温度/湿度记录仪iButton,具有8KB数据记录存储器 完整的数据资料
(PDF, 1MB)
DS1963S SHA iButton
DS1971 256位EEPROM iButton® 完整的数据资料
(PDF, 296kB)
免费样品
DS1973 4K位EEPROM iButton® 完整的数据资料
(PDF, 268kB)
免费样品
DS1982 1K位只添加iButton® 完整的数据资料
(PDF, 564kB)
免费样品
DS1985 16K位只添加iButton® 完整的数据资料
(PDF, 708kB)
免费样品
DS1986 64K位只添加iButton® 完整的数据资料
(PDF, 688kB)
DS1990A 序列号iButton 完整的数据资料
(PDF, 456kB)
免费样品
DS1992 1K位/4K位存储器iButton® 完整的数据资料
(PDF, 348kB)
免费样品
DS1993 1K位/4K位存储器iButton® 完整的数据资料
(PDF, 348kB)
免费样品
DS1995 16K位存储器iButton® 完整的数据资料
(PDF, 68kB)
DS1996 64k位存储器iButton® 完整的数据资料
(PDF, 352kB)
DS2401 硅序列号 完整的数据资料
(PDF, 328kB)
免费样品
DS2405 可编址开关 完整的数据资料
(PDF, 436kB)
免费样品
DS2406 双通道、可编址开关与1K位存储器 完整的数据资料
(PDF, 452kB)
免费样品
DS2408 1-Wire、8通道、可编址开关 完整的数据资料
(PDF, 396kB)
免费样品
DS2411 硅序列号,带有VCC输入 完整的数据资料
(PDF, 380kB)
免费样品
DS2413 1-Wire、双通道、可编址开关 完整的数据资料
(PDF, 360kB)
免费样品
DS2415 1-Wire时钟芯片 完整的数据资料
(PDF, 256kB)
DS2417 1-Wire时钟芯片,带有中断 完整的数据资料
(PDF, 164kB)
免费样品
DS2422 1-Wire®温度/数据记录器,带有8KB数据记录存储器 完整的数据资料
(PDF, 500kB)
DS2431 1024位1-Wire EEPROM 完整的数据资料
(PDF, 900kB)
免费样品
DS2432 1k位、保护型1-Wire EEPROM,带有SHA-1引擎 数据资料缩写本
(PDF, 272kB)
DS2433 4K位1-Wire EEPROM 完整的数据资料
(PDF, 700kB)
免费样品
DS2438 智能电池监视器 完整的数据资料
(PDF, 376kB)
DS2450 四路、1-Wire A/D转换器 完整的数据资料
(PDF, 616kB)
免费样品
DS2480B 串行、1-Wire线驱动器 完整的数据资料
(PDF, 712kB)
免费样品
DS2502 1K位只添加存储器 完整的数据资料
(PDF, 1.0MB)
免费样品
DS2502-E48 48位节点地址芯片 完整的数据资料
(PDF, 48kB)
免费样品
DS2505 16K位只添加存储器 完整的数据资料
(PDF, 552kB)
免费样品
DS2506 64K位只添加存储器 完整的数据资料
(PDF, 900kB)
免费样品
DS2751 多种化学类型的电池电量计
DS2760 高精度、Li+电池监视器 完整的数据资料
(PDF, 296kB)
DS2761 高精度、Li+电池监视器 完整的数据资料
(PDF, 316kB)
DS2762 高精度、Li+电池监视器,带报警输出 完整的数据资料
(PDF, 268kB)
免费样品
DS28E04-100 4096位、可寻址、1-Wire EEPROM,带有PIO 完整的数据资料
(PDF, 720kB)
免费样品
 

下载,PDF格式下载,PDF格式 (67kB)
 AN126, AN 126, APP126, Appnote126, Appnote 126


      隐私权政策    法律声明

      © 2008 Maxim Integrated Products, Dallas Semiconductor版权所有