找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 2178|回复: 2
收起左侧

带有存储器功能的数字温度计-DS1624技术应用

[复制链接]
ID:898981 发表于 2021-4-9 15:44 | 显示全部楼层 |阅读模式
1. DS1624基本原理
   DS1624是美国DALLAS公司生产的集成了测量系统和存储器于一体的芯片。数字接口电路简单,与I2C总线兼容,且可以使用一片控制器控制多达8片的DS1624。其数字温度输出达13位,精度为0.03125℃。DS1624可工作在最低2.7V电压下,适用于低功耗应用系统。
1). DS1624基本特性
  ◆ 无需外围元件即可测量温度
◆ 测量范围为-55℃~+125℃,精度为0.03125℃
◆ 测量温度的结果以13位数字量(两字节传输)给出
◆ 测量温度的典型转换时间为1秒        
◆ 集成了256字节的E2PROM非易性存储器
◆ 数据的读出和写入通过一个2-线(I2C)串行接口完成
◆采用8脚DIP或SOIC封装
DS1624在测量温度时使用了独有的在线温度测量技术。它通过在一个由对温度高度敏感的振荡器决定的计数周期内对温度低敏感的振荡器时钟脉冲的计数值的计算来测量温度。DS1624在计数器中预置了一个初值,它相当于-55℃。如果计数周期结束之前计数器达到0,已预置了此初值的温度寄存器中的数字就会增加,从而表明温度高于-55℃。
与此同时,计数器斜坡累加电路被重新预置一个值,然后计数器重新对时钟计数,直到计数值为0。
通过改变增加的每1℃内的计数器的计数,斜坡累加电路可以补偿振荡器的非线性误差,以提高精度,任意温度下计数器的值和每一斜坡累加电路的值对应的计数次数须为已知。
  DS1624通过这些计算可以得到0.03125℃的精度,温度输出为13位,在发出读温度值请求后还会输出两位补偿值。表2给出了所测的温度和输出数据的关系。这些数据可通过2线制串行口连续输出,MSB在前,LSB在后。
由于数据在总线上传输时MSB在前,所以DS1624读出的数据可以是一个字节(分辨率为1℃),也可以是两个字节,第二个字节包含的最低位为0.03125℃。
  1. #include <AT89X52.H>
  2. #include <INTRINS.H>
  3. unsigned char code displaybit[]={0xfe,0xfd,0xfb,0xf7,
  4. 0xef,0xdf,0xbf,0x7f};
  5. unsigned char code displaycode[]={0x3f,0x06,0x5b,0x4f,
  6. 0x66,0x6d,0x7d,0x07,
  7. 0x7f,0x6f,0x77,0x7c,
  8. 0x39,0x5e,0x79,0x71,0x00};
  9.  
  10. unsigned char code dotcode[32]={0,3,6,9,12,16,19,22,
  11. 25,28,31,34,38,41,44,48,
  12. 50,53,56,59,63,66,69,72,
  13. 75,78,81,84,88,91,94,97};
  14. sbit SDA=P1^6;
  15. sbit SCL=P1^7;
  16.  
  17. unsigned char displaybuffer[8]={0,1,2,3,4,5,6,7};
  18. unsigned char eepromdata[8];
  19. unsigned char temperdata[2];
  20.  
  21. unsigned char timecount;
  22. unsigned char displaycount;
  23.  
  24. bit secondflag=0;
  25. unsigned char secondcount=0;
  26. unsigned char retn;
  27. unsigned int result;
  28. unsigned char x;
  29. unsigned int k;
  30. unsigned int ks;
  31.  
  32. void delay(void);
  33. void delay10ms(void);
  34. void i_start(void);
  35. void i_stop(void);
  36. void i_init(void);
  37. void i_ack(void);
  38. bit i_clock(void);
  39. bit i_send(unsigned char i_data);
  40. unsigned char i_receive(void);
  41. bit start_temperature_T(void);
  42. bit read_temperature_T(unsigned char *p);
  43. void delay(void)
  44. {
  45. _nop_();
  46. _nop_();
  47. _nop_();
  48. _nop_();
  49. _nop_();
  50. _nop_();
  51. }
  52.  
  53. void delay10ms(void)
  54. {
  55. unsigned int i;
  56. for(i=0;i<1000;i++)
  57. {
  58. delay();
  59. }
  60. }
  61.  
  62. void i_start(void)
  63. {
  64. SCL=1;
  65. delay();
  66. SDA=0;
  67. delay();
  68. SCL=0;
  69. delay();
  70. }
  71.  
  72. void i_stop(void)
  73. {
  74. SDA=0;
  75. delay();
  76. SCL=1;
  77. delay();
  78. SDA=1;
  79. delay();
  80. SCL=0;
  81. delay();
  82. }
  83. void i_init(void)
  84. {
  85. SCL=0;
  86. i_stop();
  87. }
  88.  
  89. void i_ack(void)
  90. {
  91. SDA=0;
  92. i_clock();
  93. SDA=1;
  94. }
  95.  
  96. bit i_clock(void)
  97. {
  98. bit sample;
  99.  
  100. SCL=1;
  101. delay();
  102. sample=SDA;
  103. _nop_();
  104. _nop_();
  105. SCL=0;
  106. delay();
  107. return(sample);
  108. }
  109.  
  110. bit i_send(unsigned char i_data)
  111. {
  112. unsigned char i;
  113.  
  114. for(i=0;i<8;i++)
  115. {
  116. SDA=(bit)(i_data & 0x80);
  117. i_data=i_data<<1;
  118. i_clock();
  119. }
  120. SDA=1;
  121. return(~i_clock());
  122. }
  123. unsigned char i_receive(void)
  124. {
  125. unsigned char i_data=0;
  126. unsigned char i;
  127.  
  128. for(i=0;i<8;i++)
  129. {
  130. i_data*=2;
  131. if(i_clock()) i_data++;
  132. }
  133. return(i_data);
  134. }
  135.  
  136. bit start_temperature_T(void)
  137. {
  138. i_start();
  139. if(i_send(0x90))
  140. {
  141. if(i_send(0xee))
  142. {
  143. i_stop();
  144. delay();
  145. return(1);
  146. }
  147. else
  148. {
  149. i_stop();
  150. delay();
  151. return(0);
  152. }
  153. }
  154. else
  155. {
  156. i_stop();
  157. delay();
  158. return(0);
  159. }
  160. }
  161.  
  162. bit read_temperature_T(unsigned char *p)
  163. {
  164. i_start();
  165. if(i_send(0x90))
  166. {
  167. if(i_send(0xaa))
  168. {
  169. i_start();
  170. if(i_send(0x91))
  171. {
  172. *(p+1)=i_receive();
  173. i_ack();
  174. *p=i_receive();
  175. i_stop();
  176. delay();
  177. return(1);
  178. }
  179. else
  180. {
  181. i_stop();
  182. delay();
  183. return(0);
  184. }
  185. }
  186. else
  187. {
  188. i_stop();
  189. delay();
  190. return(0);
  191. }
  192. }
  193. else
  194. {
  195. i_stop();
  196. delay();
  197. return(0);
  198. }
  199. }
  200.  
  201. void main(void)
  202. {
  203. P1=0xff;
  204. timecount=0;
  205. displaycount=0;
  206. TMOD=0x21;
  207. TH1=0x06;
  208. TL1=0x06;
  209. TR1=1;
  210. ET1=1;
  211. ET0=1;
  212. EA=1;
  213.  
  214. if(start_temperature_T()) //向DS1624发送启动A/D温度转换命令,成功则启动T0定时1s。
  215. {
  216. secondflag=0;
  217. secondcount=0;
  218. TH0=55536/256;
  219. TL0=55536%256;
  220. TR0=1;
  221. }
  222. while(1)
  223. {
  224. if(secondflag==1)
  225. {
  226. secondflag=0;
  227. TR0=0;
  228. if(read_temperature_T(temperdata)) //T0定时1s时间到,读取DS1624的温度值
  229. {
  230. for(x=0;x<8;x++)
  231. {
  232. displaybuffer[x]=16;
  233. }
  234. x=2;
  235. result=temperdata[1]; //将读取的温度值进行数据处理,并送到显示缓冲区
  236. while(result/10)
  237. {
  238. displaybuffer[x]=result%10;
  239. result=result/10;
  240. x++;
  241. }
  242. displaybuffer[x]=result;
  243. result=temperdata[0];
  244. result=result>>3;
  245. displaybuffer[0]=(dotcode[result])%10;
  246. displaybuffer[1]=(dotcode[result])/10;
  247. if(start_temperature_T()) //温度值数据处理完毕,重新启动DS1624开始温度转换
  248. {
  249. secondflag=0;
  250. secondcount=0;
  251. TH0=55536/256;
  252. TL0=55536%256;
  253. TR0=1;
  254. }
  255. }
  256. }
  257. }
  258. }
  259. void t0(void) interrupt 1 using 0 //T0用于定时1s时间到
  260. {
  261. secondcount++;
  262. if(secondcount==100)
  263. {
  264. secondcount=0;
  265. secondflag=1;
  266. }
  267. TH0=55536/256;
  268. TL0=55536%256;
  269. }
  270. void t1(void) interrupt 3 using 0 //T1定时1ms用数码管的动态刷新
  271. {
  272. timecount++;
  273. if(timecount==4) //T1定时1ms到
  274. {
  275. timecount=0;
  276. if (displaycount==5)
  277. {
  278. P0=(displaycode[displaybuffer[7-displaycount]] | 0x80); //在该位同时还要显示小数点
  279. }
  280. else
  281. {
  282. P0=displaycode[displaybuffer[7-displaycount]];
  283. }
  284. P2=displaybit[displaycount];
  285. displaycount++;
  286. if(displaycount==8)
  287. {
  288. displaycount=0;
  289. }
  290. }
  291. }
复制代码


22222.jpg
111111111.jpg

评分

参与人数 1黑币 +50 收起 理由
admin + 50 共享资料的黑币奖励!

查看全部评分

回复

使用道具 举报

ID:328014 发表于 2021-4-14 22:46 | 显示全部楼层
好资料,51黑有你更精彩!!!
回复

使用道具 举报

ID:47286 发表于 2021-4-15 01:21 来自手机 | 显示全部楼层
是每3度一级吗 范围太大了吧
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

手机版|小黑屋|51黑电子论坛 |51黑电子论坛6群 QQ 管理员QQ:125739409;技术交流QQ群281945664

Powered by 单片机教程网

快速回复 返回顶部 返回列表