单总线解析与DS2401驱动程序设计

单总线解析与DS2401驱动程序设计

                                     

 

单总线协议(1-wire)

定义:主机和从机通过1根线进行通信,在一条总线上可挂接的从器件数量几乎不受限制。特点:这是由达拉斯半导体公司推出的一项通信技术。它采用单根信号线,既可传输时钟,又能传输数据,而且数据传输是双向的。优点:单总线技术具有线路简单,硬件开销少,成本低廉,便于总线扩展和维护等。

注意:总线上拉电阻选择

单总线通信过程

2.1 初始化

初始化过程 = 复位脉冲 + 从机应答脉冲。

主机通过拉低单总线480 ~ 960 us产生复位脉冲,然后释放总线,进入接收模式。主机释放总线时,会产生低电平跳变为高电平的上升沿,单总线器件检测到上升沿之后,延时15 ~ 60 us,单总线器件拉低总线60 ~ 240 us来产生应答脉冲。主机接收到从机的应答脉冲说明单总线器件就绪,初始化过程完成。

 

 

2.2 写间隙

写间隙有两种,包括写0的时间隙和写1的时间隙。

当数据线拉低后,在15 ~ 60 us的时间窗口内对数据线进行采样。如果数据线为低电平,就是写0,如果数据线为高电平,就是写1。主机要产生一个写1时间隙,就必须把数据线拉低,在写时间隙开始后的15 us内允许数据线拉高。主机要产生一个写0时间隙,就必须把数据线拉低并保持60 us。

 

 

 

2.3 读时间隙

当主机把总线拉低是,并保持至少1 us后释放总线,必须在15 us内读取数据。

 

 

 

DS2401简介

DS2401 增强型硅序列号是一款低成本的电子注册码,以最少的电接口(通常只需一个微处理器端口)提供绝对、唯一的识别功能。内含一个工厂刻入的 64 位 ROM,其中包括: 48 位唯一序列码、 8 位 CRC 校验码和 8 位家族码 (01h)。数据采用 1-Wire 协议,仅通过一个信号引线和一个地回路串行传输。用于读取和写入器件的电源可以由数据线本身产生,无需外部供电。

3.1 复位脉冲和在线应答脉冲的复位过程 

      从下图看知道复位信号是单片机下拉总线480us~960us,然后释放总线,也就是改单片机IO口为输入状态。60us后读取总线时间,读取总线电平必须在释放总线后60us但是不能超过240us时间。如果读取到低电平,那么表示复位成功。

 

 

3.2 写 0(Write 0)

   主机拉低总线后,需要保持60us以上,但是不能超过120us.     

 

 

 

3.3 写 1(Write 1)

      主机要产生一个写1时间隙,就必须把数据线拉低,在写时间隙开始后的15 us内允许数据线拉高,15us后从机就开始读取总线的电平,期间不可以改变总线状态。  

 

 

3.4 读数据(Read Data)

当主机把总线拉低是,并保持至少1 us后释放总线,必须在15 us内读取数据。

 

 

 

DS2401驱动程序设计

DS2401 内建 ROM 仅由单根数据线访问。依据 Dallas 的 1-Wire 协议,可以从中提取 48 位序列码, 8 位家族码和 8 位 CRC 校验码。 1-Wire 通信协议规定总线的收发按照特殊时隙下的总线状态进行、由主机发出的同步脉冲下降沿初始化。所有数据读写都按照低位在前的原则。

8 位 CRC 校验码算法设计

1. static unsigned char CRC8Calculate(void *pBuf ,unsigned pBufSize)  

2. {  

3.     unsigned char retCRCValue=0x00;  

4.     unsigned char *pData;  

5.     int i=0;  

6.     unsigned char pDataBuf=0;  

7.   //  retCRCValue=0x01;  

8.     pData=(unsigned char *)pBuf;  

9.    // pDataBuf=pData[0];  

10.    // cout<>=1;  

21.                  retCRCValue|=0x80;  

22.              //    printf("i=%d;retCRCValue=%x\n",i,retCRCValue);  

23.              }  

24.              else  

25.              {  

26.                    retCRCValue>>=1;  

27.              //     printf("i=%d;retCRCValue=%x\n",i,retCRCValue);  

28.              }  

29.             pDataBuf>>=1;  

30.          }  

31.   

32.      }  

33.      return retCRCValue;  

34. }  





1. //the cyclic redundancy check  

2. void crc(unsigned char byte)  

3. {  

4. unsigned char crc,bit0,cbit,r;  

5. int i;  

6. crc=peekb(0x60);  

7. for(i=0;i<=7;i++)  

8. {  

9. cbit=crc&0x01;  

10. bit0=byte&0x01;  

11. crc=crc>>1;  

12. r=cbit^bit0;  

13. if(r==1)  

14. {  

15. crc=crc^0x8c;  

16. }  

17. byte=byte>>1;  

18. }  

19. pokeb(0x60,crc);  

20. }   

21. //end of crc  



   接口设计:

1. //******************************DS2401初始化*************************  

2.   

3. unsigned char DS2401Init(void)  

4. {  

5.     unsigned char result;  

6.     DelayNus(G);  

7.     DS2401IO = 0; // Drives DQ low  

8.     DelayNus(H);  

9.     DS2401IO = 1; // Releases the bus  

10.     DelayNus(I);  

11.     if(DS2401IO==0)  

12.     result = 1;  

13.     else   

14.     result = 0;  

15.     DelayNus(J); // Complete the reset sequence recovery  

16.     return result; // Return sample presence pulse result  

17.     //1代表初始化成功,0代表失败  

18. }  

19.   

20. //******************************发送读写命令*************************  

21. void SendOrderToDS2401(unsigned char order)  

22. {  

23.     unsigned char Temp = 8;  

24.     while(Temp)  

25.         {  

26.         if(order&0x80)  

27.             {  

28.             DS2401IO = 0;  

29.             DelayNus(4);//拉低10us  

30.             DS2401IO = 1;//拉高  

31.             DelayNus(200);  

32.             }  

33.         else  

34.             {  

35.             DS2401IO = 0;  

36.             DelayNus(100);//拉低100us  

37.             DS2401IO = 1;//拉高  

38.             DelayNus(200);  

39.             }  

40.         Temp--;  

41.         order<<=1;  

42.         }  

43.    

44. }  

45.   

46. //*****************************对2401写一位数据**********************  

47. void DS2401WriteBit(bit b)  

48. {  

49.     if (b)  

50.     {  

51.     // Write '1' bit  

52.     DS2401IO = 0; // Drives DQ low  

53.     DelayNus(A);  

54.     DS2401IO = 1; // Releases the bus  

55.     DelayNus(B); // Complete the time slot and 10us recovery  

56.     }  

57.     else  

58.     {  

59.     // Write '0' bit  

60.     DS2401IO = 0; // Drives DQ low  

61.     DelayNus(C);  

62.     DS2401IO = 1; // Releases the bus  

63.     DelayNus(D);  

64.     }  

65. }  

66.   

67. //*****************************对2401读一位数据**********************  

68.   

69. unsigned char  DS2401ReadBit(void)  

70. {  

71.     unsigned char result;  

72.     DS2401IO = 0; // Drives DQ low  

73.     DelayNus(A);  

74.     DS2401IO = 1; // Releases the bus  

75.     DelayNus(E);  

76.     result = DS2401IO ;; // Sample the bit value from the slave  

77.     DelayNus(F); // Complete the time slot and 10us recovery  

78.     return result;  

79. }  

80. //*****************************对2401写一个字节数据**********************  

81.   

82. void OWWriteByte(int value)  

83. {  

84.     unsigned char loop;  

85.     for (loop = 0; loop < 8; loop++)  

86.     {  

87.     DS2401WriteBit(value & 0x01);  

88.     value >>= 1;  

89.     }  

90. }  

91. //*****************************对2401读一个字节数据**********************  

92.   

93. unsigned char OWReadByte(void)  

94. {  

95.     unsigned char loop, result=0;  

96.     for (loop = 0; loop < 8; loop++)  

97.     {  

98.         result >>= 1;  

99.         if (DS2401ReadBit())  

100.         result |= 0x80;  

101.     }  

102.     return result;  

103. }  

104.   

105. //******************************读DS2401 ID 号*************************  

106. void ReadDS2401ID(void)  

107. {  

108.       

109.     unsigned char Temp=0;  

110.     while(1)  

111.         {  

112.         if(DS2401Init())  

113.             {  

114.                 DS2401WorkOK = 1;//表示DS2401初始化成功  

115.                 break;  

116.             }  

117.         else Temp++;  

118.         if(Temp>=10)  

119.             {  

120.                 DS2401WorkOK=0;//初始化10次失败的化,表示DS2401工作不正常  

121.                 break;  

122.             }  

123.         }  

124.     if(DS2401WorkOK)  

125.         {  

126.         OWWriteByte(0x33);//发送读命令码  

127.         for (Temp=0;Temp<8;Temp++)  

128.             {  

129.                 IDCode[Temp] = OWReadByte();//读一个字节,总共8个  

130.             }  

131.         }  

132.    

133. }  





 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

你可能感兴趣的:(单总线解析与DS2401驱动程序设计)