文章参考资料
http://www.51hei.com/bbs/dpj-91394-1.html (基于DS18B20温度传感器温控系统的Proteus仿真)
https://wenku.baidu.com/view/662b48eda0116c175e0e4857.html (LCD1602液晶显示完全资料)
https://max.book118.com/html/2017/0609/112708606.shtm (单片机与液晶显示器的接口)

一、实验目的

1.了解温度传感器DS18B20原理
2.了解液晶显示器的工作原理
3.学会DS18B20温度传感器数码管显示
4.学会DS18B20温度传感器液晶显示.


二、实验原理

DS18B20 传感器具有以下一些特性:
(1) 测温范围-55℃至+125℃,在-10℃至+85℃时的精度为正负 0.5℃; (2) 适应电压的范围在 3.0 至 5.5V;
(3) 单线接口,只用一条口线就可以与微处理器的双向通信;
(4) 支持多点组网,多个 DS18B20 并接在一根口线上就可实现多点测温;
(5) 测量结果直接输出数字温度信号,通过单线串行传输给微处理器;
(6) 具有负压特性,电源极性接反芯片不会烧坏,只是不能正常工作;
(7) 可编程分辨率为 9 至 12 位,对应的分辨温度分别是 0.5℃,0.25℃,0.125℃,
0.0625℃,能够实现高精度测温。
(8) 在 9 位分辨率时可在 93.75ms 内把温度值转换为数字;在 12 位分辨率时可在
750us 内把温度值转换为数字;
(9) 传送数据时可传送 CRC 校验码,抗干扰纠错能力强

DQ 端外接一个上拉电阻,与处理器的任一端口连接

DS18B20控制命令.

33H——读ROM(读取温度传感器ROM中的编码)
55H——匹配ROM(发出该指令后,再发64位ROM编码,用于匹配相应的DS18B20)
F0H——搜索ROM用于确定挂接在同一总线上DS18B20的数量(DS18B20支持多点组网)
CCH——跳过ROM,忽略64位ROM地址,直接向DS18B20发温度变换命令
ECH——告警搜索命令,执行后只有温度超过设定值的上下限才做出响应.
44H——温度转换,启动DS18B20进行温度转换
BEH——读温度暂存器,读内部RAM中9字节的温度数据
4EH——写暂存器.

主机与单个 DS18B20 连接时,不需要读取或者匹配 ROM,只要使用跳过指令 CCH,就可以进行数据转换和读取操作。


工作时序图


Step1:数据线置低电平
Step2:延时 800us 左右(时间范围为 480us 至 960us)
Step3:数据线拉高电平
Step4:延时 40us 左右(时间范围为 15us 至 60us)


逐位读取数据,然后把 8 位数据组成 1 个字节。编写程序时分为两个部分,一个实现读
取一位数据,另一个实现读取一个字节数据。
读取数据步骤
Step1:数据线置低电平
Step2:延时5us左右(大于1us)
Step3:数据线置高电平
Step4:延时10us(这次延时和第一次延时之和接近15us左右)
Step5:读取一位数据
Step6:延时60us左右(大于45us)
Step7:重复上面步骤,直到读完一个字节


写入数据分为写数据位1和数据位0
写数据1步骤:
Step1:数据线置低电平
Step2:延时5us左右(大于1us左右)
Step3:数据线置高电平
Step4:延时70us左右(大于55us即可)
写数据0步骤:
Step1:数据线置低电平
Step2:延时70us左右(大于60us左右)
Step3:数据线置高电平
Step4:延时5us左右

我们已经了解了温度传感器的工作方式,但如何从温度传感器读取数据显示到液晶上面来呢?这里虽然也可以用数码管显示,但相比数码管,液晶似乎更好一点,在此之前,我们必须先了解一下液晶的工作原理.


温度寄存器由两个字节组成,分为低8位和高8位。一共16位。
其中,第0位到第3位,存储的是温度值的小数部分。
第4位到第10位存储的是温度值的整数部分。
第11位到第15位为符号位。全0表示是正温度,全1表示是负温度。
表格中的数值,如果相应的位为1,表示存在。如果相应的位为0,表示不存在


液晶显示


LM016L的基本构造与引脚说明:
VSS-接地.
VDD-电源正极
VEE—液晶对比度调整端,接正电源时对比度最弱,接地电源时对比度最高,对比度过高时会产生“鬼影”,使用时可以通过一个10K的电位器调整对比度
RS—数据/命令选择—寄存器选择,高电平时选择数据寄存器、低电平时选择指令寄存器
RW—读写信号选择,高电平时进行读操作,低电平时进行写操作。当RS和RW共同为低电平时可以写入指令或者显示地址,当RS为低电平RW为高电平时可以读忙信号,当RS为高电平RW为低电平时可以写入数据。
E—使能信号;当E端由高电平跳变成低电平时,液晶模块执行命令。
D0~D7—8位双向数据口;


关于RW,RS的操作时序

在软件控制问题中,需要注意几个问题—基本问题:各时段的端口状态(电平)

  1. 液晶显示器的初始化—设置初始状态—置显示状态(电源、控制、数据端口等电平)

  2. 控制口RS/RW的控制指令变化—检测、延时、检测—发送数据问题(电平)

  3. 输出数据的获取与传递(读取/写入电平)

在编写 LCD1602 程序前,我们必须了解其手册上一些非常重要的
信息,如果这些信息不能理解透彻,编程可能会遇到或多或少的
问题.

指令集:

LCD_1602 初始化指令小结:

0x38 设置 162 显示,57 点阵,8 位数据接口
0x01 清屏
0x0F 开显示,显示光标,光标闪烁
0x08 只开显示
0x0e 开显示,显示光标,光标不闪烁
0x0c 开显示,不显示光标
0x06 地址加 1,当写入数据的时候光标右移
0x02 地址计数器 AC=0;(此时地址为 0x80) 光标归原点,但
是 DDRAM 中断内容不变

数据位如下


0x80是第一行的第一个字符,0x80+1是第一行第二个,0x80+0x40是第二行第一个地址
写入显示地址时,要求最高位D7恒为高电平,即1000 0000 + 0100 0000 = 0x80 + 0x40


三、实验器件

1.DS18B20温度传感器

2.共阴数码管7SEG

3.LM016L液晶显示


四、实验实现

数码管实现

#include <reg52.h>
unsigned char code seg7code[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f};
code unsigned char seg7codeB[]={0xbf,0x86,0xdb,0xcf,0xe6,0xed,0xfd,0x87,0xff,0xef,0x00}; //带小数点的共阴数码管段码sbit DQ=P3^5; //数据传输线接单片机的相应的引脚
unsigned char tempL=0;     //设全局变量
unsigned char tempH=0;
unsigned int sdata;     //测量到的温度的整数部分
unsigned char xiaoshu1; //小数第一位
unsigned char xiaoshu2; //小数第二位
unsigned char xiaoshu;  //两位小数
bit  fg=1;              //温度正负标志//******************延时子程序*******************************//这个延时程序的具体延时时间是time=i*8+10,适用于小于2ms的延时//************************************************************
void delay(unsigned char i)
{for(i;i>0;i--);
}//***********************************************************//                     延时子程序//************************************************************
void delay1ms(int n)
{unsigned char i;for(i=124*n;i>0;i--);  //延时124*8+10=1002us
}//*****************************初始化程序 *********************************//void Init_DS18B20(void)
{unsigned char x=0;DQ=1; //DQ先置高 delay(8); //稍延时DQ=0; //发送复位脉冲 delay(80); //延时(>480us) DQ=1; //拉高数据线 delay(5); //等待(15~60us) x=DQ; //用X的值来判断初始化有没有成功,18B20存在的话X=0,否则X=1 delay(20);
} //**********读一个字节************//ReadOneChar(void)  //主机数据线先从高拉至低电平1us以上,再使数据线升为高电平,从而产生读信号
{unsigned char i=0; //每个读周期最短的持续时间为60us,各个读周期之间必须有1us以上的高电平恢复期unsigned char dat=0; for (i=8;i>0;i--) //一个字节有8位 {DQ=1; delay(1); DQ=0;dat>>=1;        //数据移位DQ=1; if(DQ) dat|=0x80;     //得读取数据线得到一个状态delay(4);
}
return(dat);
} //*********************** **写一个字节**************************//void WriteOneChar(unsigned char dat)
{ unsigned char i=0; //数据线从高电平拉至低电平,产生写起始信号。15us之内将所需写的位送到数据线上,for(i=8;i>0;i--) //在15~60us之间对数据线进行采样,如果是高电平就写1,低写0发生。 {DQ=0; //在开始另一个写周期前必须有1us以上的高电平恢复期。 DQ=dat&0x01;  //按低位发送数据delay(5); DQ=1; dat>>=1;} delay(4);
} //读温度值(低位放tempL;高位放tempH;)
void ReadTemperature(void)
{ Init_DS18B20(); //初始化WriteOneChar(0xcc); //跳过读序列号的操作WriteOneChar(0x44); //启动温度转换delay(125); //转换需要一点时间,延时 Init_DS18B20(); //初始化WriteOneChar(0xcc); //跳过读序列号的操作 WriteOneChar(0xbe); //读温度寄存器(头两个值分别为温度的低位和高位) tempL=ReadOneChar(); //读出温度的低位LSBtempH=ReadOneChar(); //读出温度的高位MSB if(tempH>0x7f)      //最高位为1时温度是负{tempL=~tempL;         //补码转换,取反加一tempH=~tempH+1;       fg=0;      //读取温度为负时fg=0}sdata = tempL/16+tempH*16;      //整数部分xiaoshu1 = (tempL&0x0f)*10/16; //小数第一位xiaoshu2 = (tempL&0x0f)*100/16%10;//小数第二位xiaoshu=xiaoshu1*10+xiaoshu2; //小数两位
}//********************显示函数****************
void Led(unsigned int date)
{ /*困惑很久,之前有问题,现在没了.*/P1=0xfb;     //P1.0=0,选通第一位P0=seg7code[date/10];  //十位数,查表,输出delay1ms(1);P1=0xfd;     //P1.1=0,选通第二位,个位数P0=seg7codeB[date%10];delay1ms(1);P1=0xfe;     //P1.3=0,选通第三位,小数点第一位P0=seg7code[xiaoshu1];delay1ms(1);
}//**************************** //主程序
void main()
{   unsigned int i;while(1){ReadTemperature(); //读取温度 for(i=0;i<20;i++){Led(sdata);         //显示温度}}
}

LM016L实现

#include <reg52.h>
#define uchar unsigned char
#define uint unsigned int
sbit LCDEN = P2^0;
sbit LCDRW = P2^1;
sbit LCDRS = P2^2;
sbit LCDTP = P2^3;    //数据传输线接单片机的相应的引脚
unsigned char tempL=0;     //设全局变量
unsigned char tempH=0;
unsigned int sdata;     //测量到的温度的整数部分
unsigned char xiaoshu; //小数第一位
uchar code DisplayNums[] = "0123456789";
uchar code DisplayTips[] = "Temperature";//******************延时子程序*******************************//这个延时程序的具体延时时间是time=i*8+10,适用于小于2ms的延时//************************************************************
void delay(unsigned char i)
{for(i;i>0;i--);
}
void delay1ms(int n)
{unsigned char i;for(i=124*n;i>0;i--);  //延时124*8+10=1002us
}
/**********LCD部分******************/
void Write_Com(uchar Com){/*液晶写指令,对应操作*/LCDRS = 0;P0 = Com;delay1ms(5);LCDEN = 1;delay1ms(5);LCDEN = 0;delay1ms(5);
}
void Write_Data(uchar Data){/*液晶写数据*/LCDRS = 1;P0 = Data;delay1ms(5);LCDEN = 1;delay1ms(5);LCDEN = 0;delay1ms(5);
}
void Lcd_Init(){LCDEN = 0;LCDRW = 0;Write_Com(0x38);  //设置 16*2 显示,每个字符是5*7 点阵,8 位数据接口Write_Com(0x0c);    //开显示,不显示光标Write_Com(0x06);    //地址加 1,当写入数据的时候光标右移Write_Com(0x01);    //清屏,清楚之前的内容.
}
void Display_Temperature(uint Data){//Data转换成三位数//Data = 0x;uint Decade,Uint;Decade = Data/10;Uint = Data%10;/*  0x80是第一行的第一个字符,0x80+1是第一行第二个,0x80+0x40是第二行第一个地址写入显示地址时,要求最高位D7恒为高电平,即1000 0000 + 0100 0000 = 0x80 + 0x40单片机规定*/Write_Com(0x80+0x40+5); Write_Data(DisplayNums[Decade]);    //写入数据.Write_Data(DisplayNums[Uint]);Write_Data('.');Write_Data(DisplayNums[xiaoshu]);
}
void Display_Static_Temperature(){uchar i;Write_Com(0x80+3);for(i=0;i<10;i++){Write_Data(DisplayTips[i]);}Write_Com(0x80+0x40+10);Write_Data('^');   //°CWrite_Data('C');
}//*****************************初始化程序 *********************************//void Init_DS18B20(void)
{unsigned char x=0;LCDTP=1; //DQ先置高 delay(8); //稍延时LCDTP=0; //发送复位脉冲 delay(80); //延时(>480us) LCDTP=1; //拉高数据线 delay(5); //等待(15~60us) x=LCDTP; //用X的值来判断初始化有没有成功,18B20存在的话X=0,否则X=1 delay(20);
} //**********读一个字节************//ReadOneChar(void)  //主机数据线先从高拉至低电平1us以上,再使数据线升为高电平,从而产生读信号
{unsigned char i=0; //每个读周期最短的持续时间为60us,各个读周期之间必须有1us以上的高电平恢复期unsigned char dat=0; for (i=8;i>0;i--) //一个字节有8位 {LCDTP=1; delay(1); LCDTP=0;dat>>=1;      //数据移位LCDTP=1; if(LCDTP) dat|=0x80;       //得读取数据线得到一个状态delay(4);
}
return(dat);
} //*********************** **写一个字节**************************//void WriteOneChar(unsigned char dat)
{ unsigned char i=0; //数据线从高电平拉至低电平,产生写起始信号。15us之内将所需写的位送到数据线上,for(i=8;i>0;i--) //在15~60us之间对数据线进行采样,如果是高电平就写1,低写0发生。 {LCDTP=0; //在开始另一个写周期前必须有1us以上的高电平恢复期。 LCDTP=dat&0x01;  //按低位发送数据delay(5); LCDTP=1; dat>>=1;} delay(4);
} //读温度值(低位放tempL;高位放tempH;)
void ReadTemperature(void)
{ Init_DS18B20(); //初始化WriteOneChar(0xcc); //跳过读序列号的操作WriteOneChar(0x44); //启动温度转换delay(125); //转换需要一点时间,延时 Init_DS18B20(); //初始化WriteOneChar(0xcc); //跳过读序列号的操作 WriteOneChar(0xbe); //读温度寄存器(头两个值分别为温度的低位和高位) tempL=ReadOneChar(); //读出温度的低位LSBtempH=ReadOneChar(); //读出温度的高位MSB if(tempH>0x7f)      //最高位为1时温度是负{tempL=~tempL;         //补码转换,取反加一tempH=~tempH+1;       }sdata = tempL/16+tempH*16;      //整数部分xiaoshu = (tempL&0x0f)*10/16; //小数第一位
}//**************************** //主程序
void main()
{   unsigned int i;Lcd_Init();Display_Static_Temperature();while(1){ReadTemperature(); //读取温度for(i=0;i<20;i++){Display_Temperature(sdata);}}
}

为简化代码,下次改进会将源码上传至Github.

Proteus仿真-数码管显示温度(实验三)相关推荐

  1. Proteus仿真数字钟表电路实验报告(可下载工程文件)

    Proteus仿真数字钟表电路实验报告(可下载工程文件) 实验目的 实验器件 实验步骤 1. 选择合适的Proteus器件中的译码器和数值显示器件能够对4位二进制数进行正常的数值显示 2. 组成模值为 ...

  2. 仿真软件测试基尔霍夫定律,实验三 基尔霍夫定律的验证(仿真实验)

    产生的速度 实验三 基尔霍夫定律的验证(仿真实验) 一.实验目的 1. 验证基尔霍夫定律的正确性,加深对基尔霍夫定律的理解. 2. 学会使用电流表.电压表测量各支路电流和各元件电压的方法. 3. 学会 ...

  3. 1、Proteus仿真STM32流水灯实验例程、详细步骤。

    一.创建工程 (实验keil和proteus所用文件工程百度网盘链接,提取码为0f7c ,以下为链接:所用keil和proteus文件工程 ) 1.点击创建新工程,输入工程名.安装路径. 2.选择从选 ...

  4. 基于51单片机的波形发生器proteus仿真数码管LCD12864显示

    仿真图1简介: 本系统采用51单片机作为系统的MCU(具体型号见下图),该系统显示器为四位数码管,可实时显示波形的参数情况 可显示四种波形,分别是方波.正弦波.三角波.锯齿波. 该设计具有电压表功能, ...

  5. 基于51单片机的计算器 汇编语言 proteus仿真 数码管显示

    之前讲的计算器都是基于C语言的,接下来讲一下基于汇编语言的简易计算器. 硬件设计 显示器仍然是数码管,MCU是C51,支持整数部分的计算 仿真图: 程序设计 YJ EQU 50H ;结果存放 YJ1 ...

  6. 基于51单片机MPX4115的压力测量仪proteus仿真 数码管显示

    硬件设计 (末尾附文件) 总体设计方案 本次设计是基于8051单片机的测量与显示.利用传感器将压力转换为电信号后,在经过ADC0832的模数转换器经A/D转换后由单片机进行有效处理,然后用数码管进行显 ...

  7. proteus仿真数码管

    首先,针对于51单片机有以下概念 51单片机的IO口每个引脚的电流驱动百能力比较弱: ①拉电流:即单片机引脚置高电平时对外输度出的电流,不超过1毫安. ②灌电流:即单片机引脚置低电平时知对外吸收的电流 ...

  8. c语言编程TLC2543AD采集,TLC2543单片机程序 带Proteus仿真 电路原理图 AD转换实验

    #include sbit SDO=P3^0;                                                        //定义端口 sbit SDI=P3^1; ...

  9. 51单片机 Proteus仿真 数码管 万年历 电子时钟 阴历阳历 星期 DS1302 修改时间

    做了个比较叼的,数码管显示出年月日时分秒星期以及阴历的月份和日期. 按键可以修改年月日时分秒,星期几是根据年月日计算的,阴历也是计算出来的,不用按键修改.

最新文章

  1. macos big sur升级失败_【王牌出击】升级欲望更为强烈 斯旺西有望反客为主
  2. 光纤转CAN总线在消防报警主机联网中的应用
  3. Quartz使用总结、Cron表达式
  4. 使用dex2jar和luyten查看apk中的class代码
  5. oracle的merge into
  6. io hang linux 原理,Linux 避免IO hang
  7. eap方法 华为手机怎么连wifi_如何手动连接802.1x EAP证书加密WIFI
  8. 前端学HTTP之客户端识别和cookie
  9. 中国近代史自考必备简答题(一)
  10. c语言做一个体育教学软件,深度学习下的体育教学
  11. 推荐一个好组件Javascript文本比较工具
  12. 蓝雪花怎么养 蓝雪花养殖方法及注意事项
  13. Phalcon PHP 中文,Phalcon 入门
  14. 深信服各种设备管理地址
  15. 原创故事 - 不死鸡和不死牛的故事
  16. 孢子社群:今日推荐ARVR微信群:云贵川渝ARVR行业精英交流群 孢子91
  17. android之java程序性能优化(不断补充)
  18. 华为linux笔记本i3和i7的区别,华为MateBook 13 i3版性能如何 华为MateBook 13 i3版笔记本上手体验...
  19. 渐变的alert_模仿新浪邮箱的alert渐变的提示框
  20. linux下查看gaussian结构,察看Gaussian全部IOp的方法

热门文章

  1. 解决 Ubuntu upgrade 常见错误 W: Possible missing firmware /lib/firmware/rtl_nic/rtl8125a-3.fw
  2. linux -- patch补丁文件以及相关内容
  3. Exploring Simple Siamese Representation Learning论文笔记
  4. Vue——10 - webpack打包保姆级教程01——打包js、json、css、less、html、背景图片以及图片、字体(Font)文件,devsever,生产环境配置以及css的兼容写法
  5. 数据透视表的使用总结
  6. java宅急送下载_基于jsp的宅急送物流管理系统-JavaEE实现宅急送物流管理系统 - java项目源码...
  7. 解决Firefox无法下载插件
  8. WinAPI键盘输入消息
  9. 在react中使用百度地图
  10. WPS通配符(正则表达式)