找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 6091|回复: 1
收起左侧

LCD1602显示DS18B20正温度值的单片机源码

[复制链接]
ID:297159 发表于 2018-8-2 18:52 | 显示全部楼层 |阅读模式
电路原理图如下:
LCD602显示DS18B20温度值proteus仿真.PNG
采用11.0592Mhz晶振,stc89c52芯片实时LCD602实时显示DS18B20温度值.
主程序
#include"ds18b20.h"
#include"lcd1602.h"
void main()
{

    uint i;                 
    uchar  L,M;
    uchar display[3];
    ds_init();

    write_byte(0xcc);//发送跳跃ROM指令
        write_byte(0x4e);//写暂存器指令
        write_byte(0x7f);
        write_byte(0xf7);
        write_byte(0x7f);//配置工作在12位模式下

        ds_init();       //初始化DS18B20
        write_byte(0xcc);//发送跳跃ROM指令
        write_byte(0x48);//写入EEPROM

    LCD_init();      //lcd初始化
while(1)
        {
        ds_init();       //初始化DS18B20
        
    write_byte(0xcc);//发送跳跃ROM指令
        write_byte(0x44);//发送温度转换指令
        Delay_Ms(1);
        ds_init();       //初始化DS18B20
        write_byte(0xcc);//发送跳跃ROM指令
        write_byte(0xbe);//读取DS18B20暂存器值

        L = read_byte(); //L
        M = read_byte(); //H

                i = M;
                i <<= 8;
                i |= L;                                                
                i = i * 0.0625 * 10 + 0.5;
        

                display[0]=(uint)i/100;
                display[1]=(uint)i%100/10;
                display[2]=(uint)i%10;

                Write_Cmd(0x80|0x00);
                Write_Dat(display[0]+0x30);

                Write_Cmd(0x80|0x01);
                Write_Dat(display[1]+0x30);

                Write_Cmd(0x80|0x02);
                Write_Dat('.');

                Write_Cmd(0x80|0x03);
                Write_Dat(display[2]+0x30);

                //Delay_Ms(20);
         }
}

DS18B20.h文件
#ifndef _ds18b20_h_
#define _ds18b20_h_

#include"reg52.h"
#include"intrins.h"
#define MAIN_Fosc                11059200UL        //宏定义主时钟HZ

//#define uchar unsigned char        //定义无符号字符型变量
//#define uint  unsigned int  //定义无符号整型变量

typedef unsigned char INT8U;
typedef unsigned char uchar;

typedef unsigned int INT16U;
typedef unsigned int uint;

/*硬件接口位声明*/
sbit DS  = P2^2;   //DS18B20单总线


/*描述:12T 51单片机自适应主时钟毫秒级延时函数*/
void Delay_Ms(INT16U ms);

/*单总线初始化时序*/
bit ds_init();

/*写一个字节*/
void write_byte(uchar dat);

/*读一个字节*/
uchar read_byte();

/*us延时函数,执行一次US--所需6.5us进入一次函数需要11.95us*/
void Delay_us(uchar us);

void Delay_5us();


#endif


DS18B20.c文件
#include"ds18b20.h"
void Delay_Ms(INT16U ms)
{
     INT16U i;
         do{
              i = MAIN_Fosc; // 96000
                  while(--i);   //96T per loop
     }while(--ms);                //
}
/*单总线初始化时序*/
bit ds_init()
{
        bit i;
        DS = 1;
        _nop_();//
        DS = 0;
        Delay_us(75); //拉低总线75*6.5+11.95=499.45us 挂接在总线上的18B20将会全部被复位
        
        DS = 1; //释放总线
        Delay_us(4); //4*6.5+11.95=37.95us 等待50.95us

        i = DS;
        Delay_us(20); //20*6.5+11.95=141.95us 读取存在信号

        DS = 1;        //释放总线
        _nop_();//
        return (i);
}

/*写一个字节*/
void write_byte(uchar dat)
{
        uchar i;
        for(i=0;i<8;i++)
        {
                DS = 0;
                _nop_();//产生些时序
                DS = dat & 0x01;
                Delay_us(10);//10*6.5+11.95=76.95us
                DS = 1; //释放总线准备下一次数据写入
                _nop_();
                dat >>= 1;
        }
}

/*读一个字节*/
uchar read_byte()
{
        uchar i, j, dat;
        for(i=0;i<8;i++)
        {
                DS = 0;
                _nop_();//产生读时序
                DS = 1;
                _nop_();//释放总线
                j = DS;
                Delay_us(10);//6.5*10+11.95=76.95us
                DS = 1;
                _nop_();
                dat = (j<<7)|(dat>>1);        
        }
        return (dat);
}

/*us延时函数,执行一次US--所需6.5us.进入和出去一次函数需要11.95us*/
void Delay_us(uchar us)
{
        /*****************11us延时函数*************************/
   while(us--);
         
}
/*12T 51单片机5微秒延时函数自适应时钟(11.0592M,12M,22.1184M*/
void Delay_5us()
{
        #if MAIN_Fosc == 11059200
                _nop_();
        #elif MAIN_Fosc == 12000000
                _nop_();
        #elif MAIN_Fosc == 22118400
                _nop_(); _nop_(); _nop_();
        #endif
}

LCD1602.c文件
#include<lcd1602.h>
#include<reg52.h>
sbit RS = P3^5;
sbit RW = P3^6;
sbit EN = P3^4;
//#define   uchar unsigned char
//#define          uint  unsigned int  
//判断液晶忙,如果忙则等待
/*void Read_Busy()
{
uchar busy;
P0=0xff; //p0置1
RS=0;          //数据,命令选择端为0,表示数据
RW=1;    //写
do
{
EN=1;
busy=P0;
EN=0;
}
while(busy&0x80); //最高位为1,则为忙。
} */

void delay(uint z)
{
uint x,y;
for(x=z;x>0;x--)
for(y=112;y>0;y--);
}
//写LCD1602命令一个字节
void Write_Cmd(uchar cmd)
{
        RS = 0;
        RW = 0;
        P0 = cmd;
        EN = 1;
        EN = 0;
        delay(5);


}

//写一个字节数据,一个字符uchar类型
void Write_Dat(uchar dat)
{
        RS = 1;
        RW = 0;
        P0 = dat;
        EN = 1;
        EN = 0;
}
//lcd1602初始化
void LCD_init()
   {
        delay(15);
        Write_Cmd(0x38);//第一步:显示模式设置。设置16*2显示        0011 100
        delay(15);
        Write_Cmd(0x38);//第一步:显示模式设置。设置16*2显示        0011 100
        delay(15);
        Write_Cmd(0x38);//第一步:显示模式设置。设置16*2显示        0011 100
        delay(15);
        Write_Cmd(0x38);//第一步:显示模式设置。设置16*2显示        0011 100
        Write_Cmd(0x08);
        //Write_Cmd(0x0f);//第二步:显示开/关光标设置 0000  1 D C B  D=1:开显示 C=1:显示光标反之。B=1:光标闪烁B=0;光标不闪烁
        Write_Cmd(0x01);//第三步:清屏指令 ,以免之前残留在LCD上的数据
        Write_Cmd(0x06);//第四步:0000 01NS 。N=1;地址指针加1,光标加1.地址指针移位命令,读或写一个字符后,地址指针加1,且光标加1
        Write_Cmd(0x0f);//显示开及光标设置
   }

//x:要显示的横坐标取值0-40,y:要显示的行坐标取值0-1(0为第一行,1为第二行) *str:需要显示的字符串
void LCD1602_Dis_Str(uchar x, uchar y, uchar *str)
{
        if(y)
         x |= 0x40;
        x |= 0x80;
        Write_Cmd(x);
        while(*str != '\0')
        {
                Write_Dat(*str++);
        }
}
  //x:要显示的横坐标取值0-40,y:要显示的行坐标取值0-1(0为第一行,1为第二行) dat:需要显示的数据以ASCLL形式显示
void LCD1602_Dis_OneChar(uchar x, uchar y,uchar dat)
{
        if(y)
                x |= 0x40;
        x |= 0x80;
        Write_Cmd(x);
        Write_Dat(dat);               
}


#ifndef _LCD_H_
#define _LCD_H_

LCD1602.h文件
#include"reg52."
#include"intrins.h"
#define    uchar unsigned char
#define           uint  unsigned int
//uchar x,y,*str,dat,cmd;
void  Read_Busy();  //判断液晶忙?
void  delay(uint z);
void  Write_Cmd(uchar cmd); //写入一字节指令
void  Write_Dat(uchar dat);        //写入一字节数据
void  LCD_init();  //lcd初始化
void  LCD1602_Dis_Str(uchar x, uchar y, uchar *str);        //显示字符串
void  LCD1602_Dis_OneChar(uchar x, uchar y,uchar dat); //显示一个字符
#endif //定义结束




评分

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

查看全部评分

回复

使用道具 举报

ID:632424 发表于 2021-9-1 08:45 | 显示全部楼层
very good! 我模仿学习一下,ds18b20温度数据变化后如何处理显示
回复

使用道具 举报

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

本版积分规则

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

Powered by 单片机教程网

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