温度传感器程序编写

  1 /* 首先对其先进行头文件的定义以及端口的定义 
  2 然后进行函数体的写,先写 ds18b20的初始化,然后写其 写字节, 编写读ds18B20
  3 继续写温度转换函数模块,因为转换模块的结果放在了寄存器中,所以在写从寄存器中将
  4 转换后的温度读出来 要有返回值 并且为两个字节 所以为 int 类型再读之前必须先将其读取寄存器的指令写入; 先读低字节,再读高字节
  5 然后在命名一个变量用来将这两个字节进行组合,temp=tmh; temp|=tml; return temp; 这就将这两个字节进行组合
  6 当得到这个数据之后,然后进行判断高5位是正温度还是负温度,然后还要这个温度*0.0625才可以的都真正的温度*/
  7 
  8 #include"temp.h"
  9 /*******************************************************************************
 10 * 函 数 名 : Delay1ms
 11 * 函数功能    : 延时函数
 12 * 输 入 : 无
 13 * 输 出 : 无
 14 *******************************************************************************/
 15 
 16 void Delay1ms(uint y)
 17 {
 18 uint x;
 19 for( ; y>0; y--)
 20 {
 21 for(x=110; x>0; x--);
 22 }
 23 }
 24 /*******************************************************************************
 25 * 函 数 名 : Ds18b20Init
 26 * 函数功能    : 初始化
 27 * 输 入 : 无
 28 * 输 出 : 初始化成功返回1,失败返回0
 29 *******************************************************************************/
 30 
 31 uchar Ds18b20Init()
 32 {
 33 uchar i;
 34 DSPORT = 0;    //将总线拉低480us~960us
 35 i = 70;    
 36 while(i--);//延时642us
 37 DSPORT = 1;    //然后拉高总线,如果DS18B20做出反应会将在15us~60us后总线拉低
 38 i = 0;
 39 while(DSPORT)    //等待DS18B20拉低总线
 40 {
 41 Delay1ms(1); //这里的延时必须要大于480uS 
 42 i++;
 43 if(i>5)//等待>5MS
 44 {
 45 return 0;//初始化失败
 46 }
 47 
 48 }
 49 return 1;//初始化成功
 50 }
 51 
 52 /*******************************************************************************
 53 * 函 数 名 : Ds18b20WriteByte
 54 * 函数功能    : 向18B20写入一个字节
 55 * 输 入 : 无
 56 * 输 出 : 无
 57 *******************************************************************************/
 58 
 59 void Ds18b20WriteByte(uchar dat)
 60 {
 61 uint i, j;
 62 
 63 for(j=0; j<8; j++)
 64 {
 65 DSPORT = 0;    //每写入一位数据之前先把总线拉低1us
 66 i++;
 67 DSPORT = dat & 0x01; //然后写入一个数据,从最低位开始
 68 i=6;
 69 while(i--); //延时68us,持续时间最少60us
 70 DSPORT = 1;    //然后释放总线,至少1us给总线恢复时间才能接着写入第二个数值
 71 dat >>= 1;
 72 }
 73 }
 74 /*******************************************************************************
 75 * 函 数 名 : Ds18b20ReadByte
 76 * 函数功能    : 读取一个字节
 77 * 输 入 : 无
 78 * 输 出 : 无
 79 *******************************************************************************/
 80 
 81 
 82 uchar Ds18b20ReadByte()
 83 {
 84 uchar byte, bi;
 85 uint i, j;    
 86 for(j=8; j>0; j--)
 87 {
 88 DSPORT = 0;//先将总线拉低1us
 89 i++;
 90 DSPORT = 1;//然后释放总线
 91 i++;
 92 i++;//延时6us等待数据稳定
 93 bi = DSPORT;    //读取数据,从最低位开始读取
 94 /*将byte左移一位,然后与上右移7位后的bi,注意移动之后移掉那位补0。*/
 95 byte = (byte >> 1) | (bi << 7);    //byte首先为0, 若bi=1时, 左移7位 则 1000 0000,和byte=0000 0000相或,则byte为 1000 0000;当DSPORT下一位过来时,假设为1时,则之前byte=1000 0000右移一位之后为byte =0100 0000,bi=1,左移七位,则bi=1000 0000和byte相或为1100 0000依次传输完8位
 96 i = 4;    //读取完之后等待48us再接着读取下一个数
 97 while(i--);
 98 }    
 99 return byte;
100 }
101 /*******************************************************************************
102 * 函 数 名 : Ds18b20ChangTemp
103 * 函数功能    : 让18b20开始转换温度
104 * 输 入 : 无
105 * 输 出 : 无
106 *******************************************************************************/
107 
108 void Ds18b20ChangTemp()
109 {
110 Ds18b20Init();
111 Delay1ms(1);
112 Ds18b20WriteByte(0xcc);    //跳过ROM操作命令    
113 Ds18b20WriteByte(0x44);    //温度转换命令 按理说要加750mS的延时,如果不加就会出现闪烁
114 //Delay1ms(100);    //等待转换成功,而如果你是一直刷着的话,就不用这个延时了
115 
116 }
117 /*******************************************************************************
118 * 函 数 名 : Ds18b20ReadTempCom
119 * 函数功能    : 发送读取温度命令
120 * 输 入 : 无
121 * 输 出 : 无
122 *******************************************************************************/
123 
124 void Ds18b20ReadTempCom()
125 {
126 
127 Ds18b20Init();
128 Delay1ms(1);
129 Ds18b20WriteByte(0xcc);    //跳过ROM操作命令
130 Ds18b20WriteByte(0xbe);    //发送读取温度命令
131 }
132 /*******************************************************************************
133 * 函 数 名 : Ds18b20ReadTemp
134 * 函数功能    : 读取温度
135 * 输 入 : 无
136 * 输 出 : 无
137 *******************************************************************************/
138 
139 int Ds18b20ReadTemp()
140 {
141 int temp = 0;
142 uchar tmh, tml;
143 Ds18b20ChangTemp();    //先写入转换命令
144 Ds18b20ReadTempCom();    //然后等待转换完后发送读取温度命令
145 tml = Ds18b20ReadByte();    //读取温度值共16位,先读低字节
146 tmh = Ds18b20ReadByte();    //再读高字节
147 temp = tmh;
148 temp <<= 8;
149 temp |= tml;
150 return temp;
151 }
152 
153  
154 
155 /**************************************************************************************
156 *    DS18B20温度传感器实验    *
157 实现现象:下载程序后,在温度传感器接口处,按照丝印方向插好温度传感器,数码管就会显示
158 检测的温度值,
159 注意事项:    
160 ***************************************************************************************/
161 
162 #include "reg52.h"    //此文件中定义了单片机的一些特殊功能寄存器
163 #include"temp.h"
164 
165 typedef unsigned int u16;    //对数据类型进行声明定义
166 typedef unsigned char u8;
167 
168 sbit LSA=P2^2;
169 sbit LSB=P2^3;
170 sbit LSC=P2^4;
171 
172 
173 char num=0;
174 u8 DisplayData[8];
175 u8 code smgduan[10]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f};
176 
177 /*******************************************************************************
178 * 函 数 名 : delay
179 * 函数功能    : 延时函数,i=1时,大约延时10us
180 *******************************************************************************/
181 void delay(u16 i)
182 {
183 while(i--);    
184 }
185 
186 
187 /*******************************************************************************
188 * 函 数 名 : datapros()
189 * 函数功能    : 温度读取处理转换函数
190 * 输 入 : temp
191 * 输 出 : 无
192 *******************************************************************************/
193 
194 void datapros(int temp) 
195 {
196 float tp; 
197 if(temp< 0)    //当温度值为负数
198 {
199 DisplayData[0] = 0x40; // - 表示“-”号
200 //因为读取的温度是实际温度的补码,所以减1,再取反求出原码
201 temp=temp-1;
202 temp=~temp;
203 tp=temp; 
204 temp=tp*0.0625*100+0.5;    //*100是为了放大100倍,去掉后面的两个小数
205 //留两个小数点就*100,+0.5是四舍五入,因为C语言浮点数转换为整型的时候把小数点
206 //后面的数自动去掉,不管是否大于0.5,而+0.5之后大于0.5的就是进1了,小于0.5的就
207 //算加上0.5,还是在小数点后面。
208 
209 }
210 else
211 {    
212 DisplayData[0] = 0x00;
213 tp=temp;//因为数据处理有小数点所以将温度赋给一个浮点型变量
214 //如果温度是正的那么,那么正数的原码就是补码它本身
215 temp=tp*0.0625*100+0.5;    
216 //留两个小数点就*100,+0.5是四舍五入,因为C语言浮点数转换为整型的时候把小数点
217 //后面的数自动去掉,不管是否大于0.5,而+0.5之后大于0.5的就是进1了,小于0.5的就
218 //算加上0.5,还是在小数点后面。
219 }
220 DisplayData[1] = smgduan[temp / 10000]; //因为温度在-50——125之间,这是三位,后面有*100,所以变成了五位了
221 DisplayData[2] = smgduan[temp % 10000 / 1000];
222 DisplayData[3] = smgduan[temp % 1000 / 100] | 0x80;//为了让个位数码管的小数点也亮
223 DisplayData[4] = smgduan[temp % 100 / 10];//小数点倒数第二位 
224 DisplayData[5] = smgduan[temp % 10];//小数点最后一位
225 }
226 
227 
228 /*******************************************************************************
229 * 函数名 :DigDisplay()
230 * 函数功能    :数码管显示函数
231 * 输入 : 无
232 * 输出 : 无
233 *******************************************************************************/
234 void DigDisplay()
235 {
236 u8 i;
237 for(i=0;i<6;i++)
238 {
239 switch(i)    //位选,选择点亮的数码管,
240 {
241 case(0):
242 LSA=0;LSB=0;LSC=0; break;//显示第0位
243 case(1):
244 LSA=1;LSB=0;LSC=0; break;//显示第1位
245 case(2):
246 LSA=0;LSB=1;LSC=0; break;//显示第2位
247 case(3):
248 LSA=1;LSB=1;LSC=0; break;//显示第3位
249 case(4):
250 LSA=0;LSB=0;LSC=1; break;//显示第4位
251 case(5):
252 LSA=1;LSB=0;LSC=1; break;//显示第5位    
253 }
254 P0=DisplayData[5-i];//发送数据
255 delay(100); //间隔一段时间扫描    
256 P0=0x00;//消隐
257 }    
258 }
259 
260 /*******************************************************************************
261 * 函 数 名 : main
262 * 函数功能    : 主函数
263 * 输 入 : 无
264 * 输 出 : 无
265 *******************************************************************************/
266 void main()
267 {    
268 while(1)
269 {
270 datapros(Ds18b20ReadTemp());    //数据处理函数
271 DigDisplay();//数码管显示函数    
272 }    
273 }
274 
275  
276 
277 #ifndef __TEMP_H_
278 #define __TEMP_H_
279 
280 #include<reg52.h>
281 //---重定义关键词---//
282 #ifndef uchar
283 #define uchar unsigned char
284 #endif
285 
286 #ifndef uint 
287 #define uint unsigned int
288 #endif
289 
290 //--定义使用的IO口--//
291 sbit DSPORT=P3^7;
292 
293 //--声明全局函数--//
294 void Delay1ms(uint );
295 uchar Ds18b20Init();
296 void Ds18b20WriteByte(uchar com);
297 uchar Ds18b20ReadByte();
298 void Ds18b20ChangTemp();
299 void Ds18b20ReadTempCom();
300 int Ds18b20ReadTemp();
301 
302 #endif
原文地址:https://www.cnblogs.com/wises/p/9539445.html