找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 2415|回复: 0
收起左侧

基于51单片机LCD1602显示DS18B20测温的项目工程

[复制链接]
ID:171036 发表于 2020-5-14 19:29 | 显示全部楼层 |阅读模式
  1. #include<reg52.h>//包含51单片机内部寄存器头文件
  2. #define uchar unsigned char // 自定义uchar为unsigned char(即无符号字符型数据,数据范围:0到255。)
  3. #define uint unsigned int//自定义uint为unsigned int(即无符号字符整数型数据,数据范围:0到6355。)         
  4. sbit RS=P2^0;//位定义LCD1602字符型液晶显示器的数据/命令选择引脚                 
  5. sbit RW=P2^1;//位定义LCD1602字符型液晶显示器的读写引脚                        
  6. sbit EN=P2^2; //位定义LCD1602字符型液晶显示器的使能引脚
  7. sbit DQ=P1^4;//位定义DS18B20数据端口
  8. uint temperature,t;//读温度值变量
  9. uint temperatureflag;//负温度标志位变量                                 //DS18B20数据信号端口
  10. uint wendu,wendubai,wendushi,wenduge,xiaoshudian,xiaoshu,fuhaowei;//温度值变量、温度百位变量、温度十位变量、温度个位变量、小数点变量、符号位变量、
  11. uchar code table[]="Welcome To";                  
  12. uchar code table1[]="Our System !";              
  13. uchar code table2[]="temperature is:";   
  14.   void Delay(uint z)//延时程序
  15. {
  16.    uint x,y;
  17.    for(x=z;x>0;x--)
  18.     for(y=110;y>0;y--);
  19. }
  20.   void WriteCommand(uchar command)//LCD1602字符型液晶显示器写指令函数
  21. {
  22.    RS=0;//LCD1602字符型液晶显示器指令寄存器低电平
  23.    RW=0;//LCD1602字符型液晶显示器写指令操作低电平
  24.    P0=command;//LCD1602字符型液晶显示器写指令函数写指令到单片机P2组端口,再输送到LCD1602字符型液晶显示器指令寄存器中执行。
  25.    Delay(5);//实际单片机演示,可以去掉延时。Proteus 仿真,需要保留延时。
  26.    EN=1;//LCD1602字符型液晶显示器使能端高电平  
  27.    Delay(5);//实际单片机演示,可以去掉延时。Proteus 仿真,需要保留延时。
  28.    EN=0;//LCD1602字符型液晶显示器使能端低电平
  29. }
  30.   void WriteData(uchar information)//LCD1602字符型液晶显示器写数据函数
  31. {  
  32.    RS=1;//LCD1602字符型液晶显示器数据寄存器高电平
  33.    RW=0;//LCD1602字符型液晶显示器写数据操作低电平
  34.    P0=information;//LCD1602字符型液晶显示器写数据函数写数据到单片机P2组端口,再输送到LCD1602字符型液晶显示器上显示。
  35.    Delay(5);//实际单片机演示,可以去掉延时。Proteus 仿真,需要保留延时。
  36.    EN=1;//LCD1602字符型液晶显示器使能端高电平
  37.    Delay(5);//实际单片机演示,可以去掉延时。Proteus 仿真,需要保留延时。
  38.    EN=0;//LCD1602字符型液晶显示器使能端低电平
  39. }
  40.   void LCD1602Init()//LCD1602初始化函数
  41. {
  42.    WriteCommand(0x38);//设置LCD1602字符型液晶显示器16x2显示,5*7或5*8点阵,8位数据并口,简称显模。
  43.    WriteCommand(0x08);//设置LCD1602字符型液晶显示器显示开,简称亮屏。
  44.    WriteCommand(0x01);//设置清除LCD1602字符型液晶显示器屏上所有内容,并让光标复位到LCD1602字符型液晶显示器屏左上角,简称清屏。
  45.    WriteCommand(0x06);//设置开光标(或字符)地址指针自增1,光标右移动一个字符位,整屏显示不移动。
  46.    WriteCommand(0x0c);//设置开LCD1602字符型液晶显示器显示,关光标,关光标(字符)闪烁。
  47. }
  48.   void LCD1602Display()//LCD1602字符型液晶显示器显示函数
  49. {
  50.    uchar j;//j表示数组元素个数变量
  51.    WriteCommand(0x80+0x00);//LCD1602字符型液晶显示器第一行第一个位置显示
  52.    for(j=0;j<10;j++)//有10个字符,要循环10次。
  53.   {
  54.     WriteData(table[j]);//显示字符串
  55.     Delay(5);
  56.    }
  57.    WriteCommand(0x80+0x40);//LCD1602字符型液晶显示器第二行第一个位置显示
  58.    for(j=0;j<11;j++)//有8个字符,要循环8次。
  59.   {
  60.     WriteData(table1[j]);//显示字符串
  61.     Delay(5);
  62.    }
  63. }
  64.   void DS18B20_Delay(uint i)//微妙级延时函数
  65. {
  66.    while(i--);
  67. }
  68. //  void FengNingQi_Alarm()//蜂鸣器报警函数
  69. //{
  70. //   uint x;
  71. //   uint y;
  72. //   uint t;
  73. //   for(x=0;x<t;x++)
  74. //  {
  75. //    for(y=0;y<50;y++);
  76. //    FengNingQi=~FengNingQi;//蜂鸣器按位取反FengNingQi
  77. //   }
  78. // }
  79.   bit DS18B20Init()//DS18B20初始化函数
  80. {
  81.    uchar x=0;
  82.    DQ = 1;//单片机将DS18B20通信端口DQ拉高复位  
  83.    DS18B20_Delay(8);//稍做延时
  84.    DQ = 0;//单片机将DS18B20通信端口DQ拉低
  85.    DS18B20_Delay(80);//延时在480us与960us之间
  86.    DQ = 1;//单片机将DS18B20通信端口DQ拉高
  87.    DS18B20_Delay(4);//延时在15us与60us之间
  88.    x=DQ;//稍做延时后,如果x=0,则初始化成功,若x=1则初始化失败。
  89.    DS18B20_Delay(20);//延时在60us与240us之间
  90.    return x;
  91. }
  92.   void DS18B20_WriteOneByte(uchar j)//DS18b20写一个字节函数
  93. {
  94.    uchar i=0;
  95.    for (i=8; i>0; i--)//单片机向DS18B20写入数据
  96.   {
  97.     DQ = 0;//单片机将DS18B20通信端口DQ从高电平拉至低电平时,单片机向DS18B20写数据开始。
  98.     DQ = j&0x01;//单片机按将字节低位写入DS18B20
  99.     DS18B20_Delay(5);//延时在60us与120us之间
  100.     DQ = 1;//单片机将DS18B20通信端口DQ拉高
  101.     j>>=1;//变量j右移一位,最高位补零。例如当j=1,换成二进制是0000 0001,右移一位就是0000 000。扩展:单片机无符号或有符号数左移几位,高位就依次补几位0,低位也依次去掉几位,让左移几位依次代替低位去掉的几位。单片机有符号数,如果是正数,右移几位,先是确定最高位用0,低位也依次去掉几位,让右移几位依次代替低位去掉的几位,如果是负数,右移几位,先是确定最高位用1,低位也依次去掉几位,让右移几位依次代替低位去掉的几位。      
  102.    }
  103. }
  104.   uchar DS18B20_ReadOneByte()//DS18B20读一个字节函数
  105. {
  106.    uchar i=0;
  107.    uchar j = 0;
  108.    for (i=8;i>0;i--)//单片机读取DS18B20采集的温度数据转换成一个字节
  109.   {
  110.     DQ = 0;//单片机将DS18B20通信端口DQ从高电平拉成低电平时,单片机读取DS18B20所采集到温度数据开始。
  111.     j>>=1;//变量j右移一位,最高位补零。例如当j=1,换成二进制是0000 0001,右移一位就是0000 000。扩展:单片机无符号或有符号数左移几位,高位就依次补几位0,低位也依次去掉几位,让左移几位依次代替低位去掉的几位。单片机有符号数,如果是正数,右移几位,先是确定最高位用0,低位也依次去掉几位,让右移几位依次代替低位去掉的几位,如果是负数,右移几位,先是确定最高位用1,低位也依次去掉几位,让右移几位依次代替低位去掉的几位。
  112.     DQ = 1;//单片机将DS18B20通信端口DQ拉高
  113.     if(DQ)//判断DQ是否等于1
  114.     j|=0x80;//若DQ=1,则让当前j最高位为1,在下次循环中移位至次高位,最后达到从低位到高位接收的目的;若DQ=0,则可跳过此语句,直接在下次循环对byte进行移位补0。  
  115.     DS18B20_Delay(4);//稍做延时
  116.   }
  117.    return j;
  118. }
  119.   uint DS18B20_ReadTemperature()//单片机读取DS18b20当前温度
  120. {
  121.    uchar L=0;//定义温度值低8位变量
  122.    uchar H=0;//定义温度值高8位变量   
  123.    DS18B20Init( );//DS18B20初始化函数
  124.    DS18B20_WriteOneByte(0xcc);//单片机只连一个DS18B20温度传感器时,可写该段代码,表示单片机向DS18B20写入跳过读DS18B20序号列号指令。
  125.    DS18B20_WriteOneByte(0x44);//单片机向DS18B20九字节暂存器(包括两个字节储温温度寄存器、一字节高温触发器、一字节低温触发器、一字节温度精度转换配置寄存器、三个字节的保留位、一字节DS18B20的64位ROM前56位编码校验CRC发生器)中前两个字节温度寄存器写入启动DS18B20温度转换指令
  126. // DS18B20_Delay(100);//稍作延时
  127.    DS18B20Init( );//DS18B20初始化函数
  128.    DS18B20_WriteOneByte(0xcc);//单片机只连一个DS18B20温度传感器时,可写该段代码,表示单片机向DS18B20写入跳过读DS18B20序号列号指令。
  129.    DS18B20_WriteOneByte(0xbe);//单片机向DS18B20九字节暂存器(包括两个字节储温温度寄存器、一字节高温触发器、一字节低温触发器、一字节温度精度转换配置寄存器、三个字节的保留位、一字节DS18B20的64位ROM前56位编码校验CRC发生器)中前两个字节温度寄存器写入读取温度的指令
  130. // DS18B20_Delay(100);//稍作延时
  131.    L=DS18B20_ReadOneByte( );//单片机向DS18B20发送读取温度值低8位指令,把读到的温度值低8位赋给温度值低8位变量
  132.    H=DS18B20_ReadOneByte( );//单片机向DS18B20发送读取温度值高8位指令,把读到的温度值高8位赋给温度值高8位变量
  133.    temperature = H;//DS18B20读到的温度值高8位赋给温度值变量,变成高8位温度值变量,还不是一个温度值变量,由于一个温度值变量是由高8位低8位共16位组成。
  134.    temperature = temperature << 8;//温度值高8位变量左移8位,就可以变成一个只有高8位低8位全0的温度值变量。
  135.    temperature = temperature | L;//只有高8位低8位全0的温度值变量与温度值低8位变量或运算后就变成一个真正有高8位低8位共16位的温度值变量
  136.    if(temperature>0x0fff)//判断表示温度寄存器16位二进制数的温度值变量是否大于表示温度寄存器16位二进制数的正温度值,假若大于且当表示温度寄存器16位二进制数的温度值变量的前5位二进制数全为1时,该温度值变量表示负温度值。
  137.   {
  138.     temperature = ~temperature+2;//负温度值
  139.     temperatureflag=1;//负温度标志变量等于1
  140.    }
  141.    else
  142.   {      
  143.     temperatureflag=0;//负温度标志变量等于0
  144.    }
  145.    temperature = temperature*0.0625*10;//扩大10倍的温度值
  146.    return temperature;//返回扩大10倍的温度值
  147.      
  148. }
  149.   void TemperatureFenJie()//LCD1602的温度显示函数   
  150. {
  151.    wendu=DS18B20_ReadTemperature();//DS18B20读到的温度值赋给温度值变量
  152.    if(temperatureflag==1)//判断负温度标志变量是否等于1
  153.   {   
  154.     fuhaowei=0x2d;//负符号
  155.     wendubai=wendu/1000;//温度值百位
  156.     wendushi=wendu%1000/100;//温度值十位
  157.     wenduge=wendu%100/10;//温度值个位
  158.     xiaoshudian=0x2e;//小数点
  159.     xiaoshu=wendu%10;//小数位
  160.    }
  161.    else
  162.   {
  163.     fuhaowei=0x2b;//正符号
  164.     if(wendu==0)//判断温度是否等于0
  165.    {
  166.      fuhaowei=0x20;//无符号
  167.     }
  168.     wendubai=wendu/1000;//温度值百位
  169.     wendushi=wendu%1000/100;//温度值十位
  170.     wenduge=wendu%100/10;//温度值个位
  171.     xiaoshudian=0x2e;//小数点
  172.     xiaoshu=wendu%10;//小数位
  173.    }         
  174. }
  175.   void TemperatureDisplay()//LCD1602的温度显示函数   
  176. {
  177.    WriteCommand(0x80+0x40);//LCD1602字符型液晶显示器第二行第九个(从第零开始数)显示位
  178.    WriteData(fuhaowei);//符号位显示。
  179.    WriteData(0x30+wendubai);//0x30表示字符库的数字0,整个代码表示温度值百位可显示0到9的数字。
  180.    WriteData(0x30+wendushi);//0x30表示字符库的数字0,整个代码表示温度值十位可显示0到9的数字。
  181.    WriteData(0x30+wenduge);//0x30表示字符库的数字0,整个代码表示温度值个位可显示0到9的数字。
  182.    WriteData(xiaoshudian);//小数点
  183.    WriteData(0x30+xiaoshu);//0x30表示字符库的数字0,整个代码表示小数位可显示0到9的数字。
  184.    WriteData(0xdf);//0xdf表示字符库中摄氏度左上角的符号   
  185.    WriteData(0x43);//0x43表示字符库中大写字母C
  186. }
  187.   void main()                                 //主函数
  188. {
  189.    uchar num;
  190.    LCD1602Init();//LCD1602字符型液晶显示器初始化函数
  191.    LCD1602Display();//LCD1602字符型液晶显示器显示函数
  192.    Delay(500);
  193.    WriteCommand(0x01);          //清除LCD1602显示的内容
  194.    DS18B20Init();//DS18B20初始化函数
  195.    while(1)
  196. {
  197.     WriteCommand(0x80+0x00);//把LCD1602写进来的字符显示地址设为从0x80H(即00H)的上排第一位开始写
  198.     for(num=0;num<15;num++)//将table2[]中的字符依次写入LCD1602的第一排
  199.    {
  200.      WriteData(table2[num]);
  201.      Delay(5);
  202.     }
  203.     TemperatureFenJie();//温度分解函数
  204.     TemperatureDisplay();//温度显示函数
  205.   }
  206. }
复制代码
图片113.png
图片114.png

图片115.png

评分

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

查看全部评分

回复

使用道具 举报

无效楼层,该帖已经被删除
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

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

Powered by 单片机教程网

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