基于51单片机温度控制器源代码(18b20+lcd1602)

2019年9月23日14:51:18 1

本源程序在51单片机开发板测试通过。

18b20中英文资料

#include"reg52.h"
#include"intrins.h"
#define uint unsigned int
#define uchar unsigned char

#define LCD1602_DB P0 //LCD1602 data bus数据总线
sbit LCD1602_RS = P2^6;
sbit LCD1602_RW = P2^5;
sbit LCD1602_EN = P2^7;

sbit LED=P2^0;

sbit DSPORT=P3^7; //DS18B20数据线

unsigned char Ds18b20Init();
void Ds18b20WriteByte(unsigned char com);
unsigned char Ds18b20ReadByte();
void Ds18b20ChangTemp();
void Ds18b20ReadTempCom();
int Ds18b20ReadTemp();

void Read_Busy();
void Lcd1602_Write_Cmd(unsigned char cmd);
void Lcd1602_Write_Data(unsigned char dat);
void InitLcd1602();

void delayms(uint xms);
void LcdDisplay(int temp);

void main()
{
uint temp;
P1=0x00;

// LED=Ds18b20Init(); //测试用,DS18B20初始化成功,P2^0亮

while(1)
{
temp=Ds18b20ReadTemp();
LcdDisplay(temp);
delayms(1000);
}
}

/*******************************************************************************
* 函数名 : LcdDisplay()
* 函数功能 : LCD显示读取到的温度
* 输入 : v
* 输出 : 无
*******************************************************************************/

void LcdDisplay(int temp) //lcd显示
{
   unsigned char datas[] = {0, 0, 0, 0, 0}; //定义数组
   float tp;
   InitLcd1602();
   if(temp< 0) //当温度值为负数
   {
      Lcd1602_Write_Cmd(0x80); //写地址 80表示初始地址
      Lcd1602_Write_Data('-'); //显示负
//因为读取的温度是实际温度的补码,所以减1,再取反求出原码
      temp=temp-1;
      temp=~temp;
      tp=temp;
      temp=tp*0.0625*100+0.5;
//留两个小数点就*100,+0.5是四舍五入,因为C语言浮点数转换为整型的时候把小数点
//后面的数自动去掉,不管是否大于0.5,而+0.5之后大于0.5的就是进1了,小于0.5的就
//算由?.5,还是在小数点后面。
    }
    else
    {
        Lcd1602_Write_Cmd(0x80); //写地址 80表示初始地址
        Lcd1602_Write_Data('+'); //显示正
        tp=temp;//因为数据处理有小数点所以将温度赋给一个浮点型变量
//如果温度是正的那么,那么正数的原码就是补码它本身
       temp=tp*0.0625*100+0.5;
//留两个小数点就*100,+0.5是四舍五入,因为C语言浮点数转换为整型的时候把小数点
//后面的数自动去掉,不管是否大于0.5,而+0.5之后大于0.5的就是进1了,小于0.5的就
//算加上0.5,还是在小数点后面。
}
       datas[0] = temp / 10000;
       datas[1] = temp % 10000 / 1000;
       datas[2] = temp % 1000 / 100;
       datas[3] = temp % 100 / 10;
       datas[4] = temp % 10;
       Lcd1602_Write_Cmd(0x82); //写地址 80表示初始地址
       Lcd1602_Write_Data('0'+datas[0]); //百位
       Lcd1602_Write_Cmd(0x83); //写地址 80表示初始地址
       Lcd1602_Write_Data('0'+datas[1]); //十位
       Lcd1602_Write_Cmd(0x84); //写地址 80表示初始地址
       Lcd1602_Write_Data('0'+datas[2]); //个位

       Lcd1602_Write_Cmd(0x85); //写地址 80表示初始地址
       Lcd1602_Write_Data('.'); //显示 ‘.’

       Lcd1602_Write_Cmd(0x86); //写地址 80表示初始地址
       Lcd1602_Write_Data('0'+datas[3]); //显示小数点

       Lcd1602_Write_Cmd(0x87); //写地址 80表示初始地址
       Lcd1602_Write_Data('0'+datas[4]); //显示小数点
}

/*******************************************************************************
* 函数名 : Ds18b20Init
* 函数功能 : 初始化
* 输入 : 无
* 输出 : 初始化成功返回1,失败返回0
*******************************************************************************/

unsigned char Ds18b20Init()
{
    uint i,n;
    DSPORT=0; //单片机拉低数据线,形成复位脉冲

    n=70; //复位脉冲480us~960us
    while(--n) //12M晶振,n=1时延时10us,n=2时延时21us,以后每加1,递进11us
       _nop_();

    DSPORT=1; //单片机拉高数据线,等待DS18B20应答信号(低电平)

    n=5; //等待DS18B20应答信号,延时15-60us
    while(--n)
        _nop_();

    while(DSPORT) //单片机等待低电平应答信号。如果复位成功,则在15-60ms内产生一个由DS18B20返回的低电平
     {
         i++;
         if(i>6000) //等待应答信号不应无限循环,应有退出机制
             return 0;//初始化不成功的标志
     }

     n=48; //单片机等待DS18B20响应最小值480us
     while(--n)
          _nop_();

     DSPORT=1; //单片机拉高数据线,初始化结束
     return 1; //初始化成功的标志
}

/*******************************************************************************
* 函数名 : Ds18b20WriteByte
* 函数功能 : 向18B20写入一个字节
* 输入 : com
* 输出 : 无
*******************************************************************************/

void Ds18b20WriteByte(unsigned char dat)
{
   unsigned int j,n;
   for(j=0;j<8;j++)
   {
      DSPORT=0; //准备写入数据
     _nop_(); //每写入一位数据之前先把总线拉低1us-3us
     _nop_();

     DSPORT=dat&0x01; //从最低位开始写入二进制位,要求15us内完成

     n=6; //延时60us,写时序持续时间最少60us
     while(--n)
         _nop_();

     DSPORT=1; //然后释放总线,至少1us给总线恢复时间才能接着写入第二个数值
     dat>>=1;
   }
}
/*******************************************************************************
* 函数名 : Ds18b20ReadByte
* 函数功能 : 读取一个字节
* 输入 : com
* 输出 : 无
******************************************************************************
unsigned char Ds18b20ReadByte()
{
   unsigned char byte,bi;
   unsigned int n,j;
   for(j=8;j>0;j--)
  {
     DSPORT=0;
    _nop_(); //读取温度传感器数据前要求单片机先把总线拉低1us以上3us以内
   _nop_();
   DSPORT=1; //单片机释放总线,等待温度传感器传送数据
   bi=DSPORT; //读取数据,从最低位开始读取
   byte=(byte>>1)|(bi<<7);

   n=5; //延时60us,写时序持续时间最少60us
   while(--n)
      _nop_();
  }
  return byte;
}
/*******************************************************************************
* 函数名 : Ds18b20ChangTemp
* 函数功能 : 让18b20开始转换温度
* 输入 : com
* 输出 : 无
*******************************************************************************/

void Ds18b20ChangTemp()
{
   Ds18b20Init();
   delayms(1);
   Ds18b20WriteByte(0xcc); //跳过ROM操作命令
   Ds18b20WriteByte(0x44); //温度转换命令
// Delay1ms(100); //等待转换成功,而如果你是一直刷着的话,就不用这个延时了

}
/*******************************************************************************
* 函数名 : Ds18b20ReadTempCom
* 函数功能 : 发送读取温度命令
* 输入 : com
* 输出 : 无
*******************************************************************************/

void Ds18b20ReadTempCom()
{

   Ds18b20Init();
   delayms(1);
   Ds18b20WriteByte(0xcc); //跳过ROM操作命令
   Ds18b20WriteByte(0xbe); //发送读取温度命令
}
/*******************************************************************************
* 函数名 : Ds18b20ReadTemp
* 函数功能 : 读取温度
* 输入 : com
* 输出 : 无
*******************************************************************************/

int Ds18b20ReadTemp()
{
   int temp=0;
   unsigned char tmh,tml;
   Ds18b20ChangTemp(); //先写入转换命令
   Ds18b20ReadTempCom(); //然后等待转换完后发送读取温度命令
  tml=Ds18b20ReadByte(); //读取温度值共16位,先读低字节
  tmh=Ds18b20ReadByte(); //再读高字节
  temp=tmh;
  temp<<=8;
  temp|=tml;
  return temp;
}

void delayms(uint xms)
{
   uint i,j;
   for(i=xms;i>0;i--)
      for(j=110;j>0;j--)
         ;
}
/*******************************************************************************
* 函数名 :
* 函数功能 : LCD1602显示函数集
* 输入 : v
* 输出 : 无
*******************************************************************************/
void Read_Busy() //忙检测函数,判断bit7是0,允许执行;1禁止
{
   unsigned char sta; //
   LCD1602_DB = 0xff;
   LCD1602_RS = 0;
   LCD1602_RW = 1;
   do
   {
       LCD1602_EN = 1;
       sta = LCD1602_DB;
       LCD1602_EN = 0; //使能,用完就拉低,释放总线
    }while(sta & 0x80);
}

void Lcd1602_Write_Cmd(unsigned char cmd) //写命令
{
    Read_Busy();
    LCD1602_RS = 0;
    LCD1602_RW = 0;
    LCD1602_DB = cmd;
    LCD1602_EN = 1;
    LCD1602_EN = 0;
}

void Lcd1602_Write_Data(unsigned char dat) //写数据
{
    Read_Busy();
    LCD1602_RS = 1;
    LCD1602_RW = 0;
    LCD1602_DB = dat;
    LCD1602_EN = 1;
    LCD1602_EN = 0;
}

void InitLcd1602() //1602初始化
{
    Lcd1602_Write_Cmd(0x38); //打开,5*8,8位数据
    Lcd1602_Write_Cmd(0x0c);
    Lcd1602_Write_Cmd(0x06);
    Lcd1602_Write_Cmd(0x01); //清屏
}

发表评论

您必须才能发表评论!

目前评论:1   其中:访客  0   博主  1

    • yup82 Admin

      天猫购买:telesky旗舰店
      学习资料 提取码: qunc