单总线解析与DS2401驱动程序设计
单总线解析与DS2401驱动程序设计
1 单总线协议(1-wire)
定义:主机和从机通过1根线进行通信,在一条总线上可挂接的从器件数量几乎不受限制。特点:这是由达拉斯半导体公司推出的一项通信技术。它采用单根信号线,既可传输时钟,又能传输数据,而且数据传输是双向的。优点:单总线技术具有线路简单,硬件开销少,成本低廉,便于总线扩展和维护等。
注意:总线上拉电阻选择
2 单总线通信过程
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内读取数据。
3 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内读取数据。
4 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<<hex<<pDataBuf<<endl; 11. 12. while(pBufSize--) 13. { 14. pDataBuf=*pData++; 15. for(i=0;i<8;i++) 16. { 17. if((retCRCValue^(pDataBuf))&0x01) 18. { 19. retCRCValue^=0x18; 20. retCRCValue>>=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驱动程序设计相关推荐
- 简单说说驱动程序设计的入门
简单说说驱动程序设计的入门,其实初级驱动设计中也能使用C++,也能使用类,但和用户程序中的用法有一些区别,一些特殊的地方需要特别注意.从笔者的经验来看,WDK给出的AVStream小端口驱动示例工程, ...
- 键盘驱动程序设计(中)
问题 键盘扫描码可以直接使用吗?扫描码代表键位上的字符吗? 键盘扫描码不可以直接使用,扫描码不代表键位上的字符. 常用编码区别 扫描码(Scan Code) 与键盘厂商有关,不同厂商的扫描码可能不同 ...
- 基于μC/OS—III的CC1120驱动程序设计
基于μC/OS-III的CC1120驱动程序设计 时间:2014-01-21 来源:电子设计工程 作者:张绍游,张贻雄,石江宏 关键字:CC1120 嵌入式操作系统 STM32F103ZE ...
- 2018-2019-1 20165318 20165322 20165326 实验四 外设驱动程序设计
实验四 外设驱动程序设计 实验内容 任务一 任务二 问题及解决方法 参考链接 实验内容 任务一 学习资源中全课中的"hqyj.嵌入式Linux应用程序开发标准教程.pdf"中的第十 ...
- 信息安全系统设计基础 实验四:外社驱动程序设计 20135327郭皓 20135329 李海空...
北京电子科技学院(BESTI) 实 验 报 告 课程:信息安全设计基础 班级:1353 姓名:郭皓 李海空 学号:20135327 ...
- 2017-2018-1 20155327 实验四 外设驱动程序设计
2017-2018-1 20155327 实验四 外设驱动程序设计 题目一 学习资源中全课中的"hqyj.嵌入式Linux应用程序开发标准教程.pdf"中的第十一章 提交康奈尔笔记 ...
- 信息安全系统设计基础实验四:外设驱动程序设计 20145222黄亚奇 20145213祁玮
北京电子科技学院(BESTI) 实 验 报 告 封 面 课程:信息安全系统设计基础 班级:1452 姓名: 黄亚奇 祁玮 学号: 20145222 20145213 成绩: 指导教师:娄嘉鹏 实验日期 ...
- 2018-2019-1 20165211 实验四 外设驱动程序设计
2018-2019-1 20165211 实验四 外设驱动程序设计 任务一 1.实验要求 学习资源中全课中的"hqyj.嵌入式Linux应用程序开发标准教程.pdf"中的第十一章 ...
- Linux USB驱动程序设计
Linux USB驱动程序设计 1. USB发展史 USB(Universal Serial Bus ),通用串行总线,是一种外部总线标准,用于规范电脑与外部设备的连接和通讯. USB是在1994年底 ...
最新文章
- 100年前没人信他,但他仅1项研究便远程摧毁万架飞机……
- 扩展欧几里得,解线性同余方程 逆元 poj1845
- 2014年5月第二个周末总结--保守自己的心
- vss 2005 配置服务器端的时候提示IIS没有安装
- 自由软件之父Richard Stallman及其思想
- linux某用户 计划任务,Linux计划任务管理
- 林记seo告诉你seo教程菜鸟seo一个月到底能赚多少钱
- deepfool简单实现
- 每年10万被动收入目标分解 | 进击
- Seating Arrangement CSU - 1997 (思维题,是否存在n个数的序列,使得相邻啷个数的差绝对值大于d)
- 手势识别原来还可以这样控制电脑,你知道怎么做到的吗?
- android sku 库存管理,建议收藏!为什么合理的SKU设置对有效库存管理与销售至关重要?...
- Unity的C#编程教程_61_委托和事件 Delegates and Events 详解及应用练习
- MFC鼠标绘制直线段并使用编码裁剪算法
- Android 天气APP(十一)未来七天的天气预报、逐小时预报、UI优化
- mysql日志 事务问题_mysql因为事务日志问题无法启动
- 总结了 30 段极简 Python 代码
- 你们的老朋友又来啦!来听小强讲视频超分辨率算法前沿进展
- Elasticsearch Analyzer 内置分词器
- React学习笔记八-受控与非受控组件