第八课 温度检测DS18B20实验准备:DS18B20 LCD1602 课程内容:一、 模块分析:仅一条总线,既用于传命令,又用于传数据。 单总线的所有处理均从初始化开始。 1) 初始化t0时刻总线拉高,然后即把总线(P37)电平拉低(给0),延时480—960微秒然后把总线拉高(给1),延时480微秒 (在这480微秒时间内DS18B20会响应,单模块可以忽略,多模块才需要判断) 如果要判断DS18B20是否存在,可以先延时100微秒,判断总线电平是否为0然后再继续延时380微秒 3)写入 基本数据 0 与 1 的判断写0时序:t0总线先拉高再拉低,延时>60微秒, 然后总线拉高,延时>1微秒 写1时序:t0总线先拉高再拉低,延时4微秒, 然后总线拉高,延时>60微秒 4)读数据t0时刻总线拉高,再拉低,延时4微秒,再拉高,延时10秒,准备收数据。 然后,接收总线数据(即判断 总线 是 0 或 1,这是由DS18B20送出的)。 延时50微秒,总线拉高。 5)传数据,字节传送时,先传送低位一、 分功能块编代码,可放入 function.h中sbit D18B20=P3^7; //ds18b20 端口 //TempDelay(80); //530uS //TempDelay(14); //100uS //_nop_(); //1.085uS(11.0529M) 1us(12M) //可用 KEIL调试模式检测 //http://blog.sina.com.cn/s/blog_980e19e00101b5dh.html void TempDelay (uchar us) //延时处理 { while(us--); } void Init18b20 (void) //18B20初始化 { D18B20=1; D18B20=0; TempDelay(80); //delay 530 uS//80 D18B20=1; TempDelay(34); //delay 480 uS//70 D18B20 = 1; } void write_byte (uchar dat) //18B20写入一个字节 { uchar i; for (i=0;i<> { D18B20 = 0; _nop_(); //用空指令延时 D18B20=dat&0x01; //取出最低位放入总线 TempDelay(5); //delay 45 uS //5 D18B20=1; dat>>= 1; //准备下一位数据 } } //说明 一次1bit的读取最少需要60us 两次读取之间需要至少1us的恢复时间 // 单次读取1bit 总线拉低不能超过15us 然后马上拉高 uchar read_byte (void) //读18B20的一个字节 { uchar i,u=0; for(i=0;i<> { D18B20 = 0; u >>= 1; //右移,腾出左边的一位存数,同时有延时效果 D18B20 = 1; if(D18B20==1) u |= 0x80; //存入 数据 TempDelay (4); } return(u); } //读出温度函数 //返回为温度值 温度值为short变量 有正负 short read_temp() //short可以表示-32768~+32767 { uchar TL,TH; uchar temp; short t; Init18b20 (); //总线复位 write_byte(0xcc); //发命令 write_byte(0x44); //发转换命令 Init18b20(); //复位 write_byte(0xcc); //发命令 write_byte(0xbe); //发送读温度命令 TL=read_byte(); //读温度值的低字节 TH=read_byte(); //读温度值的高字节 t=TH; if(TH>7) { TH=~TH; TL=~TL; temp=0;//温度为负 }else temp=1; t<> t+=TL; // 两字节合成一个整型变量。 t=(float)t*0.0625; //0.0625为12位温度采集的分辨率 t为采集的数值 这里扩大10倍提取小数点后一位 if(temp)return t; else return -t; } LCD1602 显示温度时,要先判断正负,负的要显示 – 号,实现以上代码段后,主程序就简单了,当然,简单的背后还有前几节课的支撑。 void main() { short temp; lcd_init(); // 1602初始化 lcd_ wcmd (0x80); //设置显示位置为第一行的第1个字符 while(1) { lcd_ wcmd (0x80); temp =read_temp(); lcd_wdat(temp %10000/1000+0x30); lcd_wdat(temp %1000/100+0x30); lcd_wdat(temp %100/10+0x30); lcd_wdat(temp %10+0x30); } } 后记:自这课之后,基本可以使用不同的器件玩下开发了,例如加液晶屏,时钟控制等. 各种器件,一般都附带有厂家的例程或者能从网上找到例程.只要仔细分析时序图,把例程中代码"搬运"一下到自己的代码中,略加修改,即可用,不需要重复花时间去开发对应驱动,这就是平常所讲的不要重复造"轮子". 编程思想,并不是把所有代码放一堆在一个文件中,而是把想实现的功能细分为简单的功能模块(用各个 .h头文件 #include作关联调用),然后专心设计每一个简单模块,这是C语言开发软件常用的一种模式. 另外.并不是跟着教程学会了基本的编程与几个器件的使用,就表示会了单片机开发了,只有当自己能够独立完成一个完整的系统,例如 洞洞板+液晶+时钟+蜂鸣器+本课的温度器件,动手焊接线路,构造一个完整的代码结构和模块化编程,实现整点报时及报室温,再想牛点的话,排上几个LED点阵,模拟指针时钟特效,等等.当一个完整的系统是自己一点一点建成后,可以向人展示成品时,也就入门了. 再之后,可以玩点步进电机,超声波,红外,数模转换,无线传送,3寸或5寸屏液晶汉字显示,控制家电,控制PC,... ... |
|